diff --git a/.devcontainer/app-init.sh b/.devcontainer/app-init.sh index a0e7fbb1b..004cf786c 100644 --- a/.devcontainer/app-init.sh +++ b/.devcontainer/app-init.sh @@ -11,13 +11,13 @@ echo "Waiting for DB container to come online..." /usr/local/bin/wait-for localhost:5432 -- echo "DB ready" echo "Installing dependencies..." -cd server -pnpm install -cd ../ux -pnpm install +cd backend +npm install +cd ../frontend +npm install cd ../blocks -pnpm install -pnpm build +npm install +npm build cd .. echo "Ready!" diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 80ae91750..36a4524ac 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -11,8 +11,8 @@ { "label": "Create terminals", "dependsOn": [ - "Server", - "UX" + "Backend", + "Frontend" ], // Mark as the default build task so cmd/ctrl+shift+b will create them "group": { @@ -26,14 +26,14 @@ }, { // The name that shows up in terminal tab - "label": "Server", + "label": "Backend", // The task will launch a shell "type": "shell", "command": "/bin/zsh", "args": [], // Set the shell type "options": { - "cwd": "/workspace/server" + "cwd": "/workspace/backend" }, // Mark as a background task to avoid the spinner animation on the terminal tab "isBackground": true, @@ -44,12 +44,12 @@ } }, { - "label": "UX", + "label": "Frontend", "type": "shell", "command": "/bin/zsh", "args": [], "options": { - "cwd": "/workspace/ux", + "cwd": "/workspace/frontend", }, "isBackground": true, "problemMatcher": [], diff --git a/blocks/package-lock.json b/blocks/package-lock.json new file mode 100644 index 000000000..3b3b1f5bb --- /dev/null +++ b/blocks/package-lock.json @@ -0,0 +1,1174 @@ +{ + "name": "blocks", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "blocks", + "version": "1.0.0", + "license": "AGPL-3.0", + "dependencies": { + "lit": "3.2.1" + }, + "devDependencies": { + "@rollup/plugin-graphql": "2.0.5", + "@rollup/plugin-node-resolve": "15.3.0", + "@rollup/plugin-terser": "0.4.4", + "glob": "11.0.0", + "rollup": "4.24.0", + "rollup-plugin-summary": "2.0.1" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.5.1.tgz", + "integrity": "sha512-Aou5UdlSpr5whQe8AA/bZG0jMj96CoJIWbGfZ91qieWu5AWUMKw8VR/pAkQkJYvBNhmCcWnZlyyk5oze8JIqYA==", + "license": "BSD-3-Clause" + }, + "node_modules/@lit/reactive-element": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.2.tgz", + "integrity": "sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.5.0" + } + }, + "node_modules/@rollup/plugin-graphql": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-graphql/-/plugin-graphql-2.0.5.tgz", + "integrity": "sha512-NMx9uVIheYMOQHV9Aann0sk/2+henT8T5JUbHneOvbD3iUrVUC7AaZ1B1ELJ/1vhqUe2OQIkRtGHzOQwBLoCvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "graphql-tag": "^2.12.6" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "graphql": ">=0.9.0", + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", + "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brotli-size": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/brotli-size/-/brotli-size-4.0.0.tgz", + "integrity": "sha512-uA9fOtlTRC0iqKfzff1W34DXUA3GyVqbUaeo3Rw3d4gd1eavKVCETXrn3NzO74W+UVkG3UHu8WxUi+XvKI/huA==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "0.1.1" + }, + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha512-sxNZ+ljy+RA1maXoUReeqBBpBC6RLKmg5ewzV+x+mSETmWNoKdZN6vcQjpFROemza23hGFskJtFNoUWUaQ+R4Q==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graphql": { + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.0.tgz", + "integrity": "sha512-uSisMYERbaB9bkA9M4/4dnqyktaEkf1kMHNKq/7DHyxVeWqHQ2mBmVqm5u6/FVHwF3iCNalKcg82Zfl+tffWoA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/gzip-size": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-7.0.0.tgz", + "integrity": "sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gzip-size/node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lit": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz", + "integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^2.0.4", + "lit-element": "^4.1.0", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-element": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.2.tgz", + "integrity": "sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.5.0", + "@lit/reactive-element": "^2.1.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-html": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.2.tgz", + "integrity": "sha512-Qy9hU88zcmaxBXcc10ZpdK7cOLXvXpRoBxERdtqV9QOrfpMZZ6pSYP91LhpPtap3sFMUiL7Tw2RImbe0Al2/kw==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-summary": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-summary/-/rollup-plugin-summary-2.0.1.tgz", + "integrity": "sha512-aO8t5ZxAB9svdUl4etKUbWr7FFK/2RLj81ZiHnsJKsXPcZEekh32+TknJFj/V8JYRqjmlb/Ygi4aktRa9LdQjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "brotli-size": "^4.0.0", + "cli-table3": "^0.6.3", + "filesize": "^10.0.5", + "gzip-size": "^7.0.0", + "terser": "^5.15.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + } + }, + "node_modules/rollup/node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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" + } + ], + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/smob": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.1.tgz", + "integrity": "sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/terser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "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, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + } + } +} diff --git a/blocks/package.json b/blocks/package.json index d7ae0ea84..567c35e89 100644 --- a/blocks/package.json +++ b/blocks/package.json @@ -20,6 +20,5 @@ "glob": "11.0.0", "rollup": "4.24.0", "rollup-plugin-summary": "2.0.1" - }, - "packageManager": "pnpm@9.12.2+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228" + } } diff --git a/blocks/pnpm-lock.yaml b/blocks/pnpm-lock.yaml deleted file mode 100644 index 733cc2951..000000000 --- a/blocks/pnpm-lock.yaml +++ /dev/null @@ -1,900 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - lit: - specifier: 3.2.1 - version: 3.2.1 - devDependencies: - '@rollup/plugin-graphql': - specifier: 2.0.5 - version: 2.0.5(graphql@16.8.1)(rollup@4.24.0) - '@rollup/plugin-node-resolve': - specifier: 15.3.0 - version: 15.3.0(rollup@4.24.0) - '@rollup/plugin-terser': - specifier: 0.4.4 - version: 0.4.4(rollup@4.24.0) - glob: - specifier: 11.0.0 - version: 11.0.0 - rollup: - specifier: 4.24.0 - version: 4.24.0 - rollup-plugin-summary: - specifier: 2.0.1 - version: 2.0.1(rollup@4.24.0) - -packages: - - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.1': - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.5': - resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} - - '@jridgewell/source-map@0.3.6': - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.19': - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@lit-labs/ssr-dom-shim@1.2.1': - resolution: {integrity: sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==} - - '@lit/reactive-element@2.0.4': - resolution: {integrity: sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==} - - '@rollup/plugin-graphql@2.0.5': - resolution: {integrity: sha512-NMx9uVIheYMOQHV9Aann0sk/2+henT8T5JUbHneOvbD3iUrVUC7AaZ1B1ELJ/1vhqUe2OQIkRtGHzOQwBLoCvg==} - engines: {node: '>=14.0.0'} - peerDependencies: - graphql: '>=0.9.0' - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-node-resolve@15.3.0': - resolution: {integrity: sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/plugin-terser@0.4.4': - resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/pluginutils@5.1.2': - resolution: {integrity: sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.24.0': - resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.24.0': - resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.24.0': - resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.24.0': - resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': - resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.24.0': - resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.24.0': - resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.24.0': - resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': - resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.24.0': - resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.24.0': - resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.24.0': - resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.24.0': - resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.24.0': - resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.24.0': - resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.24.0': - resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} - cpu: [x64] - os: [win32] - - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - - '@types/resolve@1.20.2': - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - - '@types/trusted-types@2.0.7': - resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - - acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} - engines: {node: '>=0.4.0'} - hasBin: true - - acorn@8.13.0: - resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} - engines: {node: '>=0.4.0'} - hasBin: true - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - brotli-size@4.0.0: - resolution: {integrity: sha512-uA9fOtlTRC0iqKfzff1W34DXUA3GyVqbUaeo3Rw3d4gd1eavKVCETXrn3NzO74W+UVkG3UHu8WxUi+XvKI/huA==} - engines: {node: '>= 10.16.0'} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - cli-table3@0.6.5: - resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} - engines: {node: 10.* || >= 12.*} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - duplexer@0.1.1: - resolution: {integrity: sha512-sxNZ+ljy+RA1maXoUReeqBBpBC6RLKmg5ewzV+x+mSETmWNoKdZN6vcQjpFROemza23hGFskJtFNoUWUaQ+R4Q==} - - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - filesize@10.1.6: - resolution: {integrity: sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==} - engines: {node: '>= 10.4.0'} - - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - glob@11.0.0: - resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} - engines: {node: 20 || >=22} - hasBin: true - - graphql-tag@2.12.6: - resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} - engines: {node: '>=10'} - peerDependencies: - graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - - graphql@16.8.1: - resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - - gzip-size@7.0.0: - resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - is-core-module@2.15.1: - resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} - engines: {node: '>= 0.4'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@4.0.2: - resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} - engines: {node: 20 || >=22} - - lit-element@4.1.1: - resolution: {integrity: sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==} - - lit-html@3.2.1: - resolution: {integrity: sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==} - - lit@3.2.1: - resolution: {integrity: sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==} - - lru-cache@11.0.1: - resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==} - engines: {node: 20 || >=22} - - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} - engines: {node: 20 || >=22} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} - engines: {node: 20 || >=22} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - rollup-plugin-summary@2.0.1: - resolution: {integrity: sha512-aO8t5ZxAB9svdUl4etKUbWr7FFK/2RLj81ZiHnsJKsXPcZEekh32+TknJFj/V8JYRqjmlb/Ygi4aktRa9LdQjw==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - - rollup@4.24.0: - resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - serialize-javascript@6.0.1: - resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - smob@1.4.1: - resolution: {integrity: sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - terser@5.21.0: - resolution: {integrity: sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==} - engines: {node: '>=10'} - hasBin: true - - terser@5.36.0: - resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==} - engines: {node: '>=10'} - hasBin: true - - tslib@2.8.0: - resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - -snapshots: - - '@colors/colors@1.5.0': - optional: true - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jridgewell/gen-mapping@0.3.3': - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.19 - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.1': {} - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/source-map@0.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 - - '@jridgewell/source-map@0.3.6': - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/sourcemap-codec@1.4.15': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.19': - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@lit-labs/ssr-dom-shim@1.2.1': {} - - '@lit/reactive-element@2.0.4': - dependencies: - '@lit-labs/ssr-dom-shim': 1.2.1 - - '@rollup/plugin-graphql@2.0.5(graphql@16.8.1)(rollup@4.24.0)': - dependencies: - '@rollup/pluginutils': 5.1.2(rollup@4.24.0) - graphql: 16.8.1 - graphql-tag: 2.12.6(graphql@16.8.1) - optionalDependencies: - rollup: 4.24.0 - - '@rollup/plugin-node-resolve@15.3.0(rollup@4.24.0)': - dependencies: - '@rollup/pluginutils': 5.1.2(rollup@4.24.0) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-module: 1.0.0 - resolve: 1.22.8 - optionalDependencies: - rollup: 4.24.0 - - '@rollup/plugin-terser@0.4.4(rollup@4.24.0)': - dependencies: - serialize-javascript: 6.0.1 - smob: 1.4.1 - terser: 5.21.0 - optionalDependencies: - rollup: 4.24.0 - - '@rollup/pluginutils@5.1.2(rollup@4.24.0)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 2.3.1 - optionalDependencies: - rollup: 4.24.0 - - '@rollup/rollup-android-arm-eabi@4.24.0': - optional: true - - '@rollup/rollup-android-arm64@4.24.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.24.0': - optional: true - - '@rollup/rollup-darwin-x64@4.24.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.24.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.24.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.24.0': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.24.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.24.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.24.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.24.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.24.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.24.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.24.0': - optional: true - - '@types/estree@1.0.6': {} - - '@types/resolve@1.20.2': {} - - '@types/trusted-types@2.0.7': {} - - acorn@8.10.0: {} - - acorn@8.13.0: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - balanced-match@1.0.2: {} - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - brotli-size@4.0.0: - dependencies: - duplexer: 0.1.1 - - buffer-from@1.1.2: {} - - cli-table3@0.6.5: - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - commander@2.20.3: {} - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - deepmerge@4.3.1: {} - - duplexer@0.1.1: {} - - duplexer@0.1.2: {} - - eastasianwidth@0.2.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - estree-walker@2.0.2: {} - - filesize@10.1.6: {} - - foreground-child@3.3.0: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - glob@11.0.0: - dependencies: - foreground-child: 3.3.0 - jackspeak: 4.0.2 - minimatch: 10.0.1 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 2.0.0 - - graphql-tag@2.12.6(graphql@16.8.1): - dependencies: - graphql: 16.8.1 - tslib: 2.8.0 - - graphql@16.8.1: {} - - gzip-size@7.0.0: - dependencies: - duplexer: 0.1.2 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - is-core-module@2.15.1: - dependencies: - hasown: 2.0.2 - - is-fullwidth-code-point@3.0.0: {} - - is-module@1.0.0: {} - - isexe@2.0.0: {} - - jackspeak@4.0.2: - dependencies: - '@isaacs/cliui': 8.0.2 - - lit-element@4.1.1: - dependencies: - '@lit-labs/ssr-dom-shim': 1.2.1 - '@lit/reactive-element': 2.0.4 - lit-html: 3.2.1 - - lit-html@3.2.1: - dependencies: - '@types/trusted-types': 2.0.7 - - lit@3.2.1: - dependencies: - '@lit/reactive-element': 2.0.4 - lit-element: 4.1.1 - lit-html: 3.2.1 - - lru-cache@11.0.1: {} - - minimatch@10.0.1: - dependencies: - brace-expansion: 2.0.1 - - minipass@7.1.2: {} - - package-json-from-dist@1.0.1: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-scurry@2.0.0: - dependencies: - lru-cache: 11.0.1 - minipass: 7.1.2 - - picomatch@2.3.1: {} - - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - resolve@1.22.8: - dependencies: - is-core-module: 2.15.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - rollup-plugin-summary@2.0.1(rollup@4.24.0): - dependencies: - brotli-size: 4.0.0 - cli-table3: 0.6.5 - filesize: 10.1.6 - gzip-size: 7.0.0 - rollup: 4.24.0 - terser: 5.36.0 - - rollup@4.24.0: - dependencies: - '@types/estree': 1.0.6 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.24.0 - '@rollup/rollup-android-arm64': 4.24.0 - '@rollup/rollup-darwin-arm64': 4.24.0 - '@rollup/rollup-darwin-x64': 4.24.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 - '@rollup/rollup-linux-arm-musleabihf': 4.24.0 - '@rollup/rollup-linux-arm64-gnu': 4.24.0 - '@rollup/rollup-linux-arm64-musl': 4.24.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 - '@rollup/rollup-linux-riscv64-gnu': 4.24.0 - '@rollup/rollup-linux-s390x-gnu': 4.24.0 - '@rollup/rollup-linux-x64-gnu': 4.24.0 - '@rollup/rollup-linux-x64-musl': 4.24.0 - '@rollup/rollup-win32-arm64-msvc': 4.24.0 - '@rollup/rollup-win32-ia32-msvc': 4.24.0 - '@rollup/rollup-win32-x64-msvc': 4.24.0 - fsevents: 2.3.3 - - safe-buffer@5.2.1: {} - - serialize-javascript@6.0.1: - dependencies: - randombytes: 2.1.0 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@4.1.0: {} - - smob@1.4.1: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - terser@5.21.0: - dependencies: - '@jridgewell/source-map': 0.3.5 - acorn: 8.10.0 - commander: 2.20.3 - source-map-support: 0.5.21 - - terser@5.36.0: - dependencies: - '@jridgewell/source-map': 0.3.6 - acorn: 8.13.0 - commander: 2.20.3 - source-map-support: 0.5.21 - - tslib@2.8.0: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 63358c4cb..3e796e546 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -123,7 +123,6 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -1067,6 +1066,7 @@ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -1077,6 +1077,7 @@ "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", @@ -1091,7 +1092,8 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { "version": "1.1.12", @@ -1099,6 +1101,7 @@ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1110,6 +1113,7 @@ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1123,6 +1127,7 @@ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -1133,6 +1138,7 @@ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@types/json-schema": "^7.0.15" }, @@ -1146,6 +1152,7 @@ "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", @@ -1169,7 +1176,8 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.12", @@ -1177,6 +1185,7 @@ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1188,6 +1197,7 @@ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1201,6 +1211,7 @@ "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1214,6 +1225,7 @@ "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -1224,6 +1236,7 @@ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" @@ -1238,6 +1251,7 @@ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=18.18.0" } @@ -1248,6 +1262,7 @@ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" @@ -1262,6 +1277,7 @@ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=12.22" }, @@ -1276,6 +1292,7 @@ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=18.18" }, @@ -2846,13 +2863,15 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/lodash": { "version": "4.17.24", @@ -2876,7 +2895,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/mime": { "version": "1.3.5", @@ -3101,7 +3121,6 @@ "integrity": "sha512-uM5iXipgYIn13UUQCZNdWkYk+sysBeA97d5mHsAoAt1u/wpN3+zxOmsVJWosuzX+IMGRzeYUNytztrYznboIkQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.2" }, @@ -3432,7 +3451,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3456,6 +3474,7 @@ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3937,7 +3956,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4055,6 +4073,7 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -4403,7 +4422,8 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/confbox": { "version": "0.1.8", @@ -4560,7 +4580,8 @@ "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, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/default-browser": { "version": "5.5.0", @@ -4962,6 +4983,7 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -4997,6 +5019,7 @@ "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -5058,6 +5081,7 @@ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -5087,7 +5111,8 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.12", @@ -5095,6 +5120,7 @@ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5106,6 +5132,7 @@ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -5119,6 +5146,7 @@ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -5132,6 +5160,7 @@ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5145,6 +5174,7 @@ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", @@ -5163,6 +5193,7 @@ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -5190,6 +5221,7 @@ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -5203,6 +5235,7 @@ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -5351,7 +5384,8 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fast-fifo": { "version": "1.3.2", @@ -5382,14 +5416,16 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": 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, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fastq": { "version": "1.20.1", @@ -5424,6 +5460,7 @@ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "flat-cache": "^4.0.0" }, @@ -5501,6 +5538,7 @@ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -5528,6 +5566,7 @@ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -5541,7 +5580,8 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/foreground-child": { "version": "3.3.1", @@ -5773,6 +5813,7 @@ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -5967,6 +6008,7 @@ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 4" } @@ -5984,6 +6026,7 @@ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6001,6 +6044,7 @@ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.8.19" } @@ -6349,6 +6393,7 @@ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -6373,21 +6418,24 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "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, - "license": "MIT" + "license": "MIT", + "peer": 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, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/json5": { "version": "2.2.3", @@ -6501,6 +6549,7 @@ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "json-buffer": "3.0.1" } @@ -6593,6 +6642,7 @@ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -6650,6 +6700,7 @@ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -6678,7 +6729,8 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lodash.repeat": { "version": "4.1.0", @@ -6773,7 +6825,6 @@ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -7164,7 +7215,8 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/negotiator": { "version": "0.6.4", @@ -7330,6 +7382,7 @@ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -7378,6 +7431,7 @@ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7394,6 +7448,7 @@ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -7434,6 +7489,7 @@ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "callsites": "^3.0.0" }, @@ -7468,6 +7524,7 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -7547,7 +7604,6 @@ "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz", "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", "license": "MIT", - "peer": true, "dependencies": { "@vue/devtools-api": "^7.7.7" }, @@ -7633,7 +7689,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -7656,6 +7711,7 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8.0" } @@ -7914,6 +7970,7 @@ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -7964,7 +8021,6 @@ "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.18.6.tgz", "integrity": "sha512-ZlK+vJXOBPSFDCNQDBDNwSI+AHoqaFPxK8ve6mhsYLhMKWI5b8zsGY9VU1xYjngO2aBvU4fvGWXy4tTbzrBk8Q==", "license": "MIT", - "peer": true, "engines": { "node": ">= 10.18.1", "npm": ">= 6.13.4", @@ -8192,6 +8248,7 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=4" } @@ -8240,7 +8297,6 @@ "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -9351,6 +9407,7 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" }, @@ -9645,6 +9702,7 @@ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -9684,7 +9742,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9801,6 +9858,7 @@ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -9878,7 +9936,6 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -10557,7 +10614,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.29.tgz", "integrity": "sha512-BZqN4Ze6mDQVNAni0IHeMJ5mwr8VAJ3MQC9FmprRhcBYENw+wOAAjRj8jfmN6FLl0j96OXbR+CjWhmAmM+QGnA==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.29", "@vue/compiler-sfc": "3.5.29", @@ -10579,7 +10635,6 @@ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.2.8.tgz", "integrity": "sha512-vJ123v/PXCZntd6Qj5Jumy7UBmIuE92VrtdX+AXr+1WzdBHojiBxnAxdfctUFL+/JIN+VQH4BhsfTtiGsvVObg==", "license": "MIT", - "peer": true, "dependencies": { "@intlify/core-base": "11.2.8", "@intlify/shared": "11.2.8", @@ -10802,6 +10857,7 @@ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -10969,6 +11025,7 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, diff --git a/server/.npmrc b/server/.npmrc deleted file mode 100644 index d78007218..000000000 --- a/server/.npmrc +++ /dev/null @@ -1,5 +0,0 @@ -audit = false -fund = false -lockfile-version = "3" -save-exact = true -save-prefix = "" diff --git a/server/app/content/create.md b/server/app/content/create.md deleted file mode 100644 index c65036dec..000000000 --- a/server/app/content/create.md +++ /dev/null @@ -1,4 +0,0 @@ - - - -# Header \ No newline at end of file diff --git a/server/app/data.yml b/server/app/data.yml deleted file mode 100644 index 12535a18a..000000000 --- a/server/app/data.yml +++ /dev/null @@ -1,159 +0,0 @@ -# --------------------------------- -# DO NOT EDIT THIS FILE! -# This is reserved for system use! -# --------------------------------- -name: Wiki.js -defaults: - config: - # File defaults - port: 80 - db: - host: localhost - port: 5432 - user: wikijs - pass: wikijsrocks - db: wiki - ssl: false - sslOptions: - auto: true - schema: wiki - ssl: - enabled: false - pool: - min: 1 - bindIP: 0.0.0.0 - logLevel: info - logFormat: default - offline: false - dataPath: ./data - bodyParserLimit: 5mb - scheduler: - workers: 3 - pollingCheck: 5 - scheduledCheck: 300 - maxRetries: 2 - retryBackoff: 60 - historyExpiration: 90000 - # DB defaults - api: - isEnabled: false - mail: - host: '' - secure: true - verifySSL: true - metrics: - isEnabled: false - auth: - autoLogin: false - enforce2FA: false - hideLocal: false - loginBgUrl: '' - audience: 'urn:wiki.js' - tokenExpiration: '30m' - tokenRenewal: '14d' - security: - corsMode: 'OFF' - corsConfig: '' - enforceCsp: false - trustProxy: false - enforceHsts: false - disallowFloc: true - hstsDuration: 0 - cspDirectives: '' - uploadScanSVG: true - disallowIframe: true - uploadMaxFiles: 20 - authJwtAudience: 'urn:wiki.js' - authJwtExpiration: '30m' - uploadMaxFileSize: 10485760 - forceAssetDownload: true - disallowOpenRedirect: true - authJwtRenewablePeriod: '14d' - enforceSameOriginReferrerPolicy: true - flags: - experimental: false - authDebug: false - sqlLog: false - userDefaults: - timezone: 'America/New_York' - dateFormat: 'YYYY-MM-DD' - timeFormat: '12h' - # System defaults - channel: NEXT - cors: - credentials: true - maxAge: 600 - methods: 'GET,POST' - origin: true - maintainerEmail: security@requarks.io -tsDictMappings: - ar: arabic - hy: armenian - eu: basque - ca: catalan - da: danish - nl: dutch - en: english - fi: finnish - fr: french - de: german - el: greek - hi: hindi - hu: hungarian - id: indonesian - ga: irish - it: italian - lt: lithuanian - ne: nepali - no: norwegian - pt: portuguese - ro: romanian - ru: russian - sr: serbian - es: spanish - sv: swedish - ta: tamil - tr: turkish - yi: yiddish -editors: - asciidoc: - contentType: html - config: {} - markdown: - contentType: markdown - config: - allowHTML: true - linkify: true - lineBreaks: true - typographer: false - underline: false - tabWidth: 2 - latexEngine: katex - kroki: true - plantuml: true - multimdTable: true - wysiwyg: - contentType: html - config: {} -systemIds: - localAuthId: '5a528c4c-0a82-4ad2-96a5-2b23811e6588' - guestsGroupId: '10000000-0000-4000-8000-000000000001' - usersGroupId: '20000000-0000-4000-8000-000000000002' -groups: - defaultPermissions: - - 'read:pages' - - 'read:assets' - - 'read:comments' - - 'write:comments' - defaultRules: - - name: Default Rule - mode: ALLOW - match: START - roles: - - 'read:pages' - - 'read:assets' - - 'read:comments' - - 'write:comments' - path: '' - locales: [] - sites: [] diff --git a/server/app/regex.mjs b/server/app/regex.mjs deleted file mode 100644 index 2b4e7d6ce..000000000 --- a/server/app/regex.mjs +++ /dev/null @@ -1,7 +0,0 @@ -export default { - arabic: '\u0600-\u06ff\u0750-\u077f\ufb50-\ufc3f\ufe70-\ufefc', - cjk: '\u4E00-\u9FBF\u3040-\u309F\u30A0-\u30FFㄱ-ㅎ가-힣ㅏ-ㅣ', - youtube: /(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|&v(?:i)?=))([^#&?]*).*/, - vimeo: /vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^/]*)\/videos\/|album\/(?:\d+)\/video\/|)(\d+)(?:$|\/|\?)/, - dailymotion: /(?:dailymotion\.com(?:\/embed)?(?:\/video|\/hub)|dai\.ly)\/([0-9a-z]+)(?:[-_0-9a-zA-Z]+(?:#video=)?([a-z0-9]+)?)?/ -} diff --git a/server/controllers/auth.mjs b/server/controllers/auth.mjs deleted file mode 100644 index 5e333e0bd..000000000 --- a/server/controllers/auth.mjs +++ /dev/null @@ -1,159 +0,0 @@ -import express from 'express' -import ExpressBrute from 'express-brute' -import BruteKnex from '../helpers/brute-knex.mjs' -import { find, isEmpty, set } from 'lodash-es' -import path from 'node:path' -import { DateTime } from 'luxon' - -export default function () { - const router = express.Router() - - const bruteforce = new ExpressBrute(new BruteKnex({ - createTable: true, - knex: WIKI.db.knex - }), { - freeRetries: 5, - minWait: 5 * 60 * 1000, // 5 minutes - maxWait: 60 * 60 * 1000, // 1 hour - failCallback: (req, res, next) => { - res.status(401).send('Too many failed attempts. Try again later.') - } - }) - - /** - * Login form - */ - router.get('/login', async (req, res, next) => { - // -> Bypass Login - if (WIKI.config.auth.autoLogin && !req.query.all) { - const stg = await WIKI.db.authentication.query().orderBy('order').first() - const stgInfo = find(WIKI.data.authentication, ['key', stg.strategyKey]) - if (!stgInfo.useForm) { - return res.redirect(`/login/${stg.key}`) - } - } - // -> Show Login - res.sendFile(path.join(WIKI.ROOTPATH, 'assets/index.html')) - }) - - /** - * Social Strategies Login - */ - router.get('/login/:strategy', async (req, res, next) => { - try { - await WIKI.db.users.login({ - strategy: req.params.strategy - }, { req, res }) - } catch (err) { - next(err) - } - }) - - /** - * Social Strategies Callback - */ - router.all('/login/:strategy/callback', async (req, res, next) => { - if (req.method !== 'GET' && req.method !== 'POST') { return next() } - - try { - const authResult = await WIKI.db.users.login({ - strategy: req.params.strategy - }, { req, res }) - res.cookie('jwt', authResult.jwt, { expires: DateTime.now().plus({ years: 1 }).toJSDate() }) - - const loginRedirect = req.cookies['loginRedirect'] - if (loginRedirect === '/' && authResult.redirect) { - res.clearCookie('loginRedirect') - res.redirect(authResult.redirect) - } else if (loginRedirect) { - res.clearCookie('loginRedirect') - res.redirect(loginRedirect) - } else if (authResult.redirect) { - res.redirect(authResult.redirect) - } else { - res.redirect('/') - } - } catch (err) { - next(err) - } - }) - - /** - * Logout - */ - router.get('/logout', async (req, res, next) => { - const redirURL = await WIKI.db.users.logout({ req, res }) - req.logout((err) => { - if (err) { return next(err) } - res.clearCookie('jwt') - res.redirect(redirURL) - }) - }) - - /** - * Register form - */ - router.get('/register', async (req, res, next) => { - set(res.locals, 'pageMeta.title', 'Register') - const localStrg = await WIKI.db.authentication.getStrategy('local') - if (localStrg.selfRegistration) { - res.sendFile(path.join(WIKI.ROOTPATH, 'assets/index.html')) - } else { - next(new WIKI.Error.AuthRegistrationDisabled()) - } - }) - - /** - * Verify - */ - router.get('/verify/:token', bruteforce.prevent, async (req, res, next) => { - try { - const usr = await WIKI.db.userKeys.validateToken({ kind: 'verify', token: req.params.token }) - await WIKI.db.users.query().patch({ isVerified: true }).where('id', usr.id) - req.brute.reset() - if (WIKI.config.auth.enforce2FA) { - res.redirect('/login') - } else { - const result = await WIKI.db.users.refreshToken(usr) - res.cookie('jwt', result.token, { expires: DateTime.now().plus({ years: 1 }).toJSDate() }) - res.redirect('/') - } - } catch (err) { - next(err) - } - }) - - /** - * Reset Password - */ - router.get('/login-reset/:token', bruteforce.prevent, async (req, res, next) => { - try { - const usr = await WIKI.db.userKeys.validateToken({ kind: 'resetPwd', token: req.params.token }) - if (!usr) { - throw new Error('Invalid Token') - } - req.brute.reset() - - const changePwdContinuationToken = await WIKI.db.userKeys.generateToken({ - userId: usr.id, - kind: 'changePwd' - }) - const bgUrl = !isEmpty(WIKI.config.auth.loginBgUrl) ? WIKI.config.auth.loginBgUrl : '/_assets/img/splash/1.jpg' - res.render('login', { bgUrl, hideLocal: WIKI.config.auth.hideLocal, changePwdContinuationToken }) - } catch (err) { - next(err) - } - }) - - /** - * JWT Public Endpoints - */ - router.get('/.well-known/jwk.json', function (req, res, next) { - res.json(WIKI.config.certs.jwk) - }) - router.get('/.well-known/jwk.pem', function (req, res, next) { - res.send(WIKI.config.certs.public) - }) - - return router -} diff --git a/server/controllers/common.mjs b/server/controllers/common.mjs deleted file mode 100644 index e77cbabb1..000000000 --- a/server/controllers/common.mjs +++ /dev/null @@ -1,562 +0,0 @@ -import express from 'express' -import { parsePath } from '../helpers/page.mjs' -// import CleanCSS from 'clean-css' -import path from 'node:path' - -export default function () { - const router = express.Router() - const siteAssetsPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'assets') - - /** - * Robots.txt - */ - router.get('/robots.txt', (req, res, next) => { - res.type('text/plain') - if (WIKI.config.seo.robots.includes('noindex')) { - res.send('User-agent: *\nDisallow: /') - } else { - res.status(200).end() - } - }) - - /** - * Health Endpoint - */ - router.get('/healthz', (req, res, next) => { - if (WIKI.db.knex.client.pool.numFree() < 1 && WIKI.db.knex.client.pool.numUsed() < 1) { - res.status(503).json({ ok: false }).end() - } else { - res.status(200).json({ ok: true }).end() - } - }) - - /** - * Site Asset - */ - router.get('/_site{/:siteId}/:resource', async (req, res, next) => { - const site = req.params.siteId ? WIKI.sites[req.params.siteId] : await WIKI.db.sites.getSiteByHostname({ hostname: req.hostname }) - if (!site) { - return res.status(404).send('Site Not Found') - } - switch (req.params.resource) { - case 'logo': { - if (site.config.assets.logo) { - // TODO: Fetch from db if not in disk cache - res.sendFile(path.join(siteAssetsPath, `logo-${site.id}.${site.config.assets.logoExt}`)) - } else { - res.sendFile(path.join(WIKI.ROOTPATH, 'assets/_assets/logo-wikijs.svg')) - } - break - } - case 'favicon': { - if (site.config.assets.favicon) { - // TODO: Fetch from db if not in disk cache - res.sendFile(path.join(siteAssetsPath, `favicon-${site.id}.${site.config.assets.faviconExt}`)) - } else { - res.sendFile(path.join(WIKI.ROOTPATH, 'assets/_assets/logo-wikijs.svg')) - } - break - } - case 'loginbg': { - if (site.config.assets.loginBg) { - // TODO: Fetch from db if not in disk cache - res.sendFile(path.join(siteAssetsPath, `loginbg-${site.id}.jpg`)) - } else { - res.sendFile(path.join(WIKI.ROOTPATH, 'assets/_assets/bg/login.jpg')) - } - break - } - default: { - return res.status(404).send('Invalid Site Resource') - } - } - }) - - /** - * Asset Thumbnails / Download - */ - router.get('/_thumb/:id.webp', async (req, res, next) => { - const thumb = await WIKI.db.assets.getThumbnail({ - id: req.params.id - }) - - if (thumb) { - // TODO: Check permissions - - switch (thumb.previewState) { - case 'pending': { - res.redirect('/_assets/illustrations/fileman-pending.svg') - break - } - case 'ready': { - res.set('Content-Type', 'image/webp') - res.send(thumb.preview) - break - } - case 'failed': { - res.redirect('/_assets/illustrations/fileman-failed.svg') - break - } - default: { - return res.status(500).send('Invalid Thumbnail Preview State') - } - } - } else { - return res.sendStatus(404) - } - }) - - // router.get(['/_admin', '/_admin/*'], (req, res, next) => { - // if (!WIKI.auth.checkAccess(req.user, [ - // 'manage:system', - // 'write:users', - // 'manage:users', - // 'write:groups', - // 'manage:groups', - // 'manage:navigation', - // 'manage:theme', - // 'manage:api' - // ])) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.status(403).render('unauthorized', { action: 'view' }) - // } - - // _.set(res.locals, 'pageMeta.title', 'Admin') - // res.render('admin') - - // }) - - // /** - // * Download Page / Version - // */ - // router.get(['/d', '/d/*'], async (req, res, next) => { - // const pageArgs = pageHelper.parsePath(req.path, { stripExt: true }) - - // const versionId = (req.query.v) ? _.toSafeInteger(req.query.v) : 0 - - // const page = await WIKI.db.pages.getPageFromDb({ - // path: pageArgs.path, - // locale: pageArgs.locale, - // userId: req.user.id, - // isPrivate: false - // }) - - // pageArgs.tags = _.get(page, 'tags', []) - - // if (versionId > 0) { - // if (!WIKI.auth.checkAccess(req.user, ['read:history'], pageArgs)) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.render('unauthorized', { action: 'downloadVersion' }) - // } - // } else { - // if (!WIKI.auth.checkAccess(req.user, ['read:source'], pageArgs)) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.render('unauthorized', { action: 'download' }) - // } - // } - - // if (page) { - // const fileName = _.last(page.path.split('/')) + '.' + pageHelper.getFileExtension(page.contentType) - // res.attachment(fileName) - // if (versionId > 0) { - // const pageVersion = await WIKI.db.pageHistory.getVersion({ pageId: page.id, versionId }) - // res.send(pageHelper.injectPageMetadata(pageVersion)) - // } else { - // res.send(pageHelper.injectPageMetadata(page)) - // } - // } else { - // res.status(404).end() - // } - // }) - - // /** - // * Create/Edit document - // */ - // router.get(['/_edit', '/_edit/*'], async (req, res, next) => { - // const pageArgs = pageHelper.parsePath(req.path, { stripExt: true }) - // const site = await WIKI.db.sites.getSiteByHostname({ hostname: req.hostname }) - - // if (!site) { - // throw new Error('INVALID_SITE') - // } - - // if (pageArgs.path === '') { - // return res.redirect(`/_edit/home`) - // } - - // // if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) { - // // return res.redirect(`/_edit/${pageArgs.locale}/${pageArgs.path}`) - // // } - - // // req.i18n.changeLanguage(pageArgs.locale) - - // // -> Set Editor Lang - // _.set(res, 'locals.siteConfig.lang', pageArgs.locale) - // // _.set(res, 'locals.siteConfig.rtl', req.i18n.dir() === 'rtl') - - // // -> Check for reserved path - // if (pageHelper.isReservedPath(pageArgs.path)) { - // return next(new Error('Cannot create this page because it starts with a system reserved path.')) - // } - - // // -> Get page data from DB - // let page = await WIKI.db.pages.getPageFromDb({ - // siteId: site.id, - // path: pageArgs.path, - // locale: pageArgs.locale, - // userId: req.user.id - // }) - - // pageArgs.tags = _.get(page, 'tags', []) - - // // -> Effective Permissions - // const effectivePermissions = WIKI.auth.getEffectivePermissions(req, pageArgs) - - // const injectCode = { - // css: '', // WIKI.config.theming.injectCSS, - // head: '', // WIKI.config.theming.injectHead, - // body: '' // WIKI.config.theming.injectBody - // } - - // if (page) { - // // -> EDIT MODE - // if (!(effectivePermissions.pages.write || effectivePermissions.pages.manage)) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.render('unauthorized', { action: 'edit' }) - // } - - // // -> Get page tags - // await page.$relatedQuery('tags') - // page.tags = _.map(page.tags, 'tag') - - // // Handle missing extra field - // page.extra = page.extra || { css: '', js: '' } - - // // -> Beautify Script CSS - // if (!_.isEmpty(page.extra.css)) { - // page.extra.css = new CleanCSS({ format: 'beautify' }).minify(page.extra.css).styles - // } - - // _.set(res.locals, 'pageMeta.title', `Edit ${page.title}`) - // _.set(res.locals, 'pageMeta.description', page.description) - // page.mode = 'update' - // page.isPublished = (page.isPublished === true || page.isPublished === 1) ? 'true' : 'false' - // page.content = Buffer.from(page.content).toString('base64') - // } else { - // // -> CREATE MODE - // if (!effectivePermissions.pages.write) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.render('unauthorized', { action: 'create' }) - // } - - // _.set(res.locals, 'pageMeta.title', `New Page`) - // page = { - // path: pageArgs.path, - // localeCode: pageArgs.locale, - // editorKey: null, - // mode: 'create', - // content: null, - // title: null, - // description: null, - // updatedAt: new Date().toISOString(), - // extra: { - // css: '', - // js: '' - // } - // } - // } - - // res.render('editor', { page, injectCode, effectivePermissions }) - // }) - - // /** - // * History - // */ - // router.get(['/h', '/h/*'], async (req, res, next) => { - // const pageArgs = pageHelper.parsePath(req.path, { stripExt: true }) - - // if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) { - // return res.redirect(`/h/${pageArgs.locale}/${pageArgs.path}`) - // } - - // req.i18n.changeLanguage(pageArgs.locale) - - // _.set(res, 'locals.siteConfig.lang', pageArgs.locale) - // _.set(res, 'locals.siteConfig.rtl', req.i18n.dir() === 'rtl') - - // const page = await WIKI.db.pages.getPageFromDb({ - // path: pageArgs.path, - // locale: pageArgs.locale, - // userId: req.user.id, - // isPrivate: false - // }) - - // if (!page) { - // _.set(res.locals, 'pageMeta.title', 'Page Not Found') - // return res.status(404).render('notfound', { action: 'history' }) - // } - - // pageArgs.tags = _.get(page, 'tags', []) - - // const effectivePermissions = WIKI.auth.getEffectivePermissions(req, pageArgs) - - // if (!effectivePermissions.history.read) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.render('unauthorized', { action: 'history' }) - // } - - // if (page) { - // _.set(res.locals, 'pageMeta.title', page.title) - // _.set(res.locals, 'pageMeta.description', page.description) - - // res.render('history', { page, effectivePermissions }) - // } else { - // res.redirect(`/${pageArgs.path}`) - // } - // }) - - // /** - // * Page ID redirection - // */ - // router.get(['/i', '/i/:id'], async (req, res, next) => { - // const pageId = _.toSafeInteger(req.params.id) - // if (pageId <= 0) { - // return res.redirect('/') - // } - - // const page = await WIKI.db.pages.query().column(['path', 'localeCode', 'isPrivate', 'privateNS']).findById(pageId) - // if (!page) { - // _.set(res.locals, 'pageMeta.title', 'Page Not Found') - // return res.status(404).render('notfound', { action: 'view' }) - // } - - // if (!WIKI.auth.checkAccess(req.user, ['read:pages'], { - // locale: page.localeCode, - // path: page.path, - // private: page.isPrivate, - // privateNS: page.privateNS, - // explicitLocale: false, - // tags: page.tags - // })) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.render('unauthorized', { action: 'view' }) - // } - - // if (WIKI.config.lang.namespacing) { - // return res.redirect(`/${page.localeCode}/${page.path}`) - // } else { - // return res.redirect(`/${page.path}`) - // } - // }) - - // /** - // * Source - // */ - // router.get(['/s', '/s/*'], async (req, res, next) => { - // const pageArgs = pageHelper.parsePath(req.path, { stripExt: true }) - // const versionId = (req.query.v) ? _.toSafeInteger(req.query.v) : 0 - - // const page = await WIKI.db.pages.getPageFromDb({ - // path: pageArgs.path, - // locale: pageArgs.locale, - // userId: req.user.id, - // isPrivate: false - // }) - - // pageArgs.tags = _.get(page, 'tags', []) - - // if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) { - // return res.redirect(`/s/${pageArgs.locale}/${pageArgs.path}`) - // } - - // // -> Effective Permissions - // const effectivePermissions = WIKI.auth.getEffectivePermissions(req, pageArgs) - - // _.set(res, 'locals.siteConfig.lang', pageArgs.locale) - // _.set(res, 'locals.siteConfig.rtl', req.i18n.dir() === 'rtl') - - // if (versionId > 0) { - // if (!effectivePermissions.history.read) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.render('unauthorized', { action: 'sourceVersion' }) - // } - // } else { - // if (!effectivePermissions.source.read) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.render('unauthorized', { action: 'source' }) - // } - // } - - // if (page) { - // if (versionId > 0) { - // const pageVersion = await WIKI.db.pageHistory.getVersion({ pageId: page.id, versionId }) - // _.set(res.locals, 'pageMeta.title', pageVersion.title) - // _.set(res.locals, 'pageMeta.description', pageVersion.description) - // res.render('source', { - // page: { - // ...page, - // ...pageVersion - // }, - // effectivePermissions - // }) - // } else { - // _.set(res.locals, 'pageMeta.title', page.title) - // _.set(res.locals, 'pageMeta.description', page.description) - - // res.render('source', { page, effectivePermissions }) - // } - // } else { - // res.redirect(`/${pageArgs.path}`) - // } - // }) - - // /** - // * Tags - // */ - // router.get(['/t', '/t/*'], (req, res, next) => { - // _.set(res.locals, 'pageMeta.title', 'Tags') - // res.render('tags') - // }) - - /** - * User Avatar - */ - router.get('/_user/:uid/avatar', async (req, res, next) => { - if (!WIKI.auth.checkAccess(req.user, ['read:pages'])) { - return res.sendStatus(403) - } - const av = await WIKI.db.users.getUserAvatarData(req.params.uid) - if (av) { - res.set('Content-Type', 'image/jpeg') - return res.send(av) - } - - return res.sendStatus(404) - }) - - /** - * Metrics (Prometheus) - */ - router.get('/metrics', async (req, res, next) => { - if (WIKI.config.metrics.isEnabled) { - if (!WIKI.auth.checkAccess(req.user, ['read:metrics'])) { - return res.sendStatus(403) - } - WIKI.metrics.render(res) - } else { - next() - } - }) - - // /** - // * View document / asset - // */ - // router.get('/*', async (req, res, next) => { - // const stripExt = _.some(WIKI.data.pageExtensions, ext => _.endsWith(req.path, `.${ext}`)) - // const pageArgs = pageHelper.parsePath(req.path, { stripExt }) - // const isPage = (stripExt || pageArgs.path.indexOf('.') === -1) - // const site = await WIKI.db.sites.getSiteByHostname({ hostname: req.hostname }) - - // if (!site) { - // throw new Error('INVALID_SITE') - // } - - // if (isPage) { - // // if (WIKI.config.lang.namespacing && !pageArgs.explicitLocale) { - // // return res.redirect(`/${pageArgs.locale}/${pageArgs.path}`) - // // } - - // // req.i18n.changeLanguage(pageArgs.locale) - - // try { - // // -> Get Page from cache - // const page = await WIKI.db.pages.getPage({ - // siteId: site.id, - // path: pageArgs.path, - // locale: pageArgs.locale, - // userId: req.user.id - // }) - // pageArgs.tags = _.get(page, 'tags', []) - - // // -> Effective Permissions - // const effectivePermissions = WIKI.auth.getEffectivePermissions(req, pageArgs) - - // // -> Check User Access - // if (!effectivePermissions.pages.read) { - // if (req.user.id === WIKI.auth.guest.id) { - // res.cookie('loginRedirect', req.path, { - // maxAge: 15 * 60 * 1000 - // }) - // } - // if (pageArgs.path === 'home' && req.user.id === WIKI.auth.guest.id) { - // return res.redirect('/login') - // } - // return res.redirect(`/_error/unauthorized?from=${req.path}`) - // } - - // _.set(res, 'locals.siteConfig.lang', pageArgs.locale) - // // _.set(res, 'locals.siteConfig.rtl', req.i18n.dir() === 'rtl') - - // if (page) { - // _.set(res.locals, 'pageMeta.title', page.title) - // _.set(res.locals, 'pageMeta.description', page.description) - - // // -> Check Publishing State - // let pageIsPublished = page.isPublished - // if (pageIsPublished && !_.isEmpty(page.publishStartDate)) { - // pageIsPublished = moment(page.publishStartDate).isSameOrBefore() - // } - // if (pageIsPublished && !_.isEmpty(page.publishEndDate)) { - // pageIsPublished = moment(page.publishEndDate).isSameOrAfter() - // } - // if (!pageIsPublished && !effectivePermissions.pages.write) { - // _.set(res.locals, 'pageMeta.title', 'Unauthorized') - // return res.status(403).render('unauthorized', { - // action: 'view' - // }) - // } - - // // -> Render view - // res.sendFile(path.join(WIKI.ROOTPATH, 'assets/index.html')) - // } else if (pageArgs.path === 'home') { - // res.redirect('/_welcome') - // } else { - // _.set(res.locals, 'pageMeta.title', 'Page Not Found') - // if (effectivePermissions.pages.write) { - // res.status(404).render('new', { path: pageArgs.path, locale: pageArgs.locale }) - // } else { - // res.status(404).render('notfound', { action: 'view' }) - // } - // } - // } catch (err) { - // next(err) - // } - // } else { - // if (!WIKI.auth.checkAccess(req.user, ['read:assets'], pageArgs)) { - // return res.sendStatus(403) - // } - - // await WIKI.db.assets.getAsset(pageArgs.path, res) - // } - // }) - - router.get('/{*splat}', async (req, res, next) => { - const site = await WIKI.db.sites.getSiteByHostname({ hostname: req.hostname }) - - if (!site) { - throw new Error('INVALID_SITE') - } - - const stripExt = site.config.pageExtensions.some(ext => req.path.endsWith(`.${ext}`)) - const pathArgs = parsePath(req.path, { stripExt }) - const isPage = (stripExt || pathArgs.path.indexOf('.') === -1) - - if (isPage) { - res.sendFile(path.join(WIKI.ROOTPATH, 'assets/index.html')) - } else { - await WIKI.db.assets.getAsset({ pathArgs, siteId: site.id }, res) - } - }) - - return router -} diff --git a/server/controllers/ssl.mjs b/server/controllers/ssl.mjs deleted file mode 100644 index b3633f85f..000000000 --- a/server/controllers/ssl.mjs +++ /dev/null @@ -1,39 +0,0 @@ -import express from 'express' -import { get } from 'lodash-es' -import qs from 'querystring' - -export default function () { - const router = express.Router() - - /** - * Let's Encrypt Challenge - */ - router.get('/.well-known/acme-challenge/:token', (req, res, next) => { - res.type('text/plain') - if (get(WIKI.config, 'letsencrypt.challenge', false)) { - if (WIKI.config.letsencrypt.challenge.token === req.params.token) { - res.send(WIKI.config.letsencrypt.challenge.keyAuthorization) - WIKI.logger.info(`(LETSENCRYPT) Received valid challenge request. [ ACCEPTED ]`) - } else { - res.status(406).send('Invalid Challenge Token!') - WIKI.logger.warn(`(LETSENCRYPT) Received invalid challenge request. [ REJECTED ]`) - } - } else { - res.status(418).end() - } - }) - - /** - * Redirect to HTTPS if HTTP Redirection is enabled - */ - // router.all('/*', (req, res, next) => { - // if (WIKI.config.server.sslRedir && !req.secure && WIKI.servers.servers.https) { - // let query = (!_.isEmpty(req.query)) ? `?${qs.stringify(req.query)}` : `` - // return res.redirect(`https://${req.hostname}${req.originalUrl}${query}`) - // } else { - // next() - // } - // }) - - return router -} diff --git a/server/controllers/ws.mjs b/server/controllers/ws.mjs deleted file mode 100644 index 6fe0bbe5e..000000000 --- a/server/controllers/ws.mjs +++ /dev/null @@ -1,29 +0,0 @@ -import chalk from 'chalk' -import os from 'node:os' - -export default function () { - WIKI.servers.ws.on('connection', (socket) => { - // TODO: Validate token + permissions - const token = socket.handshake.auth.token - // console.info(token) - - const listeners = {} - - socket.on('server:logs', () => { - socket.emit('server:log', chalk.greenBright(`Streaming logs from ${chalk.bold('Wiki.js')} instance ${chalk.yellowBright.bold(WIKI.INSTANCE_ID)} on host ${chalk.yellowBright.bold(os.hostname())}...`)) - listeners.serverLogs = (msg) => { - socket.emit('server:log', msg) - } - WIKI.logger.ws.addListener('log', listeners.serverLogs) - WIKI.logger.warn(`User XYZ is streaming server logs. ( Listeners: ${WIKI.logger.ws.listenerCount('log')} )`) - }) - - socket.on('disconnect', () => { - if (listeners.serverLogs) { - WIKI.logger.ws.removeListener('log', listeners.serverLogs) - delete listeners.serverLogs - } - WIKI.logger.warn(`User XYZ has stopped streaming server logs. ( Listeners: ${WIKI.logger.ws.listenerCount('log')} )`) - }) - }) -} diff --git a/server/core/asar.mjs b/server/core/asar.mjs deleted file mode 100644 index 259076c75..000000000 --- a/server/core/asar.mjs +++ /dev/null @@ -1,127 +0,0 @@ -import pickle from 'chromium-pickle-js' -import path from 'node:path' -import { UINT64 } from 'cuint' -import fs from 'node:fs' - -/** - * Based of express-serve-asar (https://github.com/toyobayashi/express-serve-asar) - * by Fenglin Li (https://github.com/toyobayashi) - */ - -export default { - fdCache: {}, - async serve (pkgName, req, res, next) { - const packages = { - twemoji: path.join(WIKI.ROOTPATH, 'assets/svg/twemoji.asar') - } - const file = this.readFilesystemSync(packages[pkgName]) - const { filesystem, fd } = file - const info = filesystem.getFile(req.path.substring(1)) - if (info) { - res.set({ - 'Content-Type': 'image/svg+xml', - 'Content-Length': info.size - }) - - fs.createReadStream('', { - fd, - autoClose: false, - start: 8 + filesystem.headerSize + parseInt(info.offset, 10), - end: 8 + filesystem.headerSize + parseInt(info.offset, 10) + info.size - 1 - }).on('error', (err) => { - WIKI.logger.warn(err) - res.sendStatus(404) - }).pipe(res.status(200)) - } else { - res.sendStatus(404) - } - }, - async unload () { - const fds = Object.values(this.fdCache) - if (fds.length > 0) { - WIKI.logger.info('Closing ASAR file descriptors...') - const closeAsync = require('util').promisify(fs.close) - await Promise.all(fds.map(x => closeAsync(x.fd))) - this.fdCache = {} - } - }, - readArchiveHeaderSync (fd) { - let size - let headerBuf - - const sizeBuf = Buffer.alloc(8) - if (fs.readSync(fd, sizeBuf, 0, 8, null) !== 8) { - throw new Error('Unable to read header size') - } - - const sizePickle = pickle.createFromBuffer(sizeBuf) - size = sizePickle.createIterator().readUInt32() - headerBuf = Buffer.alloc(size) - if (fs.readSync(fd, headerBuf, 0, size, null) !== size) { - throw new Error('Unable to read header') - } - - const headerPickle = pickle.createFromBuffer(headerBuf) - const header = headerPickle.createIterator().readString() - return { header: JSON.parse(header), headerSize: size } - }, - readFilesystemSync (archive) { - if (!this.fdCache[archive]) { - const fd = fs.openSync(archive, 'r') - const header = this.readArchiveHeaderSync(fd) - const filesystem = new Filesystem(archive) - filesystem.header = header.header - filesystem.headerSize = header.headerSize - this.fdCache[archive] = { - fd, - filesystem - } - } - - return this.fdCache[archive] - } -} - -class Filesystem { - constructor (src) { - this.src = path.resolve(src) - this.header = { files: {} } - this.offset = UINT64(0) - } - - searchNodeFromDirectory (p) { - let json = this.header - const dirs = p.split(path.sep) - for (const dir of dirs) { - if (dir !== '.') { - json = json.files[dir] - } - } - return json - } - - getNode (p) { - const node = this.searchNodeFromDirectory(path.dirname(p)) - const name = path.basename(p) - if (name) { - return node.files[name] - } else { - return node - } - } - - getFile (p, followLinks) { - followLinks = typeof followLinks === 'undefined' ? true : followLinks - const info = this.getNode(p) - - if (!info) { - return false - } - - if (info.link && followLinks) { - return this.getFile(info.link) - } else { - return info - } - } -} diff --git a/server/core/auth.mjs b/server/core/auth.mjs deleted file mode 100644 index 10440a388..000000000 --- a/server/core/auth.mjs +++ /dev/null @@ -1,487 +0,0 @@ -import passport from 'passport' -import passportJWT from 'passport-jwt' -import _ from 'lodash' -import jwt from 'jsonwebtoken' -import ms from 'ms' -import { DateTime } from 'luxon' -import util from 'node:util' -import crypto from 'node:crypto' -import { pem2jwk } from 'pem-jwk' -import NodeCache from 'node-cache' -import { extractJWT } from '../helpers/security.mjs' - -const randomBytes = util.promisify(crypto.randomBytes) - -export default { - strategies: {}, - guest: { - cacheExpiration: DateTime.utc().minus({ days: 1 }) - }, - groups: {}, - validApiKeys: [], - revocationList: new NodeCache(), - - /** - * Initialize the authentication module - */ - init() { - this.passport = passport - - passport.serializeUser((user, done) => { - done(null, user.id) - }) - - passport.deserializeUser(async (id, done) => { - try { - const user = await WIKI.db.users.query().findById(id).withGraphFetched('groups').modifyGraph('groups', builder => { - builder.select('groups.id', 'permissions') - }) - if (user) { - done(null, user) - } else { - done(new Error(WIKI.lang.t('auth:errors:usernotfound')), null) - } - } catch (err) { - done(err, null) - } - }) - - this.reloadGroups() - this.reloadApiKeys() - - return this - }, - - /** - * Load authentication strategies - */ - async activateStrategies () { - try { - // Unload any active strategies - WIKI.auth.strategies = {} - const currentStrategies = _.keys(passport._strategies) - _.pull(currentStrategies, 'session') - _.forEach(currentStrategies, stg => { passport.unuse(stg) }) - - // Load JWT - passport.use('jwt', new passportJWT.Strategy({ - jwtFromRequest: extractJWT, - secretOrKey: WIKI.config.auth.certs.public, - audience: WIKI.config.auth.audience, - issuer: 'urn:wiki.js', - algorithms: ['RS256'] - }, (jwtPayload, cb) => { - cb(null, jwtPayload) - })) - - // Load enabled strategies - const enabledStrategies = await WIKI.db.authentication.getStrategies({ enabledOnly: true }) - for (const stg of enabledStrategies) { - try { - const strategy = (await import(`../modules/authentication/${stg.module}/authentication.mjs`)).default - strategy.init(passport, stg.id, stg.config) - - WIKI.auth.strategies[stg.id] = { - ...strategy, - ...stg - } - WIKI.logger.info(`Authentication Strategy ${stg.displayName}: [ OK ]`) - } catch (err) { - WIKI.logger.error(`Authentication Strategy ${stg.displayName} (${stg.id}): [ FAILED ]`) - WIKI.logger.error(err) - } - } - } catch (err) { - WIKI.logger.error(`Failed to initialize Authentication Strategies: [ ERROR ]`) - WIKI.logger.error(err) - } - }, - - /** - * Authenticate current request - * - * @param {Express Request} req - * @param {Express Response} res - * @param {Express Next Callback} next - */ - authenticate (req, res, next) { - req.isAuthenticated = false - - WIKI.auth.passport.authenticate('jwt', { session: false }, async (err, user, info) => { - if (err) { return next() } - let mustRevalidate = false - const strategyId = user.pvd - - // Expired but still valid within N days, just renew - if (info instanceof Error && info.name === 'TokenExpiredError') { - const expiredDate = (info.expiredAt instanceof Date) ? info.expiredAt.toISOString() : info.expiredAt - if (DateTime.utc().minus(ms(WIKI.config.auth.tokenRenewal)) < DateTime.fromISO(expiredDate)) { - mustRevalidate = true - } - } - - // Check if user / group is in revocation list - if (user && !user.api && !mustRevalidate) { - const uRevalidate = WIKI.auth.revocationList.get(`u${_.toString(user.id)}`) - if (uRevalidate && user.iat < uRevalidate) { - mustRevalidate = true - } else if (DateTime.fromSeconds(user.iat) <= WIKI.startedAt) { // Prevent new / restarted instance from allowing revoked tokens - mustRevalidate = true - } else { - for (const gid of user.groups) { - const gRevalidate = WIKI.auth.revocationList.get(`g${_.toString(gid)}`) - if (gRevalidate && user.iat < gRevalidate) { - mustRevalidate = true - break - } - } - } - } - - // Revalidate and renew token - if (mustRevalidate && !req.path.startsWith('/_graphql')) { - const jwtPayload = jwt.decode(extractJWT(req)) - try { - const newToken = await WIKI.db.users.refreshToken(jwtPayload.id, jwtPayload.pvd) - user = newToken.user - user.permissions = user.getPermissions() - user.groups = user.getGroups() - user.strategyId = strategyId - req.user = user - - // Try headers, otherwise cookies for response - if (req.get('content-type') === 'application/json') { - res.set('new-jwt', newToken.token) - } else { - res.cookie('jwt', newToken.token, { expires: DateTime.utc().plus({ days: 365 }).toJSDate() }) - } - } catch (errc) { - WIKI.logger.warn(errc) - return next() - } - } else if (user) { - user = await WIKI.db.users.getById(user.id) - user.permissions = user.getPermissions() - user.groups = user.getGroups() - user.strategyId = strategyId - req.user = user - } else { - // JWT is NOT valid, set as guest - if (WIKI.auth.guest.cacheExpiration <= DateTime.utc()) { - WIKI.auth.guest = await WIKI.db.users.getGuestUser() - WIKI.auth.guest.cacheExpiration = DateTime.utc().plus({ minutes: 1 }) - } - req.user = WIKI.auth.guest - req.isAuthenticated = false - return next() - } - - // Process API tokens - if (_.has(user, 'api')) { - if (!WIKI.config.api.isEnabled) { - return next(new Error('API is disabled. You must enable it from the Administration Area first.')) - } else if (_.includes(WIKI.auth.validApiKeys, user.api)) { - req.user = { - id: 1, - email: 'api@localhost', - name: 'API', - pictureUrl: null, - timezone: 'America/New_York', - locale: 'en', - permissions: _.get(WIKI.auth.groups, `${user.grp}.permissions`, []), - groups: [user.grp], - getPermissions () { - return req.user.permissions - }, - getGroups () { - return req.user.groups - } - } - return next() - } else { - return next(new Error('API Key is invalid or was revoked.')) - } - } - - // JWT is valid - req.logIn(user, { session: false }, (errc) => { - if (errc) { return next(errc) } - req.isAuthenticated = true - next() - }) - })(req, res, next) - }, - - /** - * Check if user has access to resource - * - * @param {User} user - * @param {Array} permissions - * @param {String|Boolean} path - */ - checkAccess(user, permissions = [], page = false) { - const userPermissions = user.permissions ? user.permissions : user.getPermissions() - - // System Admin - if (_.includes(userPermissions, 'manage:system')) { - return true - } - - // Check Permissions - if (_.intersection(userPermissions, permissions).length < 1) { - return false - } - - // Skip if no page rule to check - if (!page) { - return true - } - - // Check Page Rules - if (user.groups) { - let checkState = { - deny: false, - match: false, - specificity: '' - } - user.groups.forEach(grp => { - const grpId = _.isObject(grp) ? _.get(grp, 'id', 0) : grp - _.get(WIKI.auth.groups, `${grpId}.pageRules`, []).forEach(rule => { - if (rule.locales && rule.locales.length > 0) { - if (!rule.locales.includes(page.locale)) { return } - } - if (_.intersection(rule.roles, permissions).length > 0) { - switch (rule.match) { - case 'START': - if (_.startsWith(`/${page.path}`, `/${rule.path}`)) { - checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['END', 'REGEX', 'EXACT', 'TAG'] }) - } - break - case 'END': - if (_.endsWith(page.path, rule.path)) { - checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['REGEX', 'EXACT', 'TAG'] }) - } - break - case 'REGEX': - const reg = new RegExp(rule.path) - if (reg.test(page.path)) { - checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: ['EXACT', 'TAG'] }) - } - break - case 'TAG': - _.get(page, 'tags', []).forEach(tag => { - if (tag.tag === rule.path) { - checkState = this._applyPageRuleSpecificity({ - rule, - checkState, - higherPriority: ['EXACT'] - }) - } - }) - break - case 'EXACT': - if (`/${page.path}` === `/${rule.path}`) { - checkState = this._applyPageRuleSpecificity({ rule, checkState, higherPriority: [] }) - } - break - } - } - }) - }) - - return (checkState.match && !checkState.deny) - } - - return false - }, - - /** - * Check for exclusive permissions (contain any X permission(s) but not any Y permission(s)) - * - * @param {User} user - * @param {Array} includePermissions - * @param {Array} excludePermissions - */ - checkExclusiveAccess(user, includePermissions = [], excludePermissions = []) { - const userPermissions = user.permissions ? user.permissions : user.getPermissions() - - // Check Inclusion Permissions - if (_.intersection(userPermissions, includePermissions).length < 1) { - return false - } - - // Check Exclusion Permissions - if (_.intersection(userPermissions, excludePermissions).length > 0) { - return false - } - - return true - }, - - /** - * Check and apply Page Rule specificity - * - * @access private - */ - _applyPageRuleSpecificity ({ rule, checkState, higherPriority = [] }) { - if (rule.path.length === checkState.specificity.length) { - // Do not override higher priority rules - if (_.includes(higherPriority, checkState.match)) { - return checkState - } - // Do not override a previous DENY rule with same match - if (rule.match === checkState.match && checkState.deny && !rule.deny) { - return checkState - } - } else if (rule.path.length < checkState.specificity.length) { - // Do not override higher specificity rules - return checkState - } - - return { - deny: rule.deny, - match: rule.match, - specificity: rule.path - } - }, - - /** - * Reload Groups from DB - */ - async reloadGroups () { - const groupsArray = await WIKI.db.groups.query() - this.groups = _.keyBy(groupsArray, 'id') - WIKI.auth.guest.cacheExpiration = DateTime.utc().minus({ days: 1 }) - }, - - /** - * Reload valid API Keys from DB - */ - async reloadApiKeys () { - const keys = await WIKI.db.apiKeys.query().select('id').where('isRevoked', false).andWhere('expiration', '>', DateTime.utc().toISO()) - this.validApiKeys = _.map(keys, 'id') - }, - - /** - * Generate New Authentication Public / Private Key Certificates - */ - async regenerateCertificates () { - WIKI.logger.info('Regenerating certificates...') - - _.set(WIKI.config, 'sessionSecret', (await randomBytes(32)).toString('hex')) - const certs = crypto.generateKeyPairSync('rsa', { - modulusLength: 2048, - publicKeyEncoding: { - type: 'pkcs1', - format: 'pem' - }, - privateKeyEncoding: { - type: 'pkcs1', - format: 'pem', - cipher: 'aes-256-cbc', - passphrase: WIKI.config.sessionSecret - } - }) - - _.set(WIKI.config, 'certs', { - jwk: pem2jwk(certs.publicKey), - public: certs.publicKey, - private: certs.privateKey - }) - - await WIKI.configSvc.saveToDb([ - 'certs', - 'sessionSecret' - ]) - - await WIKI.auth.activateStrategies() - WIKI.events.outbound.emit('reloadAuthStrategies') - - WIKI.logger.info('Regenerated certificates: [ COMPLETED ]') - }, - - /** - * Reset Guest User - */ - async resetGuestUser() { - WIKI.logger.info('Resetting guest account...') - const guestGroup = await WIKI.db.groups.query().where('id', 2).first() - - await WIKI.db.users.query().delete().where({ - providerKey: 'local', - email: 'guest@example.com' - }).orWhere('id', 2) - - const guestUser = await WIKI.db.users.query().insert({ - id: 2, - provider: 'local', - email: 'guest@example.com', - name: 'Guest', - password: '', - locale: 'en', - defaultEditor: 'markdown', - tfaIsActive: false, - isSystem: true, - isActive: true, - isVerified: true - }) - await guestUser.$relatedQuery('groups').relate(guestGroup.id) - - WIKI.logger.info('Guest user has been reset: [ COMPLETED ]') - }, - - /** - * Subscribe to HA propagation events - */ - subscribeToEvents() { - WIKI.events.inbound.on('reloadGroups', () => { - WIKI.auth.reloadGroups() - }) - WIKI.events.inbound.on('reloadApiKeys', () => { - WIKI.auth.reloadApiKeys() - }) - WIKI.events.inbound.on('reloadAuthStrategies', () => { - WIKI.auth.activateStrategies() - }) - WIKI.events.inbound.on('addAuthRevoke', (args) => { - WIKI.auth.revokeUserTokens(args) - }) - }, - - /** - * Get all user permissions for a specific page - */ - getEffectivePermissions (req, page) { - return { - comments: { - read: WIKI.auth.checkAccess(req.user, ['read:comments'], page), - write: WIKI.auth.checkAccess(req.user, ['write:comments'], page), - manage: WIKI.auth.checkAccess(req.user, ['manage:comments'], page) - }, - history: { - read: WIKI.auth.checkAccess(req.user, ['read:history'], page) - }, - source: { - read: WIKI.auth.checkAccess(req.user, ['read:source'], page) - }, - pages: { - read: WIKI.auth.checkAccess(req.user, ['read:pages'], page), - write: WIKI.auth.checkAccess(req.user, ['write:pages'], page), - manage: WIKI.auth.checkAccess(req.user, ['manage:pages'], page), - delete: WIKI.auth.checkAccess(req.user, ['delete:pages'], page), - script: WIKI.auth.checkAccess(req.user, ['write:scripts'], page), - style: WIKI.auth.checkAccess(req.user, ['write:styles'], page) - }, - system: { - manage: WIKI.auth.checkAccess(req.user, ['manage:system'], page) - } - } - }, - - /** - * Add user / group ID to JWT revocation list, forcing all requests to be validated against the latest permissions - */ - revokeUserTokens ({ id, kind = 'u' }) { - WIKI.auth.revocationList.set(`${kind}${_.toString(id)}`, Math.round(DateTime.utc().minus({ seconds: 5 }).toSeconds()), Math.ceil(ms(WIKI.config.auth.tokenExpiration) / 1000)) - } -} diff --git a/server/core/config.mjs b/server/core/config.mjs deleted file mode 100644 index 603aa6682..000000000 --- a/server/core/config.mjs +++ /dev/null @@ -1,148 +0,0 @@ -import { defaultsDeep, get, isPlainObject } from 'lodash-es' -import chalk from 'chalk' -import cfgHelper from '../helpers/config.mjs' -import regexData from '../app/regex.mjs' -import fs from 'node:fs/promises' -import path from 'node:path' -import yaml from 'js-yaml' - -export default { - /** - * Load root config from disk - */ - async init(silent = false) { - const confPaths = { - config: path.join(WIKI.ROOTPATH, 'config.yml'), - data: path.join(WIKI.SERVERPATH, 'app/data.yml') - } - - if (process.env.dockerdev) { - confPaths.config = path.join(WIKI.ROOTPATH, `dev/containers/config.yml`) - } - - if (process.env.CONFIG_FILE) { - confPaths.config = path.resolve(WIKI.ROOTPATH, process.env.CONFIG_FILE) - } - - if (!silent) { - process.stdout.write(chalk.blue(`Loading configuration from ${confPaths.config}... `)) - } - - let appconfig = {} - let appdata = {} - - try { - appconfig = yaml.load( - cfgHelper.parseConfigValue( - await fs.readFile(confPaths.config, 'utf8') - ) - ) - appdata = yaml.load(await fs.readFile(confPaths.data, 'utf8')) - appdata.regex = regexData - if (!silent) { - console.info(chalk.green.bold(`OK`)) - } - } catch (err) { - console.error(chalk.red.bold(`FAILED`)) - console.error(err.message) - - console.error(chalk.red.bold(`>>> Unable to read configuration file! Did you create the config.yml file?`)) - process.exit(1) - } - - // Merge with defaults - - appconfig = defaultsDeep(appconfig, appdata.defaults.config) - - // Override port - - if (appconfig.port < 1 || process.env.HEROKU) { - appconfig.port = process.env.PORT || 80 - } - - if (process.env.WIKI_PORT) { - appconfig.port = process.env.WIKI_PORT || 80 - } - - // Load package info - - const packageInfo = JSON.parse(await fs.readFile(path.join(WIKI.SERVERPATH, 'package.json'), 'utf-8')) - - // Load DB Password from Docker Secret File - if (process.env.DB_PASS_FILE) { - if (!silent) { - console.info(chalk.blue(`DB_PASS_FILE is defined. Will use secret from file.`)) - } - try { - appconfig.db.pass = await fs.readFile(process.env.DB_PASS_FILE, 'utf8').trim() - } catch (err) { - console.error(chalk.red.bold(`>>> Failed to read Docker Secret File using path defined in DB_PASS_FILE env variable!`)) - console.error(err.message) - process.exit(1) - } - } - - WIKI.config = appconfig - WIKI.data = appdata - WIKI.version = packageInfo.version - WIKI.releaseDate = packageInfo.releaseDate - WIKI.devMode = (packageInfo.dev === true) - }, - - /** - * Load config from DB - */ - async loadFromDb() { - const conf = await WIKI.db.settings.getConfig() - if (conf) { - WIKI.config = defaultsDeep(conf, WIKI.config) - } else { - WIKI.logger.warn('Missing DB Configuration!') - process.exit(1) - } - }, - /** - * Save config to DB - * - * @param {Array} keys Array of keys to save - * @returns Promise - */ - async saveToDb(keys, propagate = true) { - try { - for (const key of keys) { - let value = get(WIKI.config, key, null) - if (!isPlainObject(value)) { - value = { v: value } - } - let affectedRows = await WIKI.db.settings.query().patch({ value }).where('key', key) - if (affectedRows === 0 && value) { - await WIKI.db.settings.query().insert({ key, value }) - } - } - if (propagate) { - WIKI.events.outbound.emit('reloadConfig') - } - } catch (err) { - WIKI.logger.error(`Failed to save configuration to DB: ${err.message}`) - return false - } - - return true - }, - /** - * Apply Dev Flags - */ - async applyFlags() { - WIKI.db.knex.client.config.debug = WIKI.config.flags.sqlLog - }, - - /** - * Subscribe to HA propagation events - */ - subscribeToEvents() { - WIKI.events.inbound.on('reloadConfig', async () => { - await WIKI.configSvc.loadFromDb() - await WIKI.configSvc.applyFlags() - }) - } -} diff --git a/server/core/db.mjs b/server/core/db.mjs deleted file mode 100644 index 814d37380..000000000 --- a/server/core/db.mjs +++ /dev/null @@ -1,243 +0,0 @@ -import { create, get, has, isEmpty, isPlainObject } from 'lodash-es' -import path from 'node:path' -import knex from 'knex' -import fs from 'node:fs/promises' -import Objection from 'objection' -import PGPubSub from 'pg-pubsub' -import semver from 'semver' - -import { createDeferred } from '../helpers/common.mjs' -import migrationSource from '../db/migrator-source.mjs' -// const migrateFromLegacy = require('../db/legacy') -import { setTimeout } from 'node:timers/promises' - -/** - * ORM DB module - */ -export default { - Objection, - knex: null, - listener: null, - config: null, - VERSION: null, - LEGACY: false, - onReady: createDeferred(), - connectAttempts: 0, - /** - * Initialize DB - */ - async init (workerMode = false) { - WIKI.logger.info('Checking DB configuration...') - - // Fetch DB Config - - this.config = (!isEmpty(process.env.DATABASE_URL)) - ? process.env.DATABASE_URL - : { - host: WIKI.config.db.host.toString(), - user: WIKI.config.db.user.toString(), - password: WIKI.config.db.pass.toString(), - database: WIKI.config.db.db.toString(), - port: WIKI.config.db.port - } - - // Handle SSL Options - - let dbUseSSL = (WIKI.config.db.ssl === true || WIKI.config.db.ssl === 'true' || WIKI.config.db.ssl === 1 || WIKI.config.db.ssl === '1') - let sslOptions = null - if (dbUseSSL && isPlainObject(this.config) && get(WIKI.config.db, 'sslOptions.auto', null) === false) { - sslOptions = WIKI.config.db.sslOptions - sslOptions.rejectUnauthorized = sslOptions.rejectUnauthorized !== false - if (sslOptions.ca && sslOptions.ca.indexOf('-----') !== 0) { - sslOptions.ca = await fs.readFile(path.resolve(WIKI.ROOTPATH, sslOptions.ca), 'utf-8') - } - if (sslOptions.cert) { - sslOptions.cert = await fs.readFile(path.resolve(WIKI.ROOTPATH, sslOptions.cert), 'utf-8') - } - if (sslOptions.key) { - sslOptions.key = await fs.readFile(path.resolve(WIKI.ROOTPATH, sslOptions.key), 'utf-8') - } - if (sslOptions.pfx) { - sslOptions.pfx = await fs.readFile(path.resolve(WIKI.ROOTPATH, sslOptions.pfx), 'utf-8') - } - } else { - sslOptions = true - } - - // Handle inline SSL CA Certificate mode - if (!isEmpty(process.env.DB_SSL_CA)) { - const chunks = [] - for (let i = 0, charsLength = process.env.DB_SSL_CA.length; i < charsLength; i += 64) { - chunks.push(process.env.DB_SSL_CA.substring(i, i + 64)) - } - - dbUseSSL = true - sslOptions = { - rejectUnauthorized: true, - ca: '-----BEGIN CERTIFICATE-----\n' + chunks.join('\n') + '\n-----END CERTIFICATE-----\n' - } - } - - if (dbUseSSL && isPlainObject(this.config)) { - this.config.ssl = (sslOptions === true) ? { rejectUnauthorized: true } : sslOptions - } - - // Initialize Knex - this.knex = knex({ - client: 'pg', - useNullAsDefault: true, - asyncStackTraces: WIKI.IS_DEBUG, - connection: this.config, - searchPath: [WIKI.config.db.schema], - pool: { - ...workerMode ? { min: 0, max: 1 } : WIKI.config.pool - // FIXME: Throws DeprecatingWarning because Knex encapsulates this into a promisify... - // async afterCreate (conn, done) { - // // -> Set Connection App Name - // if (workerMode) { - // await conn.query(`set application_name = 'Wiki.js - ${WIKI.INSTANCE_ID}'`) - // } else { - // await conn.query(`set application_name = 'Wiki.js - ${WIKI.INSTANCE_ID}:MAIN'`) - // } - // done() - // } - }, - debug: WIKI.IS_DEBUG - }) - - Objection.Model.knex(this.knex) - - // Load DB Models - WIKI.logger.info('Loading DB models...') - const models = (await import(path.join(WIKI.SERVERPATH, 'models/index.mjs'))).default - - // Connect - await this.connect() - - // Check DB Version - const resVersion = await this.knex.raw('SHOW server_version;') - const dbVersion = semver.coerce(resVersion.rows[0].server_version, { loose: true }) - this.VERSION = dbVersion.version - this.LEGACY = dbVersion.major < 16 - if (dbVersion.major < 12) { - WIKI.logger.error(`Your PostgreSQL database version (${dbVersion.major}) is too old and unsupported by Wiki.js. Requires >= 12. Exiting...`) - process.exit(1) - } - WIKI.logger.info(`PostgreSQL ${dbVersion.version} [ ${this.LEGACY ? 'LEGACY MODE' : 'OK'} ]`) - - // Run Migrations - if (!workerMode) { - await this.migrateFromLegacy() - await this.syncSchemas() - } - - return { - ...this, - ...models - } - }, - /** - * Subscribe to database LISTEN / NOTIFY for multi-instances events - */ - async subscribeToNotifications () { - let connSettings = this.knex.client.connectionSettings - if (typeof connSettings === 'string') { - const encodedName = encodeURIComponent(`Wiki.js - ${WIKI.INSTANCE_ID}:PSUB`) - if (connSettings.indexOf('?') > 0) { - connSettings = `${connSettings}&ApplicationName=${encodedName}` - } else { - connSettings = `${connSettings}?ApplicationName=${encodedName}` - } - } else { - connSettings.application_name = `Wiki.js - ${WIKI.INSTANCE_ID}:PSUB` - } - this.listener = new PGPubSub(connSettings, { - log (ev) { - WIKI.logger.debug(ev) - } - }) - - // -> Outbound events handling - - this.listener.addChannel('wiki', payload => { - if (has(payload, 'event') && payload.source !== WIKI.INSTANCE_ID) { - WIKI.logger.info(`Received event ${payload.event} from instance ${payload.source}: [ OK ]`) - WIKI.events.inbound.emit(payload.event, payload.value) - } - }) - WIKI.events.outbound.onAny(this.notifyViaDB) - - // -> Listen to inbound events - - WIKI.auth.subscribeToEvents() - WIKI.configSvc.subscribeToEvents() - WIKI.db.pages.subscribeToEvents() - - WIKI.logger.info('PG PubSub Listener initialized successfully: [ OK ]') - }, - /** - * Unsubscribe from database LISTEN / NOTIFY - */ - async unsubscribeToNotifications () { - if (this.listener) { - WIKI.events.outbound.offAny(this.notifyViaDB) - WIKI.events.inbound.removeAllListeners() - this.listener.close() - } - }, - /** - * Publish event via database NOTIFY - * - * @param {string} event Event fired - * @param {object} value Payload of the event - */ - notifyViaDB (event, value) { - WIKI.db.listener.publish('wiki', { - source: WIKI.INSTANCE_ID, - event, - value - }) - }, - /** - * Attempt initial connection - */ - async connect () { - try { - WIKI.logger.info('Connecting to database...') - await this.knex.raw('SELECT 1 + 1;') - WIKI.logger.info('Database Connection Successful [ OK ]') - } catch (err) { - if (this.connectAttempts < 10) { - if (err.code) { - WIKI.logger.error(`Database Connection Error: ${err.code} ${err.address}:${err.port}`) - } else { - WIKI.logger.error(`Database Connection Error: ${err.message}`) - } - WIKI.logger.warn(`Will retry in 3 seconds... [Attempt ${++this.connectAttempts} of 10]`) - await setTimeout(3000) - await this.connect() - } else { - throw err - } - } - }, - /** - * Migrate DB Schemas - */ - async syncSchemas () { - WIKI.logger.info('Ensuring DB schema exists...') - await this.knex.raw(`CREATE SCHEMA IF NOT EXISTS ${WIKI.config.db.schema}`) - WIKI.logger.info('Ensuring DB migrations have been applied...') - return this.knex.migrate.latest({ - tableName: 'migrations', - migrationSource, - schemaName: WIKI.config.db.schema - }) - }, - /** - * Migrate DB Schemas from 2.x - */ - async migrateFromLegacy () { - // return migrateFromLegacy.migrate(self.knex) - } -} diff --git a/server/core/extensions.mjs b/server/core/extensions.mjs deleted file mode 100644 index 32ff856ce..000000000 --- a/server/core/extensions.mjs +++ /dev/null @@ -1,19 +0,0 @@ -import fs from 'node:fs/promises' -import path from 'path' - -export default { - ext: {}, - async init () { - const extDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/extensions')) - WIKI.logger.info(`Checking for installed optional extensions...`) - for (const dir of extDirs) { - WIKI.extensions.ext[dir] = (await import(path.join(WIKI.SERVERPATH, 'modules/extensions', dir, 'ext.mjs'))).default - const isInstalled = await WIKI.extensions.ext[dir].check() - if (isInstalled) { - WIKI.logger.info(`Optional extension ${dir} is installed. [ OK ]`) - } else { - WIKI.logger.info(`Optional extension ${dir} was not found on this system. [ SKIPPED ]`) - } - } - } -} diff --git a/server/core/kernel.mjs b/server/core/kernel.mjs deleted file mode 100644 index eb0a1d7c0..000000000 --- a/server/core/kernel.mjs +++ /dev/null @@ -1,119 +0,0 @@ -import { padEnd } from 'lodash-es' -import eventemitter2 from 'eventemitter2' -import NodeCache from 'node-cache' - -import asar from './asar.mjs' -import db from './db.mjs' -import extensions from './extensions.mjs' -import scheduler from './scheduler.mjs' -import servers from './servers.mjs' -import metrics from './metrics.mjs' - -let isShuttingDown = false - -export default { - async init() { - WIKI.logger.info('=======================================') - WIKI.logger.info(`= Wiki.js ${padEnd(WIKI.version + ' ', 29, '=')}`) - WIKI.logger.info('=======================================') - WIKI.logger.info('Initializing...') - WIKI.logger.info(`Running node.js ${process.version}`) - - WIKI.db = await db.init() - - try { - await WIKI.configSvc.loadFromDb() - await WIKI.configSvc.applyFlags() - } catch (err) { - WIKI.logger.error('Database Initialization Error: ' + err.message) - if (WIKI.IS_DEBUG) { - WIKI.logger.error(err) - } - process.exit(1) - } - - this.bootWeb() - }, - /** - * Pre-Web Boot Sequence - */ - async preBootWeb() { - try { - WIKI.cache = new NodeCache({ checkperiod: 0 }) - WIKI.scheduler = await scheduler.init() - WIKI.servers = servers - WIKI.events = { - inbound: new eventemitter2.EventEmitter2(), - outbound: new eventemitter2.EventEmitter2() - } - WIKI.extensions = extensions - WIKI.asar = asar - WIKI.metrics = await metrics.init() - } catch (err) { - WIKI.logger.error(err) - process.exit(1) - } - }, - /** - * Boot Web Process - */ - async bootWeb() { - try { - await this.preBootWeb() - await (await import('../web.mjs')).init() - this.postBootWeb() - } catch (err) { - WIKI.logger.error(err) - process.exit(1) - } - }, - /** - * Post-Web Boot Sequence - */ - async postBootWeb() { - await WIKI.db.locales.refreshFromDisk() - - await WIKI.db.analytics.refreshProvidersFromDisk() - await WIKI.db.authentication.refreshStrategiesFromDisk() - await WIKI.db.commentProviders.refreshProvidersFromDisk() - await WIKI.db.renderers.refreshRenderersFromDisk() - await WIKI.db.storage.refreshTargetsFromDisk() - - await WIKI.extensions.init() - - await WIKI.auth.activateStrategies() - await WIKI.db.commentProviders.initProvider() - await WIKI.db.locales.reloadCache() - await WIKI.db.sites.reloadCache() - await WIKI.db.storage.initTargets() - - await WIKI.db.subscribeToNotifications() - await WIKI.scheduler.start() - }, - /** - * Graceful shutdown - */ - async shutdown (devMode = false) { - if (isShuttingDown) { return } - isShuttingDown = true - if (WIKI.servers) { - await WIKI.servers.stopServers() - } - if (WIKI.scheduler) { - await WIKI.scheduler.stop() - } - if (WIKI.models) { - await WIKI.db.unsubscribeToNotifications() - if (WIKI.db.knex) { - await WIKI.db.knex.destroy() - } - } - if (WIKI.asar) { - await WIKI.asar.unload() - } - if (!devMode) { - WIKI.logger.info('Terminating process...') - process.exit(0) - } - } -} diff --git a/server/core/letsencrypt.js b/server/core/letsencrypt.js deleted file mode 100644 index a28659cf9..000000000 --- a/server/core/letsencrypt.js +++ /dev/null @@ -1,122 +0,0 @@ -const ACME = require('acme') -const Keypairs = require('@root/keypairs') -const _ = require('lodash') -const moment = require('moment') -const CSR = require('@root/csr') -const PEM = require('@root/pem') -const punycode = require('punycode/') - -module.exports = { - apiDirectory: WIKI.dev ? 'https://acme-staging-v02.api.letsencrypt.org/directory' : 'https://acme-v02.api.letsencrypt.org/directory', - acme: null, - async init () { - if (!_.get(WIKI.config, 'letsencrypt.payload', false)) { - await this.requestCertificate() - } else if (WIKI.config.letsencrypt.domain !== WIKI.config.ssl.domain) { - WIKI.logger.info(`(LETSENCRYPT) Domain has changed. Requesting new certificates...`) - await this.requestCertificate() - } else if (moment(WIKI.config.letsencrypt.payload.expires).isSameOrBefore(moment().add(5, 'days'))) { - WIKI.logger.info(`(LETSENCRYPT) Certificate is about to or has expired, requesting a new one...`) - await this.requestCertificate() - } else { - WIKI.logger.info(`(LETSENCRYPT) Using existing certificate for ${WIKI.config.ssl.domain}, expires on ${WIKI.config.letsencrypt.payload.expires}: [ OK ]`) - } - WIKI.config.ssl.format = 'pem' - WIKI.config.ssl.inline = true - WIKI.config.ssl.key = WIKI.config.letsencrypt.serverKey - WIKI.config.ssl.cert = WIKI.config.letsencrypt.payload.cert + '\n' + WIKI.config.letsencrypt.payload.chain - WIKI.config.ssl.passphrase = null - WIKI.config.ssl.dhparam = null - }, - async requestCertificate () { - try { - WIKI.logger.info(`(LETSENCRYPT) Initializing Let's Encrypt client...`) - this.acme = ACME.create({ - maintainerEmail: WIKI.config.maintainerEmail, - packageAgent: `wikijs/${WIKI.version}`, - notify: (ev, msg) => { - if (_.includes(['warning', 'error'], ev)) { - WIKI.logger.warn(`${ev}: ${msg}`) - } else { - WIKI.logger.debug(`${ev}: ${JSON.stringify(msg)}`) - } - } - }) - - await this.acme.init(this.apiDirectory) - - // -> Create ACME Subscriber account - - if (!_.get(WIKI.config, 'letsencrypt.account', false)) { - WIKI.logger.info(`(LETSENCRYPT) Setting up account for the first time...`) - const accountKeypair = await Keypairs.generate({ kty: 'EC', format: 'jwk' }) - const account = await this.acme.accounts.create({ - subscriberEmail: WIKI.config.ssl.subscriberEmail, - agreeToTerms: true, - accountKey: accountKeypair.private - }) - WIKI.config.letsencrypt = { - accountKeypair: accountKeypair, - account: account, - domain: WIKI.config.ssl.domain - } - await WIKI.configSvc.saveToDb(['letsencrypt']) - WIKI.logger.info(`(LETSENCRYPT) Account was setup successfully [ OK ]`) - } - - // -> Create Server Keypair - - if (!WIKI.config.letsencrypt.serverKey) { - WIKI.logger.info(`(LETSENCRYPT) Generating server keypairs...`) - const serverKeypair = await Keypairs.generate({ kty: 'RSA', format: 'jwk' }) - WIKI.config.letsencrypt.serverKey = await Keypairs.export({ jwk: serverKeypair.private }) - WIKI.logger.info(`(LETSENCRYPT) Server keypairs generated successfully [ OK ]`) - } - - // -> Create CSR - - WIKI.logger.info(`(LETSENCRYPT) Generating certificate signing request (CSR)...`) - const domains = [ punycode.toASCII(WIKI.config.ssl.domain) ] - const serverKey = await Keypairs.import({ pem: WIKI.config.letsencrypt.serverKey }) - const csrDer = await CSR.csr({ jwk: serverKey, domains, encoding: 'der' }) - const csr = PEM.packBlock({ type: 'CERTIFICATE REQUEST', bytes: csrDer }) - WIKI.logger.info(`(LETSENCRYPT) CSR generated successfully [ OK ]`) - - // -> Verify Domain + Get Certificate - - WIKI.logger.info(`(LETSENCRYPT) Requesting certificate from Let's Encrypt...`) - const certResp = await this.acme.certificates.create({ - account: WIKI.config.letsencrypt.account, - accountKey: WIKI.config.letsencrypt.accountKeypair.private, - csr, - domains, - challenges: { - 'http-01': { - init () {}, - set (data) { - WIKI.logger.info(`(LETSENCRYPT) Setting HTTP challenge for ${data.challenge.hostname}: [ READY ]`) - WIKI.config.letsencrypt.challenge = data.challenge - WIKI.logger.info(`(LETSENCRYPT) Waiting for challenge to complete...`) - return null // <- this is needed, cannot be undefined - }, - get (data) { - return WIKI.config.letsencrypt.challenge - }, - async remove (data) { - WIKI.logger.info(`(LETSENCRYPT) Removing HTTP challenge: [ OK ]`) - WIKI.config.letsencrypt.challenge = null - return null // <- this is needed, cannot be undefined - } - } - } - }) - WIKI.logger.info(`(LETSENCRYPT) New certifiate received successfully: [ COMPLETED ]`) - WIKI.config.letsencrypt.payload = certResp - WIKI.config.letsencrypt.domain = WIKI.config.ssl.domain - await WIKI.configSvc.saveToDb(['letsencrypt']) - } catch (err) { - WIKI.logger.warn(`(LETSENCRYPT) ${err}`) - throw err - } - } -} diff --git a/server/core/logger.mjs b/server/core/logger.mjs deleted file mode 100644 index 0b4766b48..000000000 --- a/server/core/logger.mjs +++ /dev/null @@ -1,61 +0,0 @@ -import chalk from 'chalk' -import EventEmitter from 'node:events' - -const LEVELS = ['error', 'warn', 'info', 'debug'] -const LEVELSIGNORED = ['verbose', 'silly'] -const LEVELCOLORS = { - error: 'red', - warn: 'yellow', - info: 'green', - debug: 'cyan' -} - -class Logger extends EventEmitter {} - -export default { - loggers: {}, - init () { - const primaryLogger = new Logger() - - let ignoreNextLevels = false - - primaryLogger.ws = new EventEmitter() - - LEVELS.forEach(lvl => { - primaryLogger[lvl] = (...args) => { - primaryLogger.emit(lvl, ...args) - } - - if (!ignoreNextLevels) { - primaryLogger.on(lvl, (msg) => { - let formatted = '' - if (WIKI.config.logFormat === 'json') { - formatted = JSON.stringify({ - timestamp: new Date().toISOString(), - instance: WIKI.INSTANCE_ID, - level: lvl, - message: msg - }) - } else { - if (msg instanceof Error) { - msg = msg.stack - } - formatted = `${new Date().toISOString()} ${chalk.dim('[' + WIKI.INSTANCE_ID + ']')} ${chalk[LEVELCOLORS[lvl]].bold(lvl)}: ${msg}` - } - - console.log(formatted) - primaryLogger.ws.emit('log', formatted) - }) - } - if (lvl === WIKI.config.logLevel) { - ignoreNextLevels = true - } - }) - - LEVELSIGNORED.forEach(lvl => { - primaryLogger[lvl] = () => {} - }) - - return primaryLogger - } -} diff --git a/server/core/mail.mjs b/server/core/mail.mjs deleted file mode 100644 index 1afb10a24..000000000 --- a/server/core/mail.mjs +++ /dev/null @@ -1,79 +0,0 @@ -import nodemailer from 'nodemailer' -import { get } from 'lodash-es' -import path from 'node:path' -import { config } from '@vue-email/compiler' - -export default { - vueEmail: null, - transport: null, - templates: {}, - init() { - if (get(WIKI.config, 'mail.host', '').length > 2) { - let conf = { - host: WIKI.config.mail.host, - port: WIKI.config.mail.port, - name: WIKI.config.mail.name, - secure: WIKI.config.mail.secure, - tls: { - rejectUnauthorized: !(WIKI.config.mail.verifySSL === false) - } - } - if (get(WIKI.config, 'mail.user', '').length > 1) { - conf = { - ...conf, - auth: { - user: WIKI.config.mail.user, - pass: WIKI.config.mail.pass - } - } - } - if (get(WIKI.config, 'mail.useDKIM', false)) { - conf = { - ...conf, - dkim: { - domainName: WIKI.config.mail.dkimDomainName, - keySelector: WIKI.config.mail.dkimKeySelector, - privateKey: WIKI.config.mail.dkimPrivateKey - } - } - } - this.transport = nodemailer.createTransport(conf) - this.vueEmail = config(path.join(WIKI.SERVERPATH, 'templates/mail'), { - verbose: false, - options: { - baseUrl: WIKI.config.mail.defaultBaseURL - } - }) - } else { - WIKI.logger.warn('Mail is not setup! Please set the configuration in the administration area!') - this.transport = null - } - return this - }, - async send(opts) { - if (!this.transport) { - WIKI.logger.warn('Cannot send email because mail is not setup in the administration area!') - throw new Error('ERR_MAIL_NOT_CONFIGURED') - } - return this.transport.sendMail({ - headers: { - 'x-mailer': 'Wiki.js' - }, - from: `"${WIKI.config.mail.senderName}" <${WIKI.config.mail.senderEmail}>`, - to: opts.to, - subject: opts.subject, - text: opts.text, - html: await this.loadTemplate(opts.template, opts.data) - }) - }, - async loadTemplate(key, opts = {}) { - try { - return this.vueEmail.render(`${key}.vue`, { - props: opts - }) - } catch (err) { - WIKI.logger.warn(err) - throw new Error('ERR_MAIL_RENDER_FAILED') - } - } -} diff --git a/server/core/metrics.mjs b/server/core/metrics.mjs deleted file mode 100644 index 9ffa25df7..000000000 --- a/server/core/metrics.mjs +++ /dev/null @@ -1,66 +0,0 @@ -import { collectDefaultMetrics, register, Gauge } from 'prom-client' -import { toSafeInteger } from 'lodash-es' - -export default { - customMetrics: {}, - async init () { - if (WIKI.config.metrics.isEnabled) { - WIKI.logger.info('Initializing metrics...') - - register.setDefaultLabels({ - WIKI_INSTANCE: WIKI.INSTANCE_ID - }) - - collectDefaultMetrics() - - this.customMetrics.groupsTotal = new Gauge({ - name: 'wiki_groups_total', - help: 'Total number of groups', - async collect() { - const total = await WIKI.db.groups.query().count('* as total').first() - this.set(toSafeInteger(total.total)) - } - }) - - this.customMetrics.pagesTotal = new Gauge({ - name: 'wiki_pages_total', - help: 'Total number of pages', - async collect() { - const total = await WIKI.db.pages.query().count('* as total').first() - this.set(toSafeInteger(total.total)) - } - }) - - this.customMetrics.tagsTotal = new Gauge({ - name: 'wiki_tags_total', - help: 'Total number of tags', - async collect() { - const total = await WIKI.db.tags.query().count('* as total').first() - this.set(toSafeInteger(total.total)) - } - }) - - this.customMetrics.usersTotal = new Gauge({ - name: 'wiki_users_total', - help: 'Total number of users', - async collect() { - const total = await WIKI.db.users.query().count('* as total').first() - this.set(toSafeInteger(total.total)) - } - }) - WIKI.logger.info('Metrics ready [ OK ]') - } else { - this.customMetrics = {} - register.clear() - } - return this - }, - async render (res) { - try { - res.contentType(register.contentType) - res.send(await register.metrics()) - } catch (err) { - res.status(500).end(err.message) - } - } -} diff --git a/server/core/scheduler.mjs b/server/core/scheduler.mjs deleted file mode 100644 index 269cb5d91..000000000 --- a/server/core/scheduler.mjs +++ /dev/null @@ -1,309 +0,0 @@ -import { DynamicThreadPool } from 'poolifier' -import os from 'node:os' -import fs from 'node:fs/promises' -import path from 'node:path' -import { CronExpressionParser } from 'cron-parser' -import { DateTime } from 'luxon' -import { v4 as uuid } from 'uuid' -import { createDeferred } from '../helpers/common.mjs' -import { camelCase, find, remove } from 'lodash-es' - -export default { - workerPool: null, - maxWorkers: 1, - activeWorkers: 0, - pollingRef: null, - scheduledRef: null, - tasks: null, - completionPromises: [], - async init () { - this.maxWorkers = WIKI.config.scheduler.workers === 'auto' ? (os.cpus().length - 1) : WIKI.config.scheduler.workers - if (this.maxWorkers < 1) { this.maxWorkers = 1 } - WIKI.logger.info(`Initializing Worker Pool (Limit: ${this.maxWorkers})...`) - this.workerPool = new DynamicThreadPool(1, this.maxWorkers, path.join(WIKI.SERVERPATH, 'worker.mjs'), { - errorHandler: (err) => WIKI.logger.warn(err), - exitHandler: () => WIKI.logger.debug('A worker has gone offline.'), - onlineHandler: () => WIKI.logger.debug('New worker is online.') - }) - this.tasks = {} - for (const f of (await fs.readdir(path.join(WIKI.SERVERPATH, 'tasks/simple')))) { - const taskName = camelCase(f.replace('.mjs', '')) - this.tasks[taskName] = (await import(path.join(WIKI.SERVERPATH, 'tasks/simple', f))).task - } - return this - }, - async start () { - WIKI.logger.info('Starting Scheduler...') - - // -> Add PostgreSQL Sub Channel - WIKI.db.listener.addChannel('scheduler', async payload => { - switch (payload.event) { - case 'newJob': { - if (this.activeWorkers < this.maxWorkers) { - this.activeWorkers++ - await this.processJob() - this.activeWorkers-- - } - break - } - case 'jobCompleted': { - const jobPromise = find(this.completionPromises, ['id', payload.id]) - if (jobPromise) { - if (payload.state === 'success') { - jobPromise.resolve() - } else { - jobPromise.reject(new Error(payload.errorMessage)) - } - setTimeout(() => { - remove(this.completionPromises, ['id', payload.id]) - }) - } - break - } - } - }) - - // -> Start scheduled jobs check - this.scheduledRef = setInterval(async () => { - this.addScheduled() - }, WIKI.config.scheduler.scheduledCheck * 1000) - - // -> Add scheduled jobs on init - await this.addScheduled() - - // -> Start job polling - this.pollingRef = setInterval(async () => { - this.processJob() - }, WIKI.config.scheduler.pollingCheck * 1000) - - WIKI.logger.info('Scheduler: [ STARTED ]') - }, - /** - * Add a job to the scheduler - * @param {Object} opts - Job options - * @param {string} opts.task - The task name to execute. - * @param {Object} [opts.payload={}] - An optional data object to pass to the job. - * @param {Date} [opts.waitUntil] - An optional datetime after which the task is allowed to run. - * @param {Number} [opts.maxRetries] - The number of times this job can be restarted upon failure. Uses server defaults if not provided. - * @param {Boolean} [opts.isScheduled=false] - Whether this is a scheduled job. - * @param {Boolean} [opts.notify=true] - Whether to notify all instances that a new job is available. - * @param {Boolean} [opts.promise=false] - Whether to return a promise property that resolves when the job completes. - * @returns {Promise} - */ - async addJob ({ task, payload = {}, waitUntil, maxRetries, isScheduled = false, notify = true, promise = false }) { - try { - const jobId = uuid() - const jobDefer = createDeferred() - if (promise) { - this.completionPromises.push({ - id: jobId, - added: DateTime.utc(), - resolve: jobDefer.resolve, - reject: jobDefer.reject - }) - } - await WIKI.db.knex('jobs') - .insert({ - id: jobId, - task, - useWorker: !(typeof this.tasks[task] === 'function'), - payload, - maxRetries: maxRetries ?? WIKI.config.scheduler.maxRetries, - isScheduled, - waitUntil, - createdBy: WIKI.INSTANCE_ID - }) - if (notify) { - WIKI.db.listener.publish('scheduler', { - source: WIKI.INSTANCE_ID, - event: 'newJob', - id: jobId - }) - } - return { - id: jobId, - ...promise && { promise: jobDefer.promise } - } - } catch (err) { - WIKI.logger.warn(`Failed to add job to scheduler: ${err.message}`) - } - }, - async processJob () { - const jobIds = [] - try { - const availableWorkers = this.maxWorkers - this.activeWorkers - if (availableWorkers < 1) { - WIKI.logger.debug('All workers are busy. Cannot process more jobs at the moment.') - return - } - - await WIKI.db.knex.transaction(async trx => { - const jobs = await trx('jobs') - .whereIn('id', WIKI.db.knex.raw(`(SELECT id FROM jobs WHERE ("waitUntil" IS NULL OR "waitUntil" <= NOW()) ORDER BY id FOR UPDATE SKIP LOCKED LIMIT ${availableWorkers})`)) - .returning('*') - .del() - if (jobs && jobs.length > 0) { - for (const job of jobs) { - WIKI.logger.info(`Processing new job ${job.id}: ${job.task}...`) - // -> Add to Job History - await WIKI.db.knex('jobHistory').insert({ - id: job.id, - task: job.task, - state: 'active', - useWorker: job.useWorker, - wasScheduled: job.isScheduled, - payload: job.payload, - attempt: job.retries + 1, - maxRetries: job.maxRetries, - executedBy: WIKI.INSTANCE_ID, - createdAt: job.createdAt - }).onConflict('id').merge({ - executedBy: WIKI.INSTANCE_ID, - startedAt: new Date() - }) - jobIds.push(job.id) - - // -> Start working on it - try { - if (job.useWorker) { - await this.workerPool.execute({ - ...job, - INSTANCE_ID: `${WIKI.INSTANCE_ID}:WKR` - }) - } else { - await this.tasks[job.task](job.payload) - } - // -> Update job history (success) - await WIKI.db.knex('jobHistory').where({ - id: job.id - }).update({ - state: 'completed', - completedAt: new Date() - }) - WIKI.logger.info(`Completed job ${job.id}: ${job.task}`) - WIKI.db.listener.publish('scheduler', { - source: WIKI.INSTANCE_ID, - event: 'jobCompleted', - state: 'success', - id: job.id - }) - } catch (err) { - WIKI.logger.warn(`Failed to complete job ${job.id}: ${job.task} [ FAILED ]`) - WIKI.logger.warn(err) - // -> Update job history (fail) - await WIKI.db.knex('jobHistory').where({ - id: job.id - }).update({ - attempt: job.retries + 1, - state: 'failed', - lastErrorMessage: err.message - }) - WIKI.db.listener.publish('scheduler', { - source: WIKI.INSTANCE_ID, - event: 'jobCompleted', - state: 'failed', - id: job.id, - errorMessage: err.message - }) - // -> Reschedule for retry - if (job.retries < job.maxRetries) { - const backoffDelay = (2 ** job.retries) * WIKI.config.scheduler.retryBackoff - await trx('jobs').insert({ - ...job, - retries: job.retries + 1, - waitUntil: DateTime.utc().plus({ seconds: backoffDelay }).toJSDate(), - updatedAt: new Date() - }) - WIKI.logger.warn(`Rescheduling new attempt for job ${job.id}: ${job.task}...`) - } - } - } - } - }) - } catch (err) { - WIKI.logger.warn(err) - if (jobIds && jobIds.length > 0) { - WIKI.db.knex('jobHistory').whereIn('id', jobIds).update({ - state: 'interrupted', - lastErrorMessage: err.message - }) - } - } - }, - async addScheduled () { - try { - await WIKI.db.knex.transaction(async trx => { - // -> Acquire lock - const jobLock = await trx('jobLock') - .where( - 'key', - WIKI.db.knex('jobLock') - .select('key') - .where('key', 'cron') - .andWhere('lastCheckedAt', '<=', DateTime.utc().minus({ minutes: 5 }).toISO()) - .forUpdate() - .skipLocked() - .limit(1) - ).update({ - lastCheckedBy: WIKI.INSTANCE_ID, - lastCheckedAt: DateTime.utc().toISO() - }) - if (jobLock > 0) { - WIKI.logger.info('Scheduling future planned jobs...') - const scheduledJobs = await WIKI.db.knex('jobSchedule') - if (scheduledJobs?.length > 0) { - // -> Get existing scheduled jobs - const existingJobs = await WIKI.db.knex('jobs').where('isScheduled', true) - let totalAdded = 0 - for (const job of scheduledJobs) { - // -> Get next planned iterations - const plannedIterations = CronExpressionParser.parse(job.cron, { - startDate: DateTime.utc().toJSDate(), - endDate: DateTime.utc().plus({ days: 1, minutes: 5 }).toJSDate(), - tz: 'UTC' - }) - // -> Add a maximum of 10 future iterations for a single task - let addedFutureJobs = 0 - while (true) { - try { - const next = plannedIterations.next() - // -> Ensure this iteration isn't already scheduled - if (!existingJobs.some(j => j.task === job.task && j.waitUntil.getTime() === next.value.getTime())) { - this.addJob({ - task: job.task, - useWorker: !(typeof this.tasks[job.task] === 'function'), - payload: job.payload, - isScheduled: true, - waitUntil: next.value.toISOString(), - notify: false - }) - addedFutureJobs++ - totalAdded++ - } - // -> No more iterations for this period or max iterations count reached - if (next.done || addedFutureJobs >= 10) { break } - } catch (err) { - break - } - } - } - if (totalAdded > 0) { - WIKI.logger.info(`Scheduled ${totalAdded} new future planned jobs: [ OK ]`) - } else { - WIKI.logger.info('No new future planned jobs to schedule: [ OK ]') - } - } - } - }) - } catch (err) { - WIKI.logger.warn(err) - } - }, - async stop () { - WIKI.logger.info('Stopping Scheduler...') - clearInterval(this.scheduledRef) - clearInterval(this.pollingRef) - await this.workerPool.destroy() - WIKI.logger.info('Scheduler: [ STOPPED ]') - } -} diff --git a/server/core/servers.mjs b/server/core/servers.mjs deleted file mode 100644 index 2848b3e8e..000000000 --- a/server/core/servers.mjs +++ /dev/null @@ -1,239 +0,0 @@ -import fs from 'node:fs/promises' -import http from 'node:http' -import https from 'node:https' -import { ApolloServer } from '@apollo/server' -import { expressMiddleware } from '@as-integrations/express5' -import { isEmpty } from 'lodash-es' -import { Server as IoServer } from 'socket.io' -import { ApolloServerPluginLandingPageLocalDefault, ApolloServerPluginLandingPageProductionDefault } from '@apollo/server/plugin/landingPage/default' -import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs' - -import { initSchema } from '../graph/index.mjs' - -export default { - graph: null, - http: null, - https: null, - ws: null, - connections: new Map(), - le: null, - /** - * Initialize HTTP Server - */ - async initHTTP () { - WIKI.logger.info(`HTTP Server on port: [ ${WIKI.config.port} ]`) - this.http = http.createServer(WIKI.app) - - this.http.on('error', (error) => { - if (error.syscall !== 'listen') { - throw error - } - - switch (error.code) { - case 'EACCES': - WIKI.logger.error('Listening on port ' + WIKI.config.port + ' requires elevated privileges!') - return process.exit(1) - case 'EADDRINUSE': - WIKI.logger.error('Port ' + WIKI.config.port + ' is already in use!') - return process.exit(1) - default: - throw error - } - }) - - this.http.on('listening', () => { - WIKI.logger.info('HTTP Server: [ RUNNING ]') - }) - - this.http.on('connection', conn => { - const connKey = `http:${conn.remoteAddress}:${conn.remotePort}` - this.connections.set(connKey, conn) - conn.on('close', () => { - this.connections.delete(connKey) - }) - }) - }, - /** - * Start HTTP Server - */ - async startHTTP () { - this.http.listen(WIKI.config.port, WIKI.config.bindIP) - }, - /** - * Initialize HTTPS Server - */ - async initHTTPS () { - if (WIKI.config.ssl.provider === 'letsencrypt') { - this.le = require('./letsencrypt') - await this.le.init() - } - - WIKI.logger.info(`HTTPS Server on port: [ ${WIKI.config.ssl.port} ]`) - const tlsOpts = {} - try { - if (WIKI.config.ssl.format === 'pem') { - tlsOpts.key = WIKI.config.ssl.inline ? WIKI.config.ssl.key : await fs.readFile(WIKI.config.ssl.key, 'utf-8') - tlsOpts.cert = WIKI.config.ssl.inline ? WIKI.config.ssl.cert : await fs.readFile(WIKI.config.ssl.cert, 'utf-8') - } else { - tlsOpts.pfx = WIKI.config.ssl.inline ? WIKI.config.ssl.pfx : await fs.readFile(WIKI.config.ssl.pfx, 'utf-8') - } - if (!isEmpty(WIKI.config.ssl.passphrase)) { - tlsOpts.passphrase = WIKI.config.ssl.passphrase - } - if (!isEmpty(WIKI.config.ssl.dhparam)) { - tlsOpts.dhparam = WIKI.config.ssl.dhparam - } - } catch (err) { - WIKI.logger.error('Failed to setup HTTPS server parameters:') - WIKI.logger.error(err) - return process.exit(1) - } - this.https = https.createServer(tlsOpts, WIKI.app) - - this.https.listen(WIKI.config.ssl.port, WIKI.config.bindIP) - this.https.on('error', (error) => { - if (error.syscall !== 'listen') { - throw error - } - - switch (error.code) { - case 'EACCES': - WIKI.logger.error('Listening on port ' + WIKI.config.ssl.port + ' requires elevated privileges!') - return process.exit(1) - case 'EADDRINUSE': - WIKI.logger.error('Port ' + WIKI.config.ssl.port + ' is already in use!') - return process.exit(1) - default: - throw error - } - }) - - this.https.on('listening', () => { - WIKI.logger.info('HTTPS Server: [ RUNNING ]') - }) - - this.https.on('connection', conn => { - const connKey = `https:${conn.remoteAddress}:${conn.remotePort}` - this.connections.set(connKey, conn) - conn.on('close', () => { - this.connections.delete(connKey) - }) - }) - }, - /** - * Start HTTPS Server - */ - async startHTTPS () { - this.https.listen(WIKI.config.ssl.port, WIKI.config.bindIP) - }, - /** - * Start GraphQL Server - */ - async startGraphQL () { - const graphqlSchema = await initSchema() - this.graph = new ApolloServer({ - schema: graphqlSchema, - allowBatchedHttpRequests: true, - csrfPrevention: true, - cache: 'bounded', - plugins: [ - process.env.NODE_ENV === 'production' - ? ApolloServerPluginLandingPageProductionDefault({ - footer: false - }) - : ApolloServerPluginLandingPageLocalDefault({ - footer: false, - embed: { - endpointIsEditable: false, - runTelemetry: false - } - }) - // ApolloServerPluginDrainHttpServer({ httpServer: this.http }) - // ...(this.https && ApolloServerPluginDrainHttpServer({ httpServer: this.https })) - ] - }) - await this.graph.start() - WIKI.app.use(graphqlUploadExpress({ - maxFileSize: WIKI.config.security.uploadMaxFileSize, - maxFiles: WIKI.config.security.uploadMaxFiles - })) - WIKI.app.use('/_graphql', expressMiddleware(this.graph, { - context: ({ req, res }) => ({ req, res }) - })) - }, - /** - * Start Socket.io WebSocket Server - */ - async initWebSocket () { - if (this.https) { - this.ws = new IoServer(this.https, { - path: '/_ws/', - serveClient: false - }) - WIKI.logger.info('WebSocket Server attached to HTTPS Server [ OK ]') - } else { - this.ws = new IoServer(this.http, { - path: '/_ws/', - serveClient: false, - cors: true // TODO: dev only, replace with app settings once stable - }) - WIKI.logger.info('WebSocket Server attached to HTTP Server [ OK ]') - } - }, - /** - * Close all active connections - */ - closeConnections (mode = 'all') { - for (const [key, conn] of this.connections) { - if (mode !== 'all' && key.indexOf(`${mode}:`) !== 0) { - continue - } - conn.destroy() - this.connections.delete(key) - } - if (mode === 'all') { - this.connections.clear() - } - }, - /** - * Stop all servers - */ - async stopServers () { - this.closeConnections() - if (this.http) { - await new Promise(resolve => this.http.close(resolve)) - this.http = null - } - if (this.https) { - await new Promise(resolve => this.https.close(resolve)) - this.https = null - } - this.graph = null - }, - /** - * Restart Server - */ - async restartServer (srv = 'https') { - this.closeConnections(srv) - switch (srv) { - case 'http': - if (this.http) { - await new Promise(resolve => this.http.close(resolve)) - this.http = null - } - this.initHTTP() - this.startHTTP() - break - case 'https': - if (this.https) { - await new Promise(resolve => this.https.close(resolve)) - this.https = null - } - this.initHTTPS() - this.startHTTPS() - break - default: - throw new Error('Cannot restart server: Invalid designation') - } - } -} diff --git a/server/core/sideloader.js b/server/core/sideloader.js deleted file mode 100644 index 7ee746579..000000000 --- a/server/core/sideloader.js +++ /dev/null @@ -1,74 +0,0 @@ -const fs = require('fs-extra') -const path = require('path') -const _ = require('lodash') - -module.exports = { - async init () { - if (!WIKI.config.offline) { - return - } - - const sideloadExists = await fs.pathExists(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'sideload')) - - if (!sideloadExists) { - return - } - - WIKI.logger.info('Sideload directory detected. Looking for packages...') - - try { - await this.importLocales() - } catch (err) { - WIKI.logger.warn(err) - } - }, - async importLocales() { - const localeExists = await fs.pathExists(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'sideload/locales.json')) - if (localeExists) { - WIKI.logger.info('Found locales master file. Importing locale packages...') - let importedLocales = 0 - - const locales = await fs.readJson(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'sideload/locales.json')) - if (locales && _.has(locales, 'data.localization.locales')) { - for (const locale of locales.data.localization.locales) { - try { - const localeData = await fs.readJson(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `sideload/${locale.code}.json`)) - if (localeData) { - WIKI.logger.info(`Importing ${locale.name} locale package...`) - - let lcObj = {} - _.forOwn(localeData, (value, key) => { - if (_.includes(key, '::')) { return } - if (_.isEmpty(value)) { value = key } - _.set(lcObj, key.replace(':', '.'), value) - }) - - const localeDbExists = await WIKI.db.locales.query().select('code').where('code', locale.code).first() - if (localeDbExists) { - await WIKI.db.locales.query().update({ - code: locale.code, - strings: lcObj, - isRTL: locale.isRTL, - name: locale.name, - nativeName: locale.nativeName - }).where('code', locale.code) - } else { - await WIKI.db.locales.query().insert({ - code: locale.code, - strings: lcObj, - isRTL: locale.isRTL, - name: locale.name, - nativeName: locale.nativeName - }) - } - importedLocales++ - } - } catch (err) { - // skip - } - } - WIKI.logger.info(`Imported ${importedLocales} locale packages: [COMPLETED]`) - } - } - } -} diff --git a/server/core/system.mjs b/server/core/system.mjs deleted file mode 100644 index b639b579c..000000000 --- a/server/core/system.mjs +++ /dev/null @@ -1,21 +0,0 @@ -import fse from 'fs-extra' -import path from 'node:path' - -export default { - updates: { - channel: 'BETA', - version: WIKI.version, - releaseDate: WIKI.releaseDate, - minimumVersionRequired: '3.0.0-beta.0', - minimumNodeRequired: '18.0.0' - }, - init () { - fse.ensureDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'assets')) - fse.ensureDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'uploads')) - - // Clear content cache - fse.emptyDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'cache')) - - return this - } -} diff --git a/server/db/legacy/index.js b/server/db/legacy/index.js deleted file mode 100644 index a475d10f7..000000000 --- a/server/db/legacy/index.js +++ /dev/null @@ -1,33 +0,0 @@ -const _ = require('lodash') - -module.exports = { - async migrate (knex) { - const migrationsTableExists = await knex.schema.hasTable('migrations') - if (!migrationsTableExists) { - return - } - - const migrations = await knex('migrations') - if (_.some(migrations, m => m.name.indexOf('2.0.0') === 0)) { - WIKI.logger.info('Found legacy 2.x installation of Wiki.js...') - if (_.some(migrations, m => m.name.indexOf('2.5.128') === 0)) { - // TODO: 2.x MIGRATIONS for 3.0 - WIKI.logger.error('Upgrading from 2.x is not yet supported. A future release will allow for upgrade from 2.x. Exiting...') - process.exit(1) - - // -> Cleanup migration table - await knex('migrations').truncate() - - // -> Advance to stable 3.0 migration state - await knex('migrations').insert({ - name: '3.0.0.js', - batch: 1, - migration_time: knex.fn.now() - }) - } else { - console.error('CANNOT UPGRADE FROM OLDER UNSUPPORTED VERSION. UPGRADE TO THE LATEST 2.X VERSION FIRST! Exiting...') - process.exit(1) - } - } - } -} diff --git a/server/db/migrations/3.0.0.mjs b/server/db/migrations/3.0.0.mjs deleted file mode 100644 index f5184e833..000000000 --- a/server/db/migrations/3.0.0.mjs +++ /dev/null @@ -1,930 +0,0 @@ -import { v4 as uuid } from 'uuid' -import bcrypt from 'bcryptjs' -import crypto from 'node:crypto' -import { DateTime } from 'luxon' -import { pem2jwk } from 'pem-jwk' - -export async function up (knex) { - WIKI.logger.info('Running 3.0.0 database migration...') - - // ===================================== - // PG EXTENSIONS - // ===================================== - await knex.raw('CREATE EXTENSION IF NOT EXISTS ltree;') - await knex.raw('CREATE EXTENSION IF NOT EXISTS pgcrypto;') - await knex.raw('CREATE EXTENSION IF NOT EXISTS pg_trgm;') - - await knex.schema - // ===================================== - // MODEL TABLES - // ===================================== - // ACTIVITY LOGS ----------------------- - .createTable('activityLogs', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.timestamp('ts').notNullable().defaultTo(knex.fn.now()) - table.string('action').notNullable() - table.jsonb('meta').notNullable() - }) - // ANALYTICS --------------------------- - .createTable('analytics', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('module').notNullable() - table.boolean('isEnabled').notNullable().defaultTo(false) - table.jsonb('config').notNullable() - }) - // API KEYS ---------------------------- - .createTable('apiKeys', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('name').notNullable() - table.text('key').notNullable() - table.timestamp('expiration').notNullable().defaultTo(knex.fn.now()) - table.boolean('isRevoked').notNullable().defaultTo(false) - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // ASSETS ------------------------------ - .createTable('assets', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('fileName').notNullable() - table.string('fileExt').notNullable() - table.boolean('isSystem').notNullable().defaultTo(false) - table.enum('kind', ['document', 'image', 'other']).notNullable().defaultTo('other') - table.string('mimeType').notNullable().defaultTo('application/octet-stream') - table.integer('fileSize').unsigned().comment('In bytes') - table.jsonb('meta').notNullable().defaultTo('{}') - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - table.binary('data') - table.binary('preview') - table.enum('previewState', ['none', 'pending', 'ready', 'failed']).notNullable().defaultTo('none') - table.jsonb('storageInfo') - }) - // AUTHENTICATION ---------------------- - .createTable('authentication', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('module').notNullable() - table.boolean('isEnabled').notNullable().defaultTo(false) - table.string('displayName').notNullable().defaultTo('') - table.jsonb('config').notNullable().defaultTo('{}') - table.boolean('registration').notNullable().defaultTo(false) - table.string('allowedEmailRegex').notNullable().defaultTo('') - table.specificType('autoEnrollGroups', 'uuid[]') - }) - .createTable('blocks', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('block').notNullable() - table.string('name').notNullable() - table.string('description').notNullable() - table.string('icon') - table.boolean('isEnabled').notNullable().defaultTo(false) - table.boolean('isCustom').notNullable().defaultTo(false) - table.json('config').notNullable() - }) - // COMMENT PROVIDERS ------------------- - .createTable('commentProviders', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('module').notNullable() - table.boolean('isEnabled').notNullable().defaultTo(false) - table.json('config').notNullable() - }) - // COMMENTS ---------------------------- - .createTable('comments', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.uuid('replyTo') - table.text('content').notNullable() - table.text('render').notNullable().defaultTo('') - table.string('name').notNullable().defaultTo('') - table.string('email').notNullable().defaultTo('') - table.string('ip').notNullable().defaultTo('') - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // GROUPS ------------------------------ - .createTable('groups', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('name').notNullable() - table.jsonb('permissions').notNullable() - table.jsonb('rules').notNullable() - table.string('redirectOnLogin').notNullable().defaultTo('') - table.string('redirectOnFirstLogin').notNullable().defaultTo('') - table.string('redirectOnLogout').notNullable().defaultTo('') - table.boolean('isSystem').notNullable().defaultTo(false) - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // HOOKS ------------------------------- - .createTable('hooks', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('name').notNullable() - table.jsonb('events').notNullable().defaultTo('[]') - table.string('url').notNullable() - table.boolean('includeMetadata').notNullable().defaultTo(false) - table.boolean('includeContent').notNullable().defaultTo(false) - table.boolean('acceptUntrusted').notNullable().defaultTo(false) - table.string('authHeader') - table.enum('state', ['pending', 'error', 'success']).notNullable().defaultTo('pending') - table.string('lastErrorMessage') - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // JOB HISTORY ------------------------- - .createTable('jobHistory', table => { - table.uuid('id').notNullable().primary() - table.string('task').notNullable() - table.enum('state', ['active', 'completed', 'failed', 'interrupted']).notNullable() - table.boolean('useWorker').notNullable().defaultTo(false) - table.boolean('wasScheduled').notNullable().defaultTo(false) - table.jsonb('payload') - table.integer('attempt').notNullable().defaultTo(1) - table.integer('maxRetries').notNullable().defaultTo(0) - table.text('lastErrorMessage') - table.string('executedBy') - table.timestamp('createdAt').notNullable() - table.timestamp('startedAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('completedAt') - }) - // JOB SCHEDULE ------------------------ - .createTable('jobSchedule', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('task').notNullable() - table.string('cron').notNullable() - table.string('type').notNullable().defaultTo('system') - table.jsonb('payload') - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // JOB SCHEDULE ------------------------ - .createTable('jobLock', table => { - table.string('key').notNullable().primary() - table.string('lastCheckedBy') - table.timestamp('lastCheckedAt').notNullable().defaultTo(knex.fn.now()) - }) - // JOBS -------------------------------- - .createTable('jobs', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('task').notNullable() - table.boolean('useWorker').notNullable().defaultTo(false) - table.jsonb('payload') - table.integer('retries').notNullable().defaultTo(0) - table.integer('maxRetries').notNullable().defaultTo(0) - table.timestamp('waitUntil') - table.boolean('isScheduled').notNullable().defaultTo(false) - table.string('createdBy') - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // LOCALES ----------------------------- - .createTable('locales', table => { - table.string('code', 10).notNullable().primary() - table.string('name').notNullable() - table.string('nativeName').notNullable() - table.string('language', 2).notNullable().index() - table.string('region', 2) - table.string('script', 4) - table.boolean('isRTL').notNullable().defaultTo(false) - table.jsonb('strings') - table.integer('completeness').notNullable().defaultTo(0) - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // NAVIGATION ---------------------------- - .createTable('navigation', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.jsonb('items').notNullable().defaultTo('[]') - }) - // PAGE HISTORY ------------------------ - .createTable('pageHistory', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.uuid('pageId').notNullable().index() - table.string('action').defaultTo('updated') - table.string('reason') - table.jsonb('affectedFields').notNullable().defaultTo('[]') - table.string('locale', 10).notNullable().defaultTo('en') - table.string('path').notNullable() - table.string('hash').notNullable() - table.string('alias') - table.string('title').notNullable() - table.string('description') - table.string('icon') - table.enu('publishState', ['draft', 'published', 'scheduled']).notNullable().defaultTo('draft') - table.timestamp('publishStartDate') - table.timestamp('publishEndDate') - table.jsonb('config').notNullable().defaultTo('{}') - table.jsonb('relations').notNullable().defaultTo('[]') - table.text('content') - table.text('render') - table.jsonb('toc') - table.string('editor').notNullable() - table.string('contentType').notNullable() - table.jsonb('scripts').notNullable().defaultTo('{}') - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('versionDate').notNullable().defaultTo(knex.fn.now()) - }) - // PAGE LINKS -------------------------- - .createTable('pageLinks', table => { - table.increments('id').primary() - table.string('path').notNullable() - table.string('locale', 10).notNullable() - }) - // PAGES ------------------------------- - .createTable('pages', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('locale', 10).notNullable() - table.string('path').notNullable() - table.string('hash').notNullable() - table.string('alias') - table.string('title').notNullable() - table.string('description') - table.string('icon') - table.enu('publishState', ['draft', 'published', 'scheduled']).notNullable().defaultTo('draft') - table.timestamp('publishStartDate') - table.timestamp('publishEndDate') - table.jsonb('config').notNullable().defaultTo('{}') - table.jsonb('relations').notNullable().defaultTo('[]') - table.text('content') - table.text('render') - table.text('searchContent') - table.specificType('ts', 'tsvector').index('pages_ts_idx', { indexType: 'GIN' }) - table.specificType('tags', 'text[]').index('pages_tags_idx', { indexType: 'GIN' }) - table.jsonb('toc') - table.string('editor').notNullable() - table.string('contentType').notNullable() - table.boolean('isBrowsable').notNullable().defaultTo(true) - table.boolean('isSearchable').notNullable().defaultTo(true) - table.specificType('isSearchableComputed', 'boolean GENERATED ALWAYS AS ("publishState" != \'draft\' AND "isSearchable") STORED').index() - table.string('password') - table.integer('ratingScore').notNullable().defaultTo(0) - table.integer('ratingCount').notNullable().defaultTo(0) - table.jsonb('scripts').notNullable().defaultTo('{}') - table.jsonb('historyData').notNullable().defaultTo('{}') - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // RENDERERS --------------------------- - .createTable('renderers', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('module').notNullable() - table.boolean('isEnabled').notNullable().defaultTo(false) - table.jsonb('config').notNullable().defaultTo('{}') - }) - // SETTINGS ---------------------------- - .createTable('settings', table => { - table.string('key').notNullable().primary() - table.jsonb('value') - }) - // SITES ------------------------------- - .createTable('sites', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('hostname').notNullable() - table.boolean('isEnabled').notNullable().defaultTo(false) - table.jsonb('config').notNullable() - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - }) - // STORAGE ----------------------------- - .createTable('storage', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('module').notNullable() - table.boolean('isEnabled').notNullable().defaultTo(false) - table.jsonb('contentTypes') - table.jsonb('assetDelivery') - table.jsonb('versioning') - table.jsonb('schedule') - table.jsonb('config') - table.jsonb('state') - }) - // TAGS -------------------------------- - .createTable('tags', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('tag').notNullable() - table.integer('usageCount').notNullable().defaultTo(0) - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // TREE -------------------------------- - .createTable('tree', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.specificType('folderPath', 'ltree').index().index('tree_folderpath_gist_idx', { indexType: 'GIST' }) - table.string('fileName').notNullable().index() - table.string('hash').notNullable().index() - table.enu('type', ['folder', 'page', 'asset']).notNullable().index() - table.string('locale', 10).notNullable().defaultTo('en').index() - table.string('title').notNullable() - table.enum('navigationMode', ['inherit', 'override', 'overrideExact', 'hide', 'hideExact']).notNullable().defaultTo('inherit').index() - table.uuid('navigationId').index() - table.specificType('tags', 'text[]').index('tree_tags_idx', { indexType: 'GIN' }) - table.jsonb('meta').notNullable().defaultTo('{}') - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // USER AVATARS ------------------------ - .createTable('userAvatars', table => { - table.uuid('id').notNullable().primary() - table.binary('data').notNullable() - }) - // USER EDITOR SETTINGS ---------------- - .createTable('userEditorSettings', table => { - table.uuid('id').notNullable() - table.string('editor').notNullable() - table.jsonb('config').notNullable().defaultTo('{}') - table.primary(['id', 'editor']) - }) - // USER KEYS --------------------------- - .createTable('userKeys', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('kind').notNullable() - table.string('token').notNullable() - table.jsonb('meta').notNullable().defaultTo('{}') - table.timestamp('validUntil').notNullable() - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - }) - // USERS ------------------------------- - .createTable('users', table => { - table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()')) - table.string('email').notNullable() - table.string('name').notNullable() - table.jsonb('auth').notNullable().defaultTo('{}') - table.jsonb('meta').notNullable().defaultTo('{}') - table.jsonb('passkeys').notNullable().defaultTo('{}') - table.jsonb('prefs').notNullable().defaultTo('{}') - table.boolean('hasAvatar').notNullable().defaultTo(false) - table.boolean('isSystem').notNullable().defaultTo(false) - table.boolean('isActive').notNullable().defaultTo(false) - table.boolean('isVerified').notNullable().defaultTo(false) - table.timestamp('lastLoginAt').index() - table.timestamp('createdAt').notNullable().defaultTo(knex.fn.now()) - table.timestamp('updatedAt').notNullable().defaultTo(knex.fn.now()) - }) - // ===================================== - // RELATION TABLES - // ===================================== - // USER GROUPS ------------------------- - .createTable('userGroups', table => { - table.increments('id').primary() - table.uuid('userId').references('id').inTable('users').onDelete('CASCADE') - table.uuid('groupId').references('id').inTable('groups').onDelete('CASCADE') - }) - // ===================================== - // REFERENCES - // ===================================== - .table('activityLogs', table => { - table.uuid('userId').notNullable().references('id').inTable('users') - }) - .table('analytics', table => { - table.uuid('siteId').notNullable().references('id').inTable('sites') - }) - .table('assets', table => { - table.uuid('authorId').notNullable().references('id').inTable('users') - table.uuid('siteId').notNullable().references('id').inTable('sites').index() - }) - .table('blocks', table => { - table.uuid('siteId').notNullable().references('id').inTable('sites') - }) - .table('commentProviders', table => { - table.uuid('siteId').notNullable().references('id').inTable('sites') - }) - .table('comments', table => { - table.uuid('pageId').notNullable().references('id').inTable('pages').index() - table.uuid('authorId').notNullable().references('id').inTable('users').index() - }) - .table('navigation', table => { - table.uuid('siteId').notNullable().references('id').inTable('sites').index() - }) - .table('pageHistory', table => { - table.uuid('authorId').notNullable().references('id').inTable('users') - table.uuid('siteId').notNullable().references('id').inTable('sites').index() - }) - .table('pageLinks', table => { - table.uuid('pageId').notNullable().references('id').inTable('pages').onDelete('CASCADE') - table.index(['path', 'locale']) - }) - .table('pages', table => { - table.uuid('authorId').notNullable().references('id').inTable('users').index() - table.uuid('creatorId').notNullable().references('id').inTable('users').index() - table.uuid('ownerId').notNullable().references('id').inTable('users').index() - table.uuid('siteId').notNullable().references('id').inTable('sites').index() - }) - .table('storage', table => { - table.uuid('siteId').notNullable().references('id').inTable('sites') - }) - .table('tags', table => { - table.uuid('siteId').notNullable().references('id').inTable('sites') - table.unique(['siteId', 'tag']) - }) - .table('tree', table => { - table.uuid('siteId').notNullable().references('id').inTable('sites') - }) - .table('userKeys', table => { - table.uuid('userId').notNullable().references('id').inTable('users') - }) - // ===================================== - // TS WORD SUGGESTION TABLE - // ===================================== - .createTable('autocomplete', table => { - table.text('word') - }) - .raw('CREATE INDEX "autocomplete_idx" ON "autocomplete" USING GIN (word gin_trgm_ops)') - - // ===================================== - // DEFAULT DATA - // ===================================== - - // -> GENERATE IDS - - const groupAdminId = uuid() - const groupUserId = WIKI.data.systemIds.usersGroupId - const groupGuestId = WIKI.data.systemIds.guestsGroupId - const siteId = uuid() - const authModuleId = WIKI.data.systemIds.localAuthId - const userAdminId = uuid() - const userGuestId = uuid() - - // -> SYSTEM CONFIG - - WIKI.logger.info('Generating certificates...') - const secret = crypto.randomBytes(32).toString('hex') - const certs = crypto.generateKeyPairSync('rsa', { - modulusLength: 2048, - publicKeyEncoding: { - type: 'pkcs1', - format: 'pem' - }, - privateKeyEncoding: { - type: 'pkcs1', - format: 'pem', - cipher: 'aes-256-cbc', - passphrase: secret - } - }) - - await knex('settings').insert([ - { - key: 'api', - value: { - isEnabled: false - } - }, - { - key: 'auth', - value: { - audience: 'urn:wiki.js', - tokenExpiration: '30m', - tokenRenewal: '14d', - certs: { - jwk: pem2jwk(certs.publicKey), - public: certs.publicKey, - private: certs.privateKey - }, - secret, - rootAdminGroupId: groupAdminId, - rootAdminUserId: userAdminId, - guestUserId: userGuestId - } - }, - { - key: 'flags', - value: { - experimental: false, - authDebug: false, - sqlLog: false - } - }, - { - key: 'icons', - value: { - fa: { - isActive: true, - config: { - version: 6, - license: 'free', - token: '' - } - }, - la: { - isActive: true - } - } - }, - { - key: 'mail', - value: { - senderName: '', - senderEmail: '', - defaultBaseURL: 'https://wiki.example.com', - host: '', - port: 465, - name: '', - secure: true, - verifySSL: true, - user: '', - pass: '', - useDKIM: false, - dkimDomainName: '', - dkimKeySelector: '', - dkimPrivateKey: '' - } - }, - { - key: 'metrics', - value: { - isEnabled: false - } - }, - { - key: 'search', - value: { - termHighlighting: true, - dictOverrides: {} - } - }, - { - key: 'security', - value: { - corsConfig: '', - corsMode: 'OFF', - cspDirectives: '', - disallowFloc: true, - disallowIframe: true, - disallowOpenRedirect: true, - enforceCsp: false, - enforceHsts: false, - enforceSameOriginReferrerPolicy: true, - forceAssetDownload: true, - hstsDuration: 0, - trustProxy: false, - authJwtAudience: 'urn:wiki.js', - authJwtExpiration: '30m', - authJwtRenewablePeriod: '14d', - uploadMaxFileSize: 10485760, - uploadMaxFiles: 20, - uploadScanSVG: true - } - }, - { - key: 'update', - value: { - lastCheckedAt: null, - version: WIKI.version, - versionDate: WIKI.releaseDate - } - }, - { - key: 'userDefaults', - value: { - timezone: 'America/New_York', - dateFormat: 'YYYY-MM-DD', - timeFormat: '12h' - } - } - ]) - - // -> DEFAULT SITE - - await knex('sites').insert({ - id: siteId, - hostname: '*', - isEnabled: true, - config: { - title: 'Default Site', - description: '', - company: '', - contentLicense: '', - footerExtra: '', - pageExtensions: ['md', 'html', 'txt'], - pageCasing: true, - discoverable: false, - defaults: { - tocDepth: { - min: 1, - max: 2 - } - }, - features: { - browse: true, - ratings: false, - ratingsMode: 'off', - comments: false, - contributions: false, - profile: true, - reasonForChange: 'required', - search: true - }, - logoText: true, - sitemap: true, - robots: { - index: true, - follow: true - }, - authStrategies: [{ id: authModuleId, order: 0, isVisible: true }], - locales: { - primary: 'en', - active: ['en'] - }, - assets: { - logo: false, - logoExt: 'svg', - favicon: false, - faviconExt: 'svg', - loginBg: false - }, - editors: { - asciidoc: { - isActive: true, - config: {} - }, - markdown: { - isActive: true, - config: { - allowHTML: true, - kroki: false, - krokiServerUrl: 'https://kroki.io', - latexEngine: 'katex', - lineBreaks: true, - linkify: true, - multimdTable: true, - plantuml: false, - plantumlServerUrl: 'https://www.plantuml.com/plantuml/', - quotes: 'english', - tabWidth: 2, - typographer: false, - underline: true - } - }, - wysiwyg: { - isActive: true, - config: {} - } - }, - theme: { - dark: false, - codeBlocksTheme: 'github-dark', - colorPrimary: '#1976D2', - colorSecondary: '#02C39A', - colorAccent: '#FF9800', - colorHeader: '#000000', - colorSidebar: '#1976D2', - injectCSS: '', - injectHead: '', - injectBody: '', - contentWidth: 'full', - sidebarPosition: 'left', - tocPosition: 'right', - showSharingMenu: true, - showPrintBtn: true, - baseFont: 'roboto', - contentFont: 'roboto' - }, - uploads: { - conflictBehavior: 'overwrite', - normalizeFilename: true - } - } - }) - - // -> DEFAULT GROUPS - - await knex('groups').insert([ - { - id: groupAdminId, - name: 'Administrators', - permissions: JSON.stringify(['manage:system']), - rules: JSON.stringify([]), - isSystem: true - }, - { - id: groupUserId, - name: 'Users', - permissions: JSON.stringify(['read:pages', 'read:assets', 'read:comments']), - rules: JSON.stringify([ - { - id: uuid(), - name: 'Default Rule', - roles: ['read:pages', 'read:assets', 'read:comments'], - match: 'START', - mode: 'ALLOW', - path: '', - locales: [], - sites: [] - } - ]), - isSystem: true - }, - { - id: groupGuestId, - name: 'Guests', - permissions: JSON.stringify(['read:pages', 'read:assets', 'read:comments']), - rules: JSON.stringify([ - { - id: uuid(), - name: 'Default Rule', - roles: ['read:pages', 'read:assets', 'read:comments'], - match: 'START', - mode: 'DENY', - path: '', - locales: [], - sites: [] - } - ]), - isSystem: true - } - ]) - - // -> AUTHENTICATION MODULE - - await knex('authentication').insert({ - id: authModuleId, - module: 'local', - isEnabled: true, - displayName: 'Local Authentication', - config: JSON.stringify({ - emailValidation: true, - enforceTfa: false - }) - }) - - // -> USERS - - await knex('users').insert([ - { - id: userAdminId, - email: process.env.ADMIN_EMAIL ?? 'admin@example.com', - auth: { - [authModuleId]: { - password: await bcrypt.hash(process.env.ADMIN_PASS || '12345678', 12), - mustChangePwd: !process.env.ADMIN_PASS, - restrictLogin: false, - tfaIsActive: false, - tfaRequired: false, - tfaSecret: '' - } - }, - name: 'Administrator', - isSystem: false, - isActive: true, - isVerified: true, - meta: { - location: '', - jobTitle: '', - pronouns: '' - }, - prefs: { - timezone: 'America/New_York', - dateFormat: 'YYYY-MM-DD', - timeFormat: '12h', - appearance: 'site', - cvd: 'none' - } - }, - { - id: userGuestId, - email: 'guest@example.com', - auth: {}, - name: 'Guest', - isSystem: true, - isActive: true, - isVerified: true, - meta: {}, - prefs: { - timezone: 'America/New_York', - dateFormat: 'YYYY-MM-DD', - timeFormat: '12h', - appearance: 'site', - cvd: 'none' - } - } - ]) - - await knex('userGroups').insert([ - { - userId: userAdminId, - groupId: groupAdminId - }, - { - userId: userAdminId, - groupId: groupUserId - }, - { - userId: userGuestId, - groupId: groupGuestId - } - ]) - - // -> BLOCKS - - await knex('blocks').insert({ - block: 'index', - name: 'Index', - description: 'Show a list of pages matching a path or set of tags.', - icon: 'rules', - isCustom: false, - isEnabled: true, - config: {}, - siteId - }) - - // -> NAVIGATION - - await knex('navigation').insert({ - id: siteId, - items: JSON.stringify([ - { - id: uuid(), - type: 'header', - label: 'Sample Header', - visibilityGroups: [] - }, - { - id: uuid(), - type: 'link', - icon: 'mdi-file-document-outline', - label: 'Sample Link 1', - target: '/', - openInNewWindow: false, - visibilityGroups: [], - children: [] - }, - { - id: uuid(), - type: 'link', - icon: 'mdi-book-open-variant', - label: 'Sample Link 2', - target: '/', - openInNewWindow: false, - visibilityGroups: [], - children: [] - }, - { - id: uuid(), - type: 'separator', - visibilityGroups: [] - }, - { - id: uuid(), - type: 'link', - icon: 'mdi-airballoon', - label: 'Sample Link 3', - target: '/', - openInNewWindow: false, - visibilityGroups: [], - children: [] - } - ]), - siteId - }) - - // -> STORAGE MODULE - - await knex('storage').insert({ - module: 'db', - siteId, - isEnabled: true, - contentTypes: { - activeTypes: ['pages', 'images', 'documents', 'others', 'large'], - largeThreshold: '5MB' - }, - assetDelivery: { - streaming: true, - directAccess: false - }, - versioning: { - enabled: false - }, - state: { - current: 'ok' - } - }) - - // -> SCHEDULED JOBS - - await knex('jobSchedule').insert([ - { - task: 'checkVersion', - cron: '0 0 * * *', - type: 'system' - }, - { - task: 'cleanJobHistory', - cron: '5 0 * * *', - type: 'system' - }, - // { - // task: 'refreshAutocomplete', - // cron: '0 */6 * * *', - // type: 'system' - // }, - { - task: 'updateLocales', - cron: '0 0 * * *', - type: 'system' - } - ]) - - await knex('jobLock').insert({ - key: 'cron', - lastCheckedBy: 'init', - lastCheckedAt: DateTime.utc().minus({ hours: 1 }).toISO() - }) - - WIKI.logger.info('Completed 3.0.0 database migration.') -} - -export function down (knex) { } diff --git a/server/db/migrator-source.mjs b/server/db/migrator-source.mjs deleted file mode 100644 index ee8663310..000000000 --- a/server/db/migrator-source.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import path from 'node:path' -import fse from 'fs-extra' -import semver from 'semver' - -export default { - /** - * Gets the migration names - * @returns Promise - */ - async getMigrations() { - const baseMigrationPath = path.join(WIKI.SERVERPATH, 'db/migrations') - const migrationFiles = await fse.readdir(baseMigrationPath) - return migrationFiles.map(m => m.replace('.mjs', '')).sort(semver.compare).map(m => ({ - file: m, - directory: baseMigrationPath - })) - }, - - getMigrationName(migration) { - return migration.file.indexOf('.mjs') >= 0 ? migration.file : `${migration.file}.mjs` - }, - - async getMigration(migration) { - return import(path.join(WIKI.SERVERPATH, 'db/migrations', `${migration.file}.mjs`)) - } -} diff --git a/server/eslint.config.js b/server/eslint.config.js deleted file mode 100644 index 96337ce65..000000000 --- a/server/eslint.config.js +++ /dev/null @@ -1,19 +0,0 @@ -import neostandard from 'neostandard' - -export default neostandard({ - globals: { - document: false, - navigator: false, - window: false, - WIKI: true - }, - ignores: [ - '**/node_modules/**', - '**/*.min.js', - 'coverage/**', - 'repo/**', - 'data/**', - 'logs/**', - 'locales/**' - ] -}) diff --git a/server/graph/index.mjs b/server/graph/index.mjs deleted file mode 100644 index 116c16f54..000000000 --- a/server/graph/index.mjs +++ /dev/null @@ -1,61 +0,0 @@ -import { merge } from 'lodash-es' -import fs from 'node:fs/promises' -import path from 'node:path' -import { makeExecutableSchema } from '@graphql-tools/schema' -import { defaultKeyGenerator, rateLimitDirective } from 'graphql-rate-limit-directive' -import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs' - -import DateScalar from './scalars/date.mjs' -import JSONScalar from './scalars/json.mjs' -import UUIDScalar from './scalars/uuid.mjs' - -export async function initSchema () { - // Rate Limiter - - const { rateLimitDirectiveTypeDefs, rateLimitDirectiveTransformer } = rateLimitDirective({ - keyGenerator: (directiveArgs, source, args, context, info) => `${context.req.ip}:${defaultKeyGenerator(directiveArgs, source, args, context, info)}` - }) - - // Schemas - - WIKI.logger.info(`Loading GraphQL Schema...`) - const typeDefs = [ - rateLimitDirectiveTypeDefs - ] - const schemaList = await fs.readdir(path.join(WIKI.SERVERPATH, 'graph/schemas')) - for (const schemaFile of schemaList) { - typeDefs.push(await fs.readFile(path.join(WIKI.SERVERPATH, `graph/schemas/${schemaFile}`), 'utf8')) - } - - // Resolvers - - WIKI.logger.info(`Loading GraphQL Resolvers...`) - let resolvers = { - Date: DateScalar, - JSON: JSONScalar, - UUID: UUIDScalar, - Upload: GraphQLUpload - } - - const resolverList = await fs.readdir(path.join(WIKI.SERVERPATH, 'graph/resolvers')) - for (const resolverFile of resolverList) { - const resolver = (await import(path.join(WIKI.SERVERPATH, 'graph/resolvers', resolverFile))).default - merge(resolvers, resolver) - } - - // Make executable schema - - WIKI.logger.info(`Compiling GraphQL Schema...`) - let schema = makeExecutableSchema({ - typeDefs, - resolvers - }) - - // Apply schema transforms - - schema = rateLimitDirectiveTransformer(schema) - - WIKI.logger.info(`GraphQL Schema: [ OK ]`) - - return schema -} diff --git a/server/graph/resolvers/analytics.mjs b/server/graph/resolvers/analytics.mjs deleted file mode 100644 index 0f3b6352d..000000000 --- a/server/graph/resolvers/analytics.mjs +++ /dev/null @@ -1,57 +0,0 @@ -import { find, get, reduce, set, sortBy, transform } from 'lodash-es' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' - -export default { - Query: { - async analyticsProviders (obj, args, context, info) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - let providers = await WIKI.db.analytics.getProviders(args.isEnabled) - providers = providers.map(stg => { - const providerInfo = find(WIKI.data.analytics, ['key', stg.key]) || {} - return { - ...providerInfo, - ...stg, - config: sortBy(transform(stg.config, (res, value, key) => { - const configData = get(providerInfo.props, key, {}) - res.push({ - key, - value: JSON.stringify({ - ...configData, - value - }) - }) - }, []), 'key') - } - }) - return providers - } - }, - Mutation: { - async updateAnalyticsProviders (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - for (const str of args.providers) { - await WIKI.db.analytics.query().patch({ - isEnabled: str.isEnabled, - config: reduce(str.config, (result, value, key) => { - set(result, `${value.key}`, get(JSON.parse(value.value), 'v', null)) - return result - }, {}) - }).where('key', str.key) - await WIKI.cache.del('analytics') - } - return { - responseResult: generateSuccess('Providers updated successfully') - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/asset.mjs b/server/graph/resolvers/asset.mjs deleted file mode 100644 index ceaccd416..000000000 --- a/server/graph/resolvers/asset.mjs +++ /dev/null @@ -1,401 +0,0 @@ -import _ from 'lodash-es' -import sanitize from 'sanitize-filename' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import { decodeTreePath, generateHash } from '../../helpers/common.mjs' -import path from 'node:path' -import fs from 'fs-extra' -import { v4 as uuid } from 'uuid' -import { pipeline } from 'node:stream/promises' - -export default { - Query: { - async assetById (obj, args, context) { - const asset = await WIKI.db.assets.query().findById(args.id).withGraphFetched('tree') - if (asset) { - const assetPath = asset.tree.folderPath ? `${decodeTreePath(asset.tree.folderPath)}/${asset.tree.fileName}` : asset.tree.fileName - if (!WIKI.auth.checkAccess(context.req.user, ['read:assets'], { path: assetPath })) { - throw new Error('ERR_FORBIDDEN') - } - return asset - } else { - throw new Error('ERR_ASSET_NOT_FOUND') - } - } - }, - Mutation: { - /** - * Rename an Asset - */ - async renameAsset (obj, args, context) { - try { - const filename = sanitize(args.fileName).toLowerCase() - - const asset = await WIKI.db.assets.query().findById(args.id) - const treeItem = await WIKI.db.tree.query().findById(args.id) - if (asset && treeItem) { - // Check for extension mismatch - if (!_.endsWith(filename, asset.fileExt)) { - throw new Error('ERR_ASSET_EXT_MISMATCH') - } - - // Check for non-dot files changing to dotfile - if (asset.fileExt.length > 0 && filename.length - asset.fileExt.length < 1) { - throw new Error('ERR_ASSET_INVALID_DOTFILE') - } - - // Check for collision - const assetCollision = await WIKI.db.tree.query().where({ - folderPath: treeItem.folderPath, - fileName: filename - }).first() - if (assetCollision) { - throw new Error('ERR_ASSET_ALREADY_EXISTS') - } - - // Check source asset permissions - const assetSourcePath = (treeItem.folderPath) ? decodeTreePath(treeItem.folderPath) + `/${treeItem.fileName}` : treeItem.fileName - if (!WIKI.auth.checkAccess(context.req.user, ['manage:assets'], { path: assetSourcePath })) { - throw new Error('ERR_FORBIDDEN') - } - - // Check target asset permissions - const assetTargetPath = (treeItem.folderPath) ? decodeTreePath(treeItem.folderPath) + `/${filename}` : filename - if (!WIKI.auth.checkAccess(context.req.user, ['write:assets'], { path: assetTargetPath })) { - throw new Error('ERR_TARGET_FORBIDDEN') - } - - // Update filename + hash - const itemHash = generateHash(assetTargetPath) - await WIKI.db.assets.query().patch({ - fileName: filename - }).findById(asset.id) - - await WIKI.db.tree.query().patch({ - fileName: filename, - title: filename, - hash: itemHash - }).findById(treeItem.id) - - // TODO: Delete old asset cache - WIKI.events.outbound.emit('purgeItemCache', itemHash) - - // TODO: Rename in Storage - // await WIKI.db.storage.assetEvent({ - // event: 'renamed', - // asset: { - // ...asset, - // path: assetSourcePath, - // destinationPath: assetTargetPath, - // moveAuthorId: context.req.user.id, - // moveAuthorName: context.req.user.name, - // moveAuthorEmail: context.req.user.email - // } - // }) - - return { - operation: generateSuccess('Asset has been renamed successfully.') - } - } else { - throw new Error('ERR_INVALID_ASSET') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Delete an Asset - */ - async deleteAsset (obj, args, context) { - try { - const treeItem = await WIKI.db.tree.query().findById(args.id) - if (treeItem) { - // Check permissions - const assetPath = (treeItem.folderPath) ? decodeTreePath(treeItem.folderPath) + `/${treeItem.fileName}` : treeItem.fileName - if (!WIKI.auth.checkAccess(context.req.user, ['manage:assets'], { path: assetPath })) { - throw new Error('ERR_FORBIDDEN') - } - - // Delete from DB - await WIKI.db.assets.query().deleteById(treeItem.id) - await WIKI.db.tree.query().deleteById(treeItem.id) - - // TODO: Delete asset cache - WIKI.events.outbound.emit('purgeItemCache', treeItem.hash) - - // TODO: Delete from Storage - // await WIKI.db.storage.assetEvent({ - // event: 'deleted', - // asset: { - // ...asset, - // path: assetPath, - // authorId: context.req.user.id, - // authorName: context.req.user.name, - // authorEmail: context.req.user.email - // } - // }) - - return { - operation: generateSuccess('Asset has been deleted successfully.') - } - } else { - throw new Error('ERR_INVALID_ASSET') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Upload Assets - */ - async uploadAssets (obj, args, context) { - try { - // FIXME: Perm - // -> Get Folder - let folder = {} - if (args.folderId || args.folderPath) { - // Get Folder by ID - folder = await WIKI.db.tree.getFolder({ id: args.folderId }) - if (!folder) { - throw new Error('ERR_INVALID_FOLDER_ID') - } - } else if (args.folderPath) { - // Get Folder by Path - if (!args.locale) { - throw new Error('ERR_MISSING_LOCALE') - } else if (!args.siteId) { - throw new Error('ERR_MISSING_SITE_ID') - } - folder = await WIKI.db.tree.getFolder({ - path: args.folderPath, - locale: args.locale, - siteId: args.siteId, - createIfMissing: true - }) - if (!folder) { - throw new Error('ERR_INVALID_FOLDER_PATH') - } - } else { - // Use Root Folder - if (!args.locale) { - throw new Error('ERR_MISSING_LOCALE') - } else if (!args.siteId) { - throw new Error('ERR_MISSING_SITE_ID') - } - folder = { - folderPath: '', - fileName: '', - locale: args.locale, - siteId: args.siteId - } - } - - // -> Get Site - const site = await WIKI.db.sites.query().findById(folder.siteId) - if (!site) { - throw new Error('ERR_INVALID_SITE_ID') - } - - // -> Get Storage Targets - const storageTargets = await WIKI.db.storage.getTargets({ siteId: folder.siteId, enabledOnly: true }) - - // -> Process Assets - const results = await Promise.allSettled(args.files.map(async fl => { - const { filename, mimetype, createReadStream } = await fl - const sanitizedFilename = sanitize(filename).toLowerCase().trim() - - WIKI.logger.debug(`Processing asset upload ${sanitizedFilename} of type ${mimetype}...`) - - // Parse file extension - if (sanitizedFilename.indexOf('.') <= 0) { - throw new Error('ERR_ASSET_DOTFILE_NOTALLOWED') - } - const fileExt = _.last(sanitizedFilename.split('.')).toLowerCase() - - // Determine asset kind - let fileKind = 'other' - switch (fileExt) { - case 'jpg': - case 'jpeg': - case 'png': - case 'webp': - case 'gif': - case 'tiff': - case 'svg': - fileKind = 'image' - break - case 'pdf': - case 'docx': - case 'xlsx': - case 'pptx': - case 'odt': - case 'epub': - case 'csv': - case 'md': - case 'txt': - case 'adoc': - case 'rtf': - case 'wdp': - case 'xps': - case 'ods': - fileKind = 'document' - break - } - - // Save to temp disk - const tempFileId = uuid() - const tempFilePath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `uploads/${tempFileId}.dat`) - WIKI.logger.debug(`Writing asset upload ${sanitizedFilename} to temp disk...`) - await pipeline( - createReadStream(), - fs.createWriteStream(tempFilePath) - ) - WIKI.logger.debug(`Querying asset ${sanitizedFilename} file size...`) - const tempFileStat = await fs.stat(tempFilePath) - - // Format filename - const formattedFilename = site.config.uploads.normalizeFilename ? sanitizedFilename.replaceAll(' ', '-') : sanitizedFilename - - // Save asset to DB - WIKI.logger.debug(`Saving asset ${sanitizedFilename} metadata to DB...`) - const assetRaw = await WIKI.db.knex('assets').insert({ - fileName: formattedFilename, - fileExt, - kind: fileKind, - mimeType: mimetype, - fileSize: Math.round(tempFileStat.size), - meta: {}, - previewState: fileKind === 'image' ? 'pending' : 'none', - authorId: context.req.user.id, - siteId: folder.siteId - }).returning('*') - - const asset = assetRaw[0] - - // Add to tree - await WIKI.db.tree.addAsset({ - id: asset.id, - parentPath: folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName, - fileName: formattedFilename, - title: formattedFilename, - locale: folder.locale, - siteId: folder.siteId, - meta: { - authorId: asset.authorId, - creatorId: asset.creatorId, - fileSize: asset.fileSize, - fileExt, - mimeType: mimetype, - ownerId: asset.ownerId - } - }) - - // Save to storage targets - const storageInfo = {} - const failedStorage = [] - await Promise.allSettled(storageTargets.map(async storageTarget => { - WIKI.logger.debug(`Saving asset ${sanitizedFilename} to storage target ${storageTarget.module} (${storageTarget.id})...`) - try { - const strInfo = await WIKI.storage.modules[storageTarget.module].assetUploaded({ - asset, - createReadStream, - storageTarget, - tempFilePath - }) - storageInfo[storageTarget.id] = strInfo ?? true - } catch (err) { - WIKI.logger.warn(`Failed to save asset ${sanitizedFilename} to storage target ${storageTarget.module} (${storageTarget.id}):`) - WIKI.logger.warn(err) - failedStorage.push({ - storageId: storageTarget.id, - storageModule: storageTarget.module, - fileId: asset.id, - fileName: formattedFilename - }) - } - })) - - // Save Storage Info to DB - await WIKI.db.knex('assets').where({ id: asset.id }).update({ storageInfo }) - - // Create thumbnail - if (fileKind === 'image') { - if (!WIKI.extensions.ext.sharp.isInstalled) { - WIKI.logger.warn('Cannot generate asset thumbnail because the Sharp extension is not installed.') - } else { - WIKI.logger.debug(`Generating thumbnail of asset ${sanitizedFilename}...`) - const previewDestPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `uploads/${tempFileId}-thumb.webp`) - // -> Resize - await WIKI.extensions.ext.sharp.resize({ - format: 'webp', - inputStream: createReadStream(), - outputPath: previewDestPath, - width: 320, - height: 200, - fit: 'inside' - }) - // -> Save to DB - await WIKI.db.knex('assets').where({ - id: asset.id - }).update({ - preview: await fs.readFile(previewDestPath), - previewState: 'ready' - }) - - // -> Delete - await fs.remove(previewDestPath) - } - } - - WIKI.logger.debug(`Removing asset ${sanitizedFilename} temp file...`) - await fs.remove(tempFilePath) - - WIKI.logger.debug(`Processed asset ${sanitizedFilename} successfully.`) - return failedStorage - })) - - // Return results - const failedResults = results.filter(r => r.status === 'rejected') - if (failedResults.length > 0) { - // -> One or more thrown errors - WIKI.logger.warn('Failed to upload one or more assets:') - for (const failedResult of failedResults) { - WIKI.logger.warn(failedResult.reason) - } - throw new Error('ERR_UPLOAD_FAILED') - } else { - const failedSaveTargets = results.map(r => r.value).filter(r => r.length > 0) - if (failedSaveTargets.length > 0) { - // -> One or more storage target save errors - WIKI.logger.warn('Failed to save one or more assets to storage targets.') - throw new Error('ERR_UPLOAD_TARGET_FAILED') - } else { - WIKI.logger.debug('Asset(s) uploaded successfully.') - return { - operation: generateSuccess('Asset(s) uploaded successfully') - } - } - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * Flush Temporary Uploads - */ - async flushTempUploads (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.assets.flushTempUploads() - return { - operation: generateSuccess('Temporary Uploads have been flushed successfully.') - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/authentication.mjs b/server/graph/resolvers/authentication.mjs deleted file mode 100644 index 299e39894..000000000 --- a/server/graph/resolvers/authentication.mjs +++ /dev/null @@ -1,741 +0,0 @@ -import _ from 'lodash-es' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import jwt from 'jsonwebtoken' -import ms from 'ms' -import { DateTime } from 'luxon' -import { base64 } from '@hexagon/base64' -import { - generateRegistrationOptions, - verifyRegistrationResponse, - generateAuthenticationOptions, - verifyAuthenticationResponse -} from '@simplewebauthn/server' -import { isoBase64URL } from '@simplewebauthn/server/helpers' - -export default { - Query: { - /** - * List of API Keys - */ - async apiKeys (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:api', 'manage:api'])) { - throw new Error('ERR_FORBIDDEN') - } - - const keys = await WIKI.db.apiKeys.query().orderBy(['isRevoked', 'name']) - return keys.map(k => ({ - id: k.id, - name: k.name, - keyShort: '...' + k.key.substring(k.key.length - 20), - isRevoked: k.isRevoked, - expiration: k.expiration, - createdAt: k.createdAt, - updatedAt: k.updatedAt - })) - }, - /** - * Current API State - */ - apiState (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:api', 'manage:api', 'read:dashboard'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.config.api.isEnabled - }, - /** - * Fetch authentication strategies - */ - async authStrategies (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.data.authentication.map(stg => ({ - ...stg, - isAvailable: stg.isAvailable === true - })) - }, - /** - * Fetch active authentication strategies - */ - async authActiveStrategies (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - const strategies = await WIKI.db.authentication.getStrategies({ enabledOnly: args.enabledOnly }) - return strategies.map(a => { - const str = _.find(WIKI.data.authentication, ['key', a.module]) || {} - return { - ...a, - config: _.transform(str.props, (r, v, k) => { - r[k] = v.sensitive ? '********' : a.config[k] - }, {}) - } - }) - }, - /** - * Fetch site authentication strategies - */ - async authSiteStrategies (obj, args, context, info) { - const site = await WIKI.db.sites.query().findById(args.siteId) - const activeStrategies = await WIKI.db.authentication.getStrategies({ enabledOnly: true }) - const siteStrategies = _.sortBy(activeStrategies.map(str => { - const siteAuth = _.find(site.config.authStrategies, ['id', str.id]) || {} - return { - id: str.id, - activeStrategy: str, - order: siteAuth.order ?? 0, - isVisible: siteAuth.isVisible ?? false - } - }), ['order']) - return args.visibleOnly ? siteStrategies.filter(s => s.isVisible) : siteStrategies - } - }, - Mutation: { - /** - * Create New API Key - */ - async createApiKey (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:api'])) { - throw new Error('ERR_FORBIDDEN') - } - - const key = await WIKI.db.apiKeys.createNewKey(args) - await WIKI.auth.reloadApiKeys() - WIKI.events.outbound.emit('reloadApiKeys') - return { - key, - operation: generateSuccess('API Key created successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * Perform Login - */ - async login (obj, args, context) { - try { - const authResult = await WIKI.db.users.login(args, context) - return { - ...authResult, - operation: generateSuccess('Login success') - } - } catch (err) { - // LDAP Debug Flag - if (args.strategy === 'ldap' && WIKI.config.flags.ldapdebug) { - WIKI.logger.warn('LDAP LOGIN ERROR (c1): ', err) - } - WIKI.logger.debug(err) - - return generateError(err) - } - }, - /** - * Perform 2FA Login - */ - async loginTFA (obj, args, context) { - try { - const authResult = await WIKI.db.users.loginTFA(args, context) - return { - ...authResult, - operation: generateSuccess('TFA success') - } - } catch (err) { - WIKI.logger.debug(err) - return generateError(err) - } - }, - /** - * Setup TFA - */ - async setupTFA (obj, args, context) { - try { - const userId = context.req.user?.id - if (!userId) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - - const usr = await WIKI.db.users.query().findById(userId) - if (!usr) { - throw new Error('ERR_INVALID_USER') - } - - const str = WIKI.auth.strategies[args.strategyId] - if (!str) { - throw new Error('ERR_INVALID_STRATEGY') - } - - if (!usr.auth[args.strategyId]) { - throw new Error('ERR_INVALID_STRATEGY') - } - - if (usr.auth[args.strategyId].tfaIsActive) { - throw new Error('ERR_TFA_ALREADY_ACTIVE') - } - - const tfaQRImage = await usr.generateTFA(args.strategyId, args.siteId) - const tfaToken = await WIKI.db.userKeys.generateToken({ - kind: 'tfaSetup', - userId: usr.id, - meta: { - strategyId: args.strategyId - } - }) - - return { - operation: generateSuccess('TFA setup started'), - continuationToken: tfaToken, - tfaQRImage - } - } catch (err) { - return generateError(err) - } - }, - /** - * Deactivate 2FA - */ - async deactivateTFA (obj, args, context) { - try { - const userId = context.req.user?.id - if (!userId) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - - const usr = await WIKI.db.users.query().findById(userId) - if (!usr) { - throw new Error('ERR_INVALID_USER') - } - - const str = WIKI.auth.strategies[args.strategyId] - if (!str) { - throw new Error('ERR_INVALID_STRATEGY') - } - - if (!usr.auth[args.strategyId]) { - throw new Error('ERR_INVALID_STRATEGY') - } - - if (!usr.auth[args.strategyId].tfaIsActive) { - throw new Error('ERR_TFA_NOT_ACTIVE') - } - - usr.auth[args.strategyId].tfaIsActive = false - usr.auth[args.strategyId].tfaSecret = null - - await usr.$query().patch({ - auth: usr.auth - }) - - return { - operation: generateSuccess('TFA deactivated successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Setup Passkey - */ - async setupPasskey (obj, args, context) { - try { - const userId = context.req.user?.id - if (!userId) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - - const usr = await WIKI.db.users.query().findById(userId) - if (!usr) { - throw new Error('ERR_INVALID_USER') - } - - const site = WIKI.sites[args.siteId] - if (!site) { - throw new Error('ERR_INVALID_SITE') - } else if (site.hostname === '*') { - WIKI.logger.warn('Cannot use passkeys with a wildcard site hostname. Enter a valid hostname under the Administration Area > General.') - throw new Error('ERR_PK_HOSTNAME_MISSING') - } - - const options = await generateRegistrationOptions({ - rpName: site.config.title, - rpId: site.hostname, - userID: usr.id, - userName: usr.email, - userDisplayName: usr.name, - attestationType: 'none', - authenticatorSelection: { - residentKey: 'required', - userVerification: 'preferred' - }, - excludeCredentials: usr.passkeys.authenticators?.map(authenticator => ({ - id: isoBase64URL.fromBuffer(new Uint8Array(authenticator.credentialID)), - type: 'public-key', - transports: authenticator.transports - })) ?? [] - }) - - usr.passkeys.reg = { - challenge: options.challenge, - rpId: site.hostname, - siteId: site.id - } - - await usr.$query().patch({ - passkeys: usr.passkeys - }) - - return { - operation: generateSuccess('Passkey registration options generated successfully.'), - registrationOptions: options - } - } catch (err) { - return generateError(err) - } - }, - /** - * Finalize Passkey Registration - */ - async finalizePasskey (obj, args, context) { - try { - const userId = context.req.user?.id - if (!userId) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - - const usr = await WIKI.db.users.query().findById(userId) - if (!usr) { - throw new Error('ERR_INVALID_USER') - } else if (!usr.passkeys?.reg) { - throw new Error('ERR_PASSKEY_NOT_SETUP') - } - - if (!args.name || args.name.trim().length < 1 || args.name.length > 255) { - throw new Error('ERR_PK_NAME_MISSING_OR_INVALID') - } - - const verification = await verifyRegistrationResponse({ - response: args.registrationResponse, - expectedChallenge: usr.passkeys.reg.challenge, - expectedOrigin: `https://${usr.passkeys.reg.rpId}`, - expectedRPID: usr.passkeys.reg.rpId, - requireUserVerification: true - }) - - if (!verification.verified) { - throw new Error('ERR_PK_VERIFICATION_FAILED') - } - - if (!usr.passkeys.authenticators) { - usr.passkeys.authenticators = [] - } - usr.passkeys.authenticators.push({ - ...verification.registrationInfo, - id: base64.fromArrayBuffer(verification.registrationInfo.credentialID, true), - createdAt: new Date(), - name: args.name, - siteId: usr.passkeys.reg.siteId, - transports: args.registrationResponse.response.transports - }) - - delete usr.passkeys.reg - - await usr.$query().patch({ - passkeys: JSON.stringify(usr.passkeys, (k, v) => { - if (v instanceof Uint8Array) { - return Array.apply([], v) - } - return v - }) - }) - - return { - operation: generateSuccess('Passkey registered successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Deactivate a passkey - */ - async deactivatePasskey (obj, args, context) { - try { - const userId = context.req.user?.id - if (!userId) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - - const usr = await WIKI.db.users.query().findById(userId) - if (!usr) { - throw new Error('ERR_INVALID_USER') - } else if (!usr.passkeys?.authenticators) { - throw new Error('ERR_PASSKEY_NOT_SETUP') - } - - usr.passkeys.authenticators = usr.passkeys.authenticators.filter(a => a.id !== args.id) - - await usr.$query().patch({ - passkeys: usr.passkeys - }) - - return { - operation: generateSuccess('Passkey deactivated successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Login via passkey - Generate challenge - */ - async authenticatePasskeyGenerate (obj, args, context) { - try { - const site = WIKI.sites[args.siteId] - if (!site) { - throw new Error('ERR_INVALID_SITE') - } else if (site.hostname === '*') { - WIKI.logger.warn('Cannot use passkeys with a wildcard site hostname. Enter a valid hostname under the Administration Area > General.') - throw new Error('ERR_PK_HOSTNAME_MISSING') - } - - const usr = await WIKI.db.users.query().findOne({ email: args.email }) - if (!usr || !usr.passkeys?.authenticators) { - // Fake success response to prevent email leaking - WIKI.logger.debug(`Cannot generate passkey challenge for ${args.email}... (non-existing or missing passkeys setup)`) - return { - operation: generateSuccess('Passkey challenge generated.'), - authOptions: await generateAuthenticationOptions({ - allowCredentials: [{ - id: new Uint8Array(Array(30).map(v => _.random(0, 254))), - type: 'public-key', - transports: ['internal'] - }], - userVerification: 'preferred', - rpId: site.hostname - }) - } - } - - const options = await generateAuthenticationOptions({ - allowCredentials: usr.passkeys.authenticators.map(authenticator => ({ - id: new Uint8Array(authenticator.credentialID), - type: 'public-key', - transports: authenticator.transports - })), - userVerification: 'preferred', - rpId: site.hostname - }) - - usr.passkeys.login = { - challenge: options.challenge, - rpId: site.hostname, - siteId: site.id - } - - await usr.$query().patch({ - passkeys: usr.passkeys - }) - - return { - operation: generateSuccess('Passkey challenge generated.'), - authOptions: options - } - } catch (err) { - return generateError(err) - } - }, - /** - * Login via passkey - Verify challenge - */ - async authenticatePasskeyVerify (obj, args, context) { - try { - if (!args.authResponse?.response?.userHandle) { - throw new Error('ERR_INVALID_PASSKEY_RESPONSE') - } - const usr = await WIKI.db.users.query().findById(args.authResponse.response.userHandle) - if (!usr) { - WIKI.logger.debug(`Passkey Login Failure: Cannot find user ${args.authResponse.response.userHandle}`) - throw new Error('ERR_LOGIN_FAILED') - } else if (!usr.passkeys?.login) { - WIKI.logger.debug(`Passkey Login Failure: Missing login auth generation step for user ${args.authResponse.response.userHandle}`) - throw new Error('ERR_LOGIN_FAILED') - } else if (!usr.passkeys.authenticators?.some(a => a.id === args.authResponse.id)) { - WIKI.logger.debug(`Passkey Login Failure: Authenticator provided is not registered for user ${args.authResponse.response.userHandle}`) - throw new Error('ERR_LOGIN_FAILED') - } - - const verification = await verifyAuthenticationResponse({ - response: args.authResponse, - expectedChallenge: usr.passkeys.login.challenge, - expectedOrigin: `https://${usr.passkeys.login.rpId}`, - expectedRPID: usr.passkeys.login.rpId, - requireUserVerification: true, - authenticator: _.find(usr.passkeys.authenticators, ['id', args.authResponse.id]) - }) - - if (!verification.verified) { - WIKI.logger.debug(`Passkey Login Failure: Challenge verification failed for user ${args.authResponse.response.userHandle}`) - throw new Error('ERR_LOGIN_FAILED') - } - - delete usr.passkeys.login - - await usr.$query().patch({ - passkeys: usr.passkeys - }) - - const jwtToken = await WIKI.db.users.refreshToken(usr) - - return { - operation: generateSuccess('Passkey challenge accepted.'), - nextAction: 'redirect', - jwt: jwtToken.token, - redirect: '/' - } - } catch (err) { - return generateError(err) - } - }, - /** - * Perform Password Change - */ - async changePassword (obj, args, context) { - try { - if (args.continuationToken) { - const authResult = await WIKI.db.users.loginChangePassword(args, context) - return { - ...authResult, - operation: generateSuccess('Password set successfully') - } - } else { - await WIKI.db.users.changePassword(args, context) - return { - operation: generateSuccess('Password changed successfully') - } - } - } catch (err) { - WIKI.logger.debug(err) - return generateError(err) - } - }, - /** - * Perform Forget Password - */ - async forgotPassword (obj, args, context) { - try { - await WIKI.db.users.loginForgotPassword(args, context) - return { - operation: generateSuccess('Password reset request processed.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Register a new account - */ - async register (obj, args, context) { - try { - const usr = await WIKI.db.users.createNewUser({ ...args, userInitiated: true }) - const authResult = await WIKI.db.users.afterLoginChecks(usr, WIKI.data.systemIds.localAuthId, context) - return { - ...authResult, - operation: generateSuccess('Registration success') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Refresh Token - */ - async refreshToken (obj, args, context) { - try { - let decoded = {} - if (!args.token) { - throw new Error('ERR_MISSING_TOKEN') - } - try { - decoded = jwt.verify(args.token, WIKI.config.auth.certs.public, { - audience: WIKI.config.auth.audience, - issuer: 'urn:wiki.js', - algorithms: ['RS256'], - ignoreExpiration: true - }) - } catch (err) { - throw new Error('ERR_INVALID_TOKEN') - } - if (DateTime.utc().minus(ms(WIKI.config.auth.tokenRenewal)) > DateTime.fromSeconds(decoded.exp)) { - throw new Error('ERR_EXPIRED_TOKEN') - } - const newToken = await WIKI.db.users.refreshToken(decoded.id) - return { - jwt: newToken.token, - operation: generateSuccess('Token refreshed successfully') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Set API state - */ - async setApiState (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.config.api.isEnabled = args.enabled - await WIKI.configSvc.saveToDb(['api']) - return { - operation: generateSuccess('API State changed successfully') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Revoke an API key - */ - async revokeApiKey (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:api'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.apiKeys.query().findById(args.id).patch({ - isRevoked: true - }) - await WIKI.auth.reloadApiKeys() - WIKI.events.outbound.emit('reloadApiKeys') - return { - operation: generateSuccess('API Key revoked successfully') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Update Authentication Strategies - */ - async updateAuthStrategies (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - const previousStrategies = await WIKI.db.authentication.getStrategies() - for (const str of args.strategies) { - const newStr = { - displayName: str.displayName, - isEnabled: str.isEnabled, - config: _.reduce(str.config, (result, value, key) => { - _.set(result, `${value.key}`, _.get(JSON.parse(value.value), 'v', null)) - return result - }, {}), - selfRegistration: str.selfRegistration, - domainWhitelist: { v: str.domainWhitelist }, - autoEnrollGroups: { v: str.autoEnrollGroups } - } - - if (_.some(previousStrategies, ['key', str.key])) { - await WIKI.db.authentication.query().patch({ - key: str.key, - strategyKey: str.strategyKey, - ...newStr - }).where('key', str.key) - } else { - await WIKI.db.authentication.query().insert({ - key: str.key, - strategyKey: str.strategyKey, - ...newStr - }) - } - } - - for (const str of _.differenceBy(previousStrategies, args.strategies, 'key')) { - const hasUsers = await WIKI.db.users.query().count('* as total').where({ providerKey: str.key }).first() - if (_.toSafeInteger(hasUsers.total) > 0) { - throw new Error(`Cannot delete ${str.displayName} as 1 or more users are still using it.`) - } else { - await WIKI.db.authentication.query().delete().where('key', str.key) - } - } - - await WIKI.auth.activateStrategies() - WIKI.events.outbound.emit('reloadAuthStrategies') - return { - responseResult: generateSuccess('Strategies updated successfully') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Generate New Authentication Public / Private Key Certificates - */ - async regenerateCertificates (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.auth.regenerateCertificates() - return { - responseResult: generateSuccess('Certificates have been regenerated successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Reset Guest User - */ - async resetGuestUser (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.auth.resetGuestUser() - return { - responseResult: generateSuccess('Guest user has been reset successfully.') - } - } catch (err) { - return generateError(err) - } - } - }, - // ------------------------------------------------------------------ - // TYPE: AuthenticationActiveStrategy - // ------------------------------------------------------------------ - AuthenticationActiveStrategy: { - config (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - return obj.config ?? {} - }, - allowedEmailRegex (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - return obj.allowedEmailRegex ?? '' - }, - autoEnrollGroups (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - return obj.autoEnrollGroups ?? [] - }, - strategy (obj, args, context) { - return _.find(WIKI.data.authentication, ['key', obj.module]) - } - } -} diff --git a/server/graph/resolvers/block.mjs b/server/graph/resolvers/block.mjs deleted file mode 100644 index 48bd91e3b..000000000 --- a/server/graph/resolvers/block.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import { generateError, generateSuccess } from '../../helpers/graph.mjs' - -export default { - Query: { - async blocks (obj, args, context) { - return WIKI.db.blocks.query().where({ - siteId: args.siteId - }) - } - }, - Mutation: { - async setBlocksState(obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:blocks'])) { - throw new Error('ERR_FORBIDDEN') - } - // TODO: update blocks state - return { - operation: generateSuccess('Blocks state updated successfully') - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/comment.mjs b/server/graph/resolvers/comment.mjs deleted file mode 100644 index d9831c4f8..000000000 --- a/server/graph/resolvers/comment.mjs +++ /dev/null @@ -1,166 +0,0 @@ -import _ from 'lodash-es' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' - -export default { - Query: { - /** - * Fetch list of Comments Providers - */ - async commentsProviders(obj, args, context, info) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - const providers = await WIKI.db.commentProviders.getProviders() - return providers.map(provider => { - const providerInfo = _.find(WIKI.data.commentProviders, ['key', provider.key]) || {} - return { - ...providerInfo, - ...provider, - config: _.sortBy(_.transform(provider.config, (res, value, key) => { - const configData = _.get(providerInfo.props, key, false) - if (configData) { - res.push({ - key, - value: JSON.stringify({ - ...configData, - value - }) - }) - } - }, []), 'key') - } - }) - }, - /** - * Fetch list of comments for a page - */ - async comments (obj, args, context) { - const page = await WIKI.db.pages.query().select('id').findOne({ locale: args.locale, path: args.path }) - if (page) { - if (WIKI.auth.checkAccess(context.req.user, ['read:comments'], args)) { - const comments = await WIKI.db.comments.query().where('pageId', page.id).orderBy('createdAt') - return comments.map(c => ({ - ...c, - authorName: c.name, - authorEmail: c.email, - authorIP: c.ip - })) - } else { - throw new WIKI.Error.CommentViewForbidden() - } - } else { - return [] - } - }, - /** - * Fetch a single comment - */ - async commentById (obj, args, context) { - const cm = await WIKI.data.commentProvider.getCommentById(args.id) - if (!cm || !cm.pageId) { - throw new WIKI.Error.CommentNotFound() - } - const page = await WIKI.db.pages.query().select('locale', 'path').findById(cm.pageId) - if (page) { - if (WIKI.auth.checkAccess(context.req.user, ['read:comments'], { - path: page.path, - locale: page.locale - })) { - return { - ...cm, - authorName: cm.name, - authorEmail: cm.email, - authorIP: cm.ip - } - } else { - throw new WIKI.Error.CommentViewForbidden() - } - } else { - WIKI.logger.warn(`Comment #${cm.id} is linked to a page #${cm.pageId} that doesn't exist! [ERROR]`) - throw new WIKI.Error.CommentGenericError() - } - } - }, - Mutation: { - /** - * Create New Comment - */ - async createComment (obj, args, context) { - try { - const cmId = await WIKI.db.comments.postNewComment({ - ...args, - user: context.req.user, - ip: context.req.ip - }) - return { - responseResult: generateSuccess('New comment posted successfully'), - id: cmId - } - } catch (err) { - return generateError(err) - } - }, - /** - * Update an Existing Comment - */ - async updateComment (obj, args, context) { - try { - const cmRender = await WIKI.db.comments.updateComment({ - ...args, - user: context.req.user, - ip: context.req.ip - }) - return { - responseResult: generateSuccess('Comment updated successfully'), - render: cmRender - } - } catch (err) { - return generateError(err) - } - }, - /** - * Delete an Existing Comment - */ - async deleteComment (obj, args, context) { - try { - await WIKI.db.comments.deleteComment({ - id: args.id, - user: context.req.user, - ip: context.req.ip - }) - return { - responseResult: generateSuccess('Comment deleted successfully') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Update Comments Providers - */ - async updateCommentsProviders(obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - for (let provider of args.providers) { - await WIKI.db.commentProviders.query().patch({ - isEnabled: provider.isEnabled, - config: _.reduce(provider.config, (result, value, key) => { - _.set(result, `${value.key}`, _.get(JSON.parse(value.value), 'v', null)) - return result - }, {}) - }).where('key', provider.key) - } - await WIKI.db.commentProviders.initProvider() - return { - responseResult: generateSuccess('Comment Providers updated successfully') - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/group.mjs b/server/graph/resolvers/group.mjs deleted file mode 100644 index 9b97edcd0..000000000 --- a/server/graph/resolvers/group.mjs +++ /dev/null @@ -1,231 +0,0 @@ -import { generateSuccess } from '../../helpers/graph.mjs' -import safeRegex from 'safe-regex' -import _ from 'lodash-es' -import { v4 as uuid } from 'uuid' - -export default { - Query: { - /** - * FETCH ALL GROUPS - */ - async groups (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:groups', 'manage:users', 'manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - return WIKI.db.groups.query().select( - 'groups.*', - WIKI.db.groups.relatedQuery('users').count().as('userCount') - ) - }, - /** - * FETCH A SINGLE GROUP - */ - async groupById(obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:groups', 'manage:users', 'manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - return WIKI.db.groups.query().findById(args.id) - } - }, - Mutation: { - /** - * ASSIGN USER TO GROUP - */ - async assignUserToGroup (obj, args, { req }) { - if (!WIKI.auth.checkAccess(req.user, ['manage:groups', 'manage:users', 'manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - // Check for guest user - if (args.userId === WIKI.config.auth.guestUserId) { - throw new Error('Cannot assign the Guest user to a group.') - } - - // Check for valid group - const grp = await WIKI.db.groups.query().findById(args.groupId) - if (!grp) { - throw new Error('Invalid Group ID') - } - - // Check assigned permissions for write:groups - if ( - WIKI.auth.checkExclusiveAccess(req.user, ['write:groups'], ['manage:groups', 'manage:system']) && - grp.permissions.some(p => { - const resType = _.last(p.split(':')) - return ['users', 'groups', 'navigation', 'theme', 'api', 'system'].includes(resType) - }) - ) { - throw new Error('You are not authorized to assign a user to this elevated group.') - } - - // Check for valid user - const usr = await WIKI.db.users.query().findById(args.userId) - if (!usr) { - throw new Error('Invalid User ID') - } - - // Check for existing relation - const relExist = await WIKI.db.knex('userGroups').where({ - userId: args.userId, - groupId: args.groupId - }).first() - if (relExist) { - throw new Error('User is already assigned to group.') - } - - // Assign user to group - await grp.$relatedQuery('users').relate(usr.id) - - // Revoke tokens for this user - WIKI.auth.revokeUserTokens({ id: usr.id, kind: 'u' }) - WIKI.events.outbound.emit('addAuthRevoke', { id: usr.id, kind: 'u' }) - - return { - operation: generateSuccess('User has been assigned to group.') - } - }, - /** - * CREATE NEW GROUP - */ - async createGroup (obj, args, { req }) { - if (!WIKI.auth.checkAccess(req.user, ['manage:groups', 'manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - const group = await WIKI.db.groups.query().insertAndFetch({ - name: args.name, - permissions: JSON.stringify(WIKI.data.groups.defaultPermissions), - rules: JSON.stringify(WIKI.data.groups.defaultRules.map(r => ({ - id: uuid(), - ...r - }))), - isSystem: false - }) - await WIKI.auth.reloadGroups() - WIKI.events.outbound.emit('reloadGroups') - return { - operation: generateSuccess('Group created successfully.'), - group - } - }, - /** - * DELETE GROUP - */ - async deleteGroup (obj, args, { req }) { - if (!WIKI.auth.checkAccess(req.user, ['manage:groups', 'manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - if (args.id === WIKI.data.systemIds.guestsGroupId || args.id === WIKI.data.systemIds.usersGroupId || args.id === WIKI.config.auth.rootAdminGroupId) { - throw new Error('Cannot delete this group.') - } - - await WIKI.db.groups.query().deleteById(args.id) - - WIKI.auth.revokeUserTokens({ id: args.id, kind: 'g' }) - WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'g' }) - - await WIKI.auth.reloadGroups() - WIKI.events.outbound.emit('reloadGroups') - - return { - operation: generateSuccess('Group has been deleted.') - } - }, - /** - * UNASSIGN USER FROM GROUP - */ - async unassignUserFromGroup (obj, args, { req }) { - if (!WIKI.auth.checkAccess(req.user, ['manage:groups', 'manage:users', 'manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - if (args.userId === 2) { - throw new Error('Cannot unassign Guest user') - } - if (args.userId === WIKI.config.auth.guestUserId && args.groupId === WIKI.data.systemIds.guestsGroupId) { - throw new Error('Cannot unassign Administrator user from Administrators group.') - } - const grp = await WIKI.db.groups.query().findById(args.groupId) - if (!grp) { - throw new Error('Invalid Group ID') - } - const usr = await WIKI.db.users.query().findById(args.userId) - if (!usr) { - throw new Error('Invalid User ID') - } - await grp.$relatedQuery('users').unrelate().where('userId', usr.id) - - WIKI.auth.revokeUserTokens({ id: usr.id, kind: 'u' }) - WIKI.events.outbound.emit('addAuthRevoke', { id: usr.id, kind: 'u' }) - - return { - operation: generateSuccess('User has been unassigned from group.') - } - }, - /** - * UPDATE GROUP - */ - async updateGroup (obj, args, { req }) { - if (!WIKI.auth.checkAccess(req.user, ['manage:groups', 'manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - // Check for unsafe regex page rules - if (_.some(args.pageRules, pr => { - return pr.match === 'REGEX' && !safeRegex(pr.path) - })) { - throw new Error('Some Page Rules contains unsafe or exponential time regex.') - } - - // Set default redirect on login value - if (_.isEmpty(args.redirectOnLogin)) { - args.redirectOnLogin = '/' - } - - // Check assigned permissions for write:groups - if ( - WIKI.auth.checkExclusiveAccess(req.user, ['write:groups'], ['manage:groups', 'manage:system']) && - args.permissions.some(p => { - const resType = _.last(p.split(':')) - return ['users', 'groups', 'navigation', 'theme', 'api', 'system'].includes(resType) - }) - ) { - throw new Error('You are not authorized to manage this group or assign these permissions.') - } - - // Check assigned permissions for manage:groups - if ( - WIKI.auth.checkExclusiveAccess(req.user, ['manage:groups'], ['manage:system']) && - args.permissions.some(p => _.last(p.split(':')) === 'system') - ) { - throw new Error('You are not authorized to manage this group or assign the manage:system permissions.') - } - - // Update group - await WIKI.db.groups.query().patch({ - name: args.name, - redirectOnLogin: args.redirectOnLogin, - permissions: JSON.stringify(args.permissions), - pageRules: JSON.stringify(args.pageRules) - }).where('id', args.id) - - // Revoke tokens for this group - WIKI.auth.revokeUserTokens({ id: args.id, kind: 'g' }) - WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'g' }) - - // Reload group permissions - await WIKI.auth.reloadGroups() - WIKI.events.outbound.emit('reloadGroups') - - return { - operation: generateSuccess('Group has been updated.') - } - } - }, - Group: { - users (grp) { - return grp.$relatedQuery('users') - } - } -} diff --git a/server/graph/resolvers/hooks.mjs b/server/graph/resolvers/hooks.mjs deleted file mode 100644 index 21cd99b69..000000000 --- a/server/graph/resolvers/hooks.mjs +++ /dev/null @@ -1,107 +0,0 @@ -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import _ from 'lodash-es' - -export default { - Query: { - async hooks (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:webhooks', 'write:webhooks', 'manage:webhooks'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.db.hooks.query().orderBy('name') - }, - async hookById (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:webhooks', 'write:webhooks', 'manage:webhooks'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.db.hooks.query().findById(args.id) - } - }, - Mutation: { - /** - * CREATE HOOK - */ - async createHook (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['write:webhooks', 'manage:webhooks'])) { - throw new Error('ERR_FORBIDDEN') - } - - // -> Validate inputs - if (!args.name || args.name.length < 1) { - throw new WIKI.Error.Custom('HookCreateInvalidName', 'Invalid Hook Name') - } - if (!args.events || args.events.length < 1) { - throw new WIKI.Error.Custom('HookCreateInvalidEvents', 'Invalid Hook Events') - } - if (!args.url || args.url.length < 8 || !args.url.startsWith('http')) { - throw new WIKI.Error.Custom('HookCreateInvalidURL', 'Invalid Hook URL') - } - // -> Create hook - const newHook = await WIKI.db.hooks.createHook(args) - WIKI.logger.debug(`New Hook ${newHook.id} created successfully.`) - - return { - operation: generateSuccess('Hook created successfully'), - hook: newHook - } - } catch (err) { - return generateError(err) - } - }, - /** - * UPDATE HOOK - */ - async updateHook (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:webhooks'])) { - throw new Error('ERR_FORBIDDEN') - } - - // -> Load hook - const hook = await WIKI.db.hooks.query().findById(args.id) - if (!hook) { - throw new WIKI.Error.Custom('HookInvalidId', 'Invalid Hook ID') - } - // -> Check for bad input - if (_.has(args.patch, 'name') && args.patch.name.length < 1) { - throw new WIKI.Error.Custom('HookCreateInvalidName', 'Invalid Hook Name') - } - if (_.has(args.patch, 'events') && args.patch.events.length < 1) { - throw new WIKI.Error.Custom('HookCreateInvalidEvents', 'Invalid Hook Events') - } - if (_.has(args.patch, 'url') && (_.trim(args.patch.url).length < 8 || !args.patch.url.startsWith('http'))) { - throw new WIKI.Error.Custom('HookInvalidURL', 'URL is invalid.') - } - // -> Update hook - await WIKI.db.hooks.query().findById(args.id).patch(args.patch) - WIKI.logger.debug(`Hook ${args.id} updated successfully.`) - - return { - operation: generateSuccess('Hook updated successfully') - } - } catch (err) { - return generateError(err) - } - }, - /** - * DELETE HOOK - */ - async deleteHook (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:webhooks'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.hooks.deleteHook(args.id) - WIKI.logger.debug(`Hook ${args.id} deleted successfully.`) - return { - operation: generateSuccess('Hook deleted successfully') - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/localization.mjs b/server/graph/resolvers/localization.mjs deleted file mode 100644 index 49f1d9780..000000000 --- a/server/graph/resolvers/localization.mjs +++ /dev/null @@ -1,10 +0,0 @@ -export default { - Query: { - async locales(obj, args, context, info) { - return WIKI.db.locales.getLocales({ cache: false }) - }, - localeStrings (obj, args, context, info) { - return WIKI.db.locales.getStrings(args.locale) - } - } -} diff --git a/server/graph/resolvers/mail.mjs b/server/graph/resolvers/mail.mjs deleted file mode 100644 index 664380280..000000000 --- a/server/graph/resolvers/mail.mjs +++ /dev/null @@ -1,78 +0,0 @@ -import _ from 'lodash-es' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import { withoutTrailingSlash } from 'ufo' - -export default { - Query: { - async mailConfig(obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - return { - ...WIKI.config.mail, - pass: WIKI.config.mail.pass.length > 0 ? '********' : '' - } - } - }, - Mutation: { - async sendMailTest(obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - if (_.isEmpty(args.recipientEmail) || args.recipientEmail.length < 6) { - throw new Error('ERR_MAIL_INVALID_RECIPIENT') - } - - await WIKI.mail.send({ - template: 'Test', - to: args.recipientEmail, - subject: 'A test email from your wiki', - text: 'This is a test email sent from your wiki.', - data: {} - }) - - return { - operation: generateSuccess('Test email sent successfully.') - } - } catch (err) { - return generateError(err) - } - }, - async updateMailConfig(obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.config.mail = { - senderName: args.senderName, - senderEmail: args.senderEmail, - defaultBaseURL: withoutTrailingSlash(args.defaultBaseURL), - host: args.host, - port: args.port, - name: args.name, - secure: args.secure, - verifySSL: args.verifySSL, - user: args.user, - pass: (args.pass === '********') ? WIKI.config.mail.pass : args.pass, - useDKIM: args.useDKIM, - dkimDomainName: args.dkimDomainName, - dkimKeySelector: args.dkimKeySelector, - dkimPrivateKey: args.dkimPrivateKey - } - await WIKI.configSvc.saveToDb(['mail']) - - WIKI.mail.init() - - return { - operation: generateSuccess('Mail configuration updated successfully.') - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/navigation.mjs b/server/graph/resolvers/navigation.mjs deleted file mode 100644 index 9dd880fe0..000000000 --- a/server/graph/resolvers/navigation.mjs +++ /dev/null @@ -1,131 +0,0 @@ -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import { isNil } from 'lodash-es' - -export default { - Query: { - async navigationById (obj, args, context, info) { - return WIKI.db.navigation.getNav({ id: args.id, cache: true, userGroups: context.req.user?.groups }) - } - }, - Mutation: { - async updateNavigation (obj, args, context) { - try { - let updateInherited = false - let updateInheritedNavId = null - let updateNavId = null - let ancestorNavId = null - - const treeEntry = await WIKI.db.knex('tree').where('id', args.pageId).first() - if (!treeEntry) { - throw new Error('Invalid ID') - } - const currentNavId = treeEntry.folderPath === '' && treeEntry.fileName === 'home' ? treeEntry.siteId : treeEntry.id - const treeEntryPath = treeEntry.folderPath ? `${treeEntry.folderPath}.${treeEntry.fileName}` : treeEntry.fileName - - // -> Create / Update Nav Menu Items - if (!isNil(args.items)) { - await WIKI.db.knex('navigation').insert({ - id: currentNavId, - items: JSON.stringify(args.items), - siteId: treeEntry.siteId - }).onConflict('id').merge({ - items: JSON.stringify(args.items) - }) - } - - // -> Find ancestor nav ID - const ancNavResult = await WIKI.db.knex.raw(` - SELECT "navigationId", "navigationMode", nlevel("folderPath" || "fileName") AS levels - FROM tree - WHERE ("folderPath" || "fileName") @> :currentPath - AND "navigationMode" IN ('override', 'hide') - ORDER BY levels DESC - LIMIT 1 - `, { - currentPath: treeEntry.folderPath - }) - if (ancNavResult.rowCount > 0) { - ancestorNavId = ancNavResult.rows[0]?.navigationId - } else { - ancestorNavId = treeEntry.siteId - } - - // -> Update mode - switch (args.mode) { - case 'inherit': { - updateNavId = ancestorNavId - if (['override', 'hide'].includes(treeEntry.navigationMode)) { - updateInherited = true - updateInheritedNavId = ancestorNavId - } - break - } - case 'override': { - updateNavId = treeEntry.id - updateInherited = true - updateInheritedNavId = treeEntry.id - break - } - case 'overrideExact': { - updateNavId = treeEntry.id - if (['override', 'hide'].includes(treeEntry.navigationMode)) { - updateInherited = true - updateInheritedNavId = ancestorNavId - } - break - } - case 'hide': { - updateInherited = true - updateNavId = null - break - } - case 'hideExact': { - updateNavId = null - if (['override', 'hide'].includes(treeEntry.navigationMode)) { - updateInherited = true - updateInheritedNavId = ancestorNavId - } - break - } - } - - // -> Set for current path - await WIKI.db.knex('tree').where('id', treeEntry.id).update({ navigationMode: args.mode, navigationId: updateNavId }) - - // -> Update nodes that inherit from current - if (updateInherited) { - await WIKI.db.knex.raw(` - UPDATE tree tt - SET "navigationId" = :navId - WHERE type IN ('page', 'folder') - AND "folderPath" <@ :overridePath - AND "navigationMode" = 'inherit' - AND NOT EXISTS ( - SELECT 1 - FROM tree tc - WHERE type IN ('page', 'folder') - AND tc."folderPath" <@ :overridePath - AND tc."folderPath" @> tt."folderPath" - AND tc."navigationMode" IN ('override', 'hide') - ) - `, { - navId: updateInheritedNavId, - overridePath: treeEntryPath - }) - } - - // for (const tree of args.tree) { - // await WIKI.cache.set(`nav:sidebar:${tree.locale}`, tree.items, 300) - // } - - return { - operation: generateSuccess('Navigation updated successfully'), - navigationMode: args.mode, - navigationId: updateNavId - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/page.mjs b/server/graph/resolvers/page.mjs deleted file mode 100644 index 80909ef18..000000000 --- a/server/graph/resolvers/page.mjs +++ /dev/null @@ -1,709 +0,0 @@ -import _ from 'lodash-es' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import { parsePath } from '../../helpers/page.mjs' -import tsquery from 'pg-tsquery' - -const tsq = tsquery() -const tagsInQueryRgx = /#[a-z0-9-\u3400-\u4DBF\u4E00-\u9FFF]+(?=(?:[^"]*(?:")[^"]*(?:"))*[^"]*$)/g - -export default { - Query: { - /** - * PAGE HISTORY - */ - async pageHistoryById (obj, args, context, info) { - const page = await WIKI.db.pages.query().select('path', 'locale').findById(args.id) - if (WIKI.auth.checkAccess(context.req.user, ['read:history'], { - path: page.path, - locale: page.locale - })) { - return WIKI.db.pageHistory.getHistory({ - pageId: args.id, - offsetPage: args.offsetPage || 0, - offsetSize: args.offsetSize || 100 - }) - } else { - throw new WIKI.Error.PageHistoryForbidden() - } - }, - /** - * PAGE VERSION - */ - async pageVersionById (obj, args, context, info) { - const page = await WIKI.db.pages.query().select('path', 'locale').findById(args.pageId) - if (WIKI.auth.checkAccess(context.req.user, ['read:history'], { - path: page.path, - locale: page.locale - })) { - return WIKI.db.pageHistory.getVersion({ - pageId: args.pageId, - versionId: args.versionId - }) - } else { - throw new WIKI.Error.PageHistoryForbidden() - } - }, - /** - * SEARCH PAGES - */ - async searchPages (obj, args, context) { - const q = args.query.trim() - const hasQuery = q.length > 0 - - // -> Validate parameters - if (!args.siteId) { - throw new Error('Missing Site ID') - } - if (args.offset && args.offset < 0) { - throw new Error('Invalid offset value.') - } - if (args.limit && (args.limit < 1 || args.limit > 100)) { - throw new Error('Limit must be between 1 and 100.') - } - - try { - const dictName = 'english' // TODO: Use provided locale or fallback on site locale - - // -> Select Columns - const searchCols = [ - 'id', - 'path', - 'locale', - 'title', - 'description', - 'icon', - 'tags', - 'updatedAt', - WIKI.db.knex.raw('count(*) OVER() AS total') - ] - - // -> Set relevancy - if (hasQuery) { - searchCols.push(WIKI.db.knex.raw('ts_rank_cd(ts, query) AS relevancy')) - } else { - args.orderBy = args.orderBy === 'relevancy' ? 'title' : args.orderBy - } - - // -> Add Highlighting if enabled - if (WIKI.config.search.termHighlighting && hasQuery) { - searchCols.push(WIKI.db.knex.raw('ts_headline(?, "searchContent", query, \'MaxWords=5, MinWords=3, MaxFragments=5\') AS highlight', [dictName])) - } - - const results = await WIKI.db.knex - .select(searchCols) - .fromRaw(hasQuery ? 'pages, to_tsquery(?, ?) query' : 'pages', hasQuery ? [dictName, tsq(q)] : []) - .where('siteId', args.siteId) - .where('isSearchableComputed', true) - .where(builder => { - if (args.path) { - builder.where('path', 'ILIKE', `${args.path}%`) - } - if (args.locale?.length > 0) { - builder.whereIn('locale', args.locale) - } - if (args.editor) { - builder.where('editor', args.editor) - } - if (args.publishState) { - builder.where('publishState', args.publishState) - } - if (args.tags) { - builder.where('tags', '@>', args.tags) - } - if (hasQuery) { - builder.whereRaw('query @@ ts') - } - }) - .orderBy(args.orderBy || 'relevancy', args.orderByDirection || 'desc') - .offset(args.offset || 0) - .limit(args.limit || 25) - - // -> Remove highlights without matches - if (WIKI.config.search.termHighlighting && hasQuery) { - for (const r of results) { - if (r.highlight?.indexOf('') < 0) { - r.highlight = null - } - } - } - - return { - results, - totalHits: results?.length > 0 ? results[0].total : 0 - } - } catch (err) { - WIKI.logger.warn(`Search Query Error: ${err.message}`) - throw err - } - }, - /** - * LIST PAGES - */ - async pages (obj, args, context, info) { - let results = await WIKI.db.pages.query().column([ - 'pages.id', - 'path', - 'locale', - 'title', - 'description', - 'isPublished', - 'isPrivate', - 'privateNS', - 'contentType', - 'createdAt', - 'updatedAt' - ]) - .withGraphJoined('tags') - .modifyGraph('tags', builder => { - builder.select('tag') - }) - .modify(queryBuilder => { - if (args.limit) { - queryBuilder.limit(args.limit) - } - if (args.locale) { - queryBuilder.where('locale', args.locale) - } - if (args.creatorId && args.authorId && args.creatorId > 0 && args.authorId > 0) { - queryBuilder.where(function () { - this.where('creatorId', args.creatorId).orWhere('authorId', args.authorId) - }) - } else { - if (args.creatorId && args.creatorId > 0) { - queryBuilder.where('creatorId', args.creatorId) - } - if (args.authorId && args.authorId > 0) { - queryBuilder.where('authorId', args.authorId) - } - } - if (args.tags && args.tags.length > 0) { - queryBuilder.whereIn('tags.tag', args.tags.map(t => _.trim(t).toLowerCase())) - } - const orderDir = args.orderByDirection === 'DESC' ? 'desc' : 'asc' - switch (args.orderBy) { - case 'CREATED': - queryBuilder.orderBy('createdAt', orderDir) - break - case 'PATH': - queryBuilder.orderBy('path', orderDir) - break - case 'TITLE': - queryBuilder.orderBy('title', orderDir) - break - case 'UPDATED': - queryBuilder.orderBy('updatedAt', orderDir) - break - default: - queryBuilder.orderBy('pages.id', orderDir) - break - } - }) - results = _.filter(results, r => { - return WIKI.auth.checkAccess(context.req.user, ['read:pages'], { - path: r.path, - locale: r.locale - }) - }).map(r => ({ - ...r, - tags: _.map(r.tags, 'tag') - })) - if (args.tags && args.tags.length > 0) { - results = _.filter(results, r => _.every(args.tags, t => _.includes(r.tags, t))) - } - return results - }, - /** - * FETCH SINGLE PAGE BY ID - */ - async pageById (obj, args, context, info) { - const page = await WIKI.db.pages.getPageFromDb(args.id) - if (page) { - if (WIKI.auth.checkAccess(context.req.user, ['read:pages'], { - path: page.path, - locale: page.locale - })) { - return { - ...page, - ...page.config, - scriptCss: page.scripts?.css, - scriptJsLoad: page.scripts?.jsLoad, - scriptJsUnload: page.scripts?.jsUnload - } - } else { - throw new Error('ERR_FORBIDDEN') - } - } else { - throw new Error('ERR_PAGE_NOT_FOUND') - } - }, - /** - * FETCH SINGLE PAGE BY PATH - */ - async pageByPath (obj, args, context, info) { - // console.info(info) - const pageArgs = parsePath(args.path) - const page = await WIKI.db.pages.getPageFromDb({ - ...pageArgs, - siteId: args.siteId - }) - if (page) { - if (WIKI.auth.checkAccess(context.req.user, ['read:pages'], { - path: page.path, - locale: page.locale - })) { - return { - ...page, - ...page.config, - scriptCss: page.scripts?.css, - scriptJsLoad: page.scripts?.jsLoad, - scriptJsUnload: page.scripts?.jsUnload - } - } else { - throw new Error('ERR_FORBIDDEN') - } - } else { - throw new Error('ERR_PAGE_NOT_FOUND') - } - }, - - /** - * FETCH PATH FROM ALIAS - */ - async pathFromAlias (obj, args, context, info) { - const alias = args.alias?.trim() - if (!alias) { - throw new Error('ERR_PAGE_ALIAS_MISSING') - } - if (!WIKI.sites[args.siteId]) { - throw new Error('ERR_INVALID_SITE') - } - const page = await WIKI.db.pages.query().findOne({ - alias: args.alias, - siteId: args.siteId - }).select('id', 'path', 'locale') - if (!page) { - throw new Error('ERR_PAGE_ALIAS_NOT_FOUND') - } - return { - id: page.id, - path: WIKI.sites[args.siteId].config.localeNamespacing ? `${page.locale}/${page.path}` : page.path - } - }, - - /** - * FETCH TAGS - */ - async tags (obj, args, context, info) { - if (!args.siteId) { throw new Error('Missing Site ID') } - const tags = await WIKI.db.knex('tags').where('siteId', args.siteId).orderBy('tag') - // TODO: check permissions - return tags - }, - /** - * FETCH PAGE TREE - */ - async pageTree (obj, args, context, info) { - let curPage = null - - if (!args.locale) { args.locale = WIKI.config.lang.code } - - if (args.path && !args.parent) { - curPage = await WIKI.db.knex('pageTree').first('parent', 'ancestors').where({ - path: args.path, - locale: args.locale - }) - if (curPage) { - args.parent = curPage.parent || 0 - } else { - return [] - } - } - - const results = await WIKI.db.knex('pageTree').where(builder => { - builder.where('locale', args.locale) - switch (args.mode) { - case 'FOLDERS': - builder.andWhere('isFolder', true) - break - case 'PAGES': - builder.andWhereNotNull('pageId') - break - } - if (!args.parent || args.parent < 1) { - builder.whereNull('parent') - } else { - builder.where('parent', args.parent) - if (args.includeAncestors && curPage && curPage.ancestors.length > 0) { - builder.orWhereIn('id', _.isString(curPage.ancestors) ? JSON.parse(curPage.ancestors) : curPage.ancestors) - } - } - }).orderBy([{ column: 'isFolder', order: 'desc' }, 'title']) - return results.filter(r => { - return WIKI.auth.checkAccess(context.req.user, ['read:pages'], { - path: r.path, - locale: r.locale - }) - }).map(r => ({ - ...r, - parent: r.parent || 0, - locale: r.locale - })) - }, - /** - * FETCH PAGE LINKS - */ - async pageLinks (obj, args, context, info) { - let results - - if (WIKI.config.db.type === 'mysql' || WIKI.config.db.type === 'mariadb' || WIKI.config.db.type === 'sqlite') { - results = await WIKI.db.knex('pages') - .column({ id: 'pages.id' }, { path: 'pages.path' }, 'title', { link: 'pageLinks.path' }, { locale: 'pageLinks.locale' }) - .leftJoin('pageLinks', 'pages.id', 'pageLinks.pageId') - .where({ - 'pages.locale': args.locale - }) - .unionAll( - WIKI.db.knex('pageLinks') - .column({ id: 'pages.id' }, { path: 'pages.path' }, 'title', { link: 'pageLinks.path' }, { locale: 'pageLinks.locale' }) - .leftJoin('pages', 'pageLinks.pageId', 'pages.id') - .where({ - 'pages.locale': args.locale - }) - ) - } else { - results = await WIKI.db.knex('pages') - .column({ id: 'pages.id' }, { path: 'pages.path' }, 'title', { link: 'pageLinks.path' }, { locale: 'pageLinks.locale' }) - .fullOuterJoin('pageLinks', 'pages.id', 'pageLinks.pageId') - .where({ - 'pages.locale': args.locale - }) - } - - return _.reduce(results, (result, val) => { - // -> Check if user has access to source and linked page - if ( - !WIKI.auth.checkAccess(context.req.user, ['read:pages'], { path: val.path, locale: args.locale }) || - !WIKI.auth.checkAccess(context.req.user, ['read:pages'], { path: val.link, locale: val.locale }) - ) { - return result - } - - const existingEntry = _.findIndex(result, ['id', val.id]) - if (existingEntry >= 0) { - if (val.link) { - result[existingEntry].links.push(`${val.locale}/${val.link}`) - } - } else { - result.push({ - id: val.id, - title: val.title, - path: `${args.locale}/${val.path}`, - links: val.link ? [`${val.locale}/${val.link}`] : [] - }) - } - return result - }, []) - }, - /** - * CHECK FOR EDITING CONFLICT - */ - async checkConflicts (obj, args, context, info) { - const page = await WIKI.db.pages.query().select('path', 'locale', 'updatedAt').findById(args.id) - if (page) { - if (WIKI.auth.checkAccess(context.req.user, ['write:pages', 'manage:pages'], { - path: page.path, - locale: page.locale - })) { - return page.updatedAt > args.checkoutDate - } else { - throw new WIKI.Error.PageUpdateForbidden() - } - } else { - throw new WIKI.Error.PageNotFound() - } - }, - /** - * FETCH LATEST VERSION FOR CONFLICT COMPARISON - */ - async checkConflictsLatest (obj, args, context, info) { - const page = await WIKI.db.pages.getPageFromDb(args.id) - if (page) { - if (WIKI.auth.checkAccess(context.req.user, ['write:pages', 'manage:pages'], { - path: page.path, - locale: page.locale - })) { - return { - ...page, - tags: page.tags.map(t => t.tag), - locale: page.locale - } - } else { - throw new WIKI.Error.PageViewForbidden() - } - } else { - throw new WIKI.Error.PageNotFound() - } - } - }, - Mutation: { - /** - * CREATE PAGE - */ - async createPage (obj, args, context) { - try { - const page = await WIKI.db.pages.createPage({ - ...args, - user: context.req.user - }) - return { - operation: generateSuccess('Page created successfully.'), - page - } - } catch (err) { - return generateError(err) - } - }, - /** - * UPDATE PAGE - */ - async updatePage (obj, args, context) { - try { - const page = await WIKI.db.pages.updatePage({ - ...args, - user: context.req.user - }) - return { - operation: generateSuccess('Page has been updated.'), - page - } - } catch (err) { - return generateError(err) - } - }, - /** - * CONVERT PAGE - */ - async convertPage (obj, args, context) { - try { - await WIKI.db.pages.convertPage({ - ...args, - user: context.req.user - }) - return { - operation: generateSuccess('Page has been converted.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * MOVE PAGE - */ - async movePage (obj, args, context) { - try { - await WIKI.db.pages.movePage({ - ...args, - user: context.req.user - }) - return { - operation: generateSuccess('Page has been moved.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * DELETE PAGE - */ - async deletePage (obj, args, context) { - try { - await WIKI.db.pages.deletePage({ - ...args, - user: context.req.user - }) - return { - operation: generateSuccess('Page has been deleted.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * DELETE TAG - */ - async deleteTag (obj, args, context) { - try { - const tagToDel = await WIKI.db.tags.query().findById(args.id) - if (tagToDel) { - await tagToDel.$relatedQuery('pages').unrelate() - await WIKI.db.tags.query().deleteById(args.id) - } else { - throw new Error('This tag does not exist.') - } - return { - operation: generateSuccess('Tag has been deleted.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * UPDATE TAG - */ - async updateTag (obj, args, context) { - try { - const affectedRows = await WIKI.db.tags.query() - .findById(args.id) - .patch({ - tag: _.trim(args.tag).toLowerCase(), - title: _.trim(args.title) - }) - if (affectedRows < 1) { - throw new Error('This tag does not exist.') - } - return { - operation: generateSuccess('Tag has been updated successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * FLUSH PAGE CACHE - */ - async flushCache (obj, args, context) { - try { - await WIKI.db.pages.flushCache() - WIKI.events.outbound.emit('flushCache') - return { - operation: generateSuccess('Pages Cache has been flushed successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * MIGRATE ALL PAGES FROM SOURCE LOCALE TO TARGET LOCALE - */ - async migrateToLocale (obj, args, context) { - try { - const count = await WIKI.db.pages.migrateToLocale(args) - return { - operation: generateSuccess('Migrated content to target locale successfully.'), - count - } - } catch (err) { - return generateError(err) - } - }, - /** - * REBUILD TREE - */ - async rebuildPageTree (obj, args, context) { - try { - await WIKI.db.pages.rebuildTree() - return { - operation: generateSuccess('Page tree rebuilt successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * RERENDER PAGE - */ - async rerenderPage (obj, args, context) { - try { - const page = await WIKI.db.pages.query().findById(args.id) - if (!page) { - throw new WIKI.Error.PageNotFound() - } - await WIKI.db.pages.renderPage(page) - return { - operation: generateSuccess('Page rerendered successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * RESTORE PAGE VERSION - */ - async restorePage (obj, args, context) { - try { - const page = await WIKI.db.pages.query().select('path', 'locale').findById(args.pageId) - if (!page) { - throw new WIKI.Error.PageNotFound() - } - - if (!WIKI.auth.checkAccess(context.req.user, ['write:pages'], { - path: page.path, - locale: page.locale - })) { - throw new WIKI.Error.PageRestoreForbidden() - } - - const targetVersion = await WIKI.db.pageHistory.getVersion({ pageId: args.pageId, versionId: args.versionId }) - if (!targetVersion) { - throw new WIKI.Error.PageNotFound() - } - - await WIKI.db.pages.updatePage({ - ...targetVersion, - id: targetVersion.pageId, - user: context.req.user, - action: 'restored' - }) - - return { - operation: generateSuccess('Page version restored successfully.') - } - } catch (err) { - return generateError(err) - } - }, - /** - * Purge history - */ - async purgePagesHistory (obj, args, context) { - try { - await WIKI.db.pageHistory.purge(args.olderThan) - return { - operation: generateSuccess('Page history purged successfully.') - } - } catch (err) { - return generateError(err) - } - } - }, - Page: { - icon (page) { - return page.icon || 'las la-file-alt' - }, - password (page) { - return page.password ? '********' : '' - }, - content (page, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:source', 'write:pages', 'manage:pages'], { - path: page.path, - locale: page.locale - })) { - throw new Error('ERR_FORBIDDEN') - } - - return page.content - }, - // async tags (page) { - // return WIKI.db.pages.relatedQuery('tags').for(page.id) - // }, - tocDepth (page) { - return { - min: page.extra?.tocDepth?.min ?? 1, - max: page.extra?.tocDepth?.max ?? 2 - } - } - // comments(pg) { - // return pg.$relatedQuery('comments') - // } - } -} diff --git a/server/graph/resolvers/rendering.mjs b/server/graph/resolvers/rendering.mjs deleted file mode 100644 index 553830459..000000000 --- a/server/graph/resolvers/rendering.mjs +++ /dev/null @@ -1,52 +0,0 @@ -import _ from 'lodash-es' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' - -export default { - Query: { - async renderers(obj, args, context, info) { - let renderers = await WIKI.db.renderers.getRenderers() - renderers = renderers.map(rdr => { - const rendererInfo = _.find(WIKI.data.renderers, ['key', rdr.key]) || {} - return { - ...rendererInfo, - ...rdr, - config: _.sortBy(_.transform(rdr.config, (res, value, key) => { - const configData = _.get(rendererInfo.props, key, false) - if (configData) { - res.push({ - key, - value: JSON.stringify({ - ...configData, - value - }) - }) - } - }, []), 'key') - } - }) - // if (args.filter) { renderers = graphHelper.filter(renderers, args.filter) } - if (args.orderBy) { renderers = _.sortBy(renderers, [args.orderBy]) } - return renderers - } - }, - Mutation: { - async updateRenderers(obj, args, context) { - try { - for (let rdr of args.renderers) { - await WIKI.db.renderers.query().patch({ - isEnabled: rdr.isEnabled, - config: _.reduce(rdr.config, (result, value, key) => { - _.set(result, `${value.key}`, _.get(JSON.parse(value.value), 'v', null)) - return result - }, {}) - }).where('key', rdr.key) - } - return { - responseResult: generateSuccess('Renderers updated successfully') - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/site.mjs b/server/graph/resolvers/site.mjs deleted file mode 100644 index 4fd827dba..000000000 --- a/server/graph/resolvers/site.mjs +++ /dev/null @@ -1,354 +0,0 @@ -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import _ from 'lodash-es' -import CleanCSS from 'clean-css' -import path from 'node:path' -import fs from 'fs-extra' -import { v4 as uuid } from 'uuid' - -export default { - Query: { - async sites () { - const sites = await WIKI.db.sites.query().orderBy('hostname') - return sites.map(s => ({ - ...s.config, - id: s.id, - hostname: s.hostname, - isEnabled: s.isEnabled, - pageExtensions: s.config.pageExtensions.join(', ') - })) - }, - async siteById (obj, args) { - const site = await WIKI.db.sites.query().findById(args.id) - return site ? { - ...site.config, - id: site.id, - hostname: site.hostname, - isEnabled: site.isEnabled, - pageExtensions: site.config.pageExtensions.join(', ') - } : null - }, - async siteByHostname (obj, args) { - let site = await WIKI.db.sites.query().where({ - hostname: args.hostname - }).first() - if (!site && !args.exact) { - site = await WIKI.db.sites.query().where({ - hostname: '*' - }).first() - } - return site ? { - ...site.config, - id: site.id, - hostname: site.hostname, - isEnabled: site.isEnabled, - pageExtensions: site.config.pageExtensions.join(', ') - } : null - } - }, - Mutation: { - /** - * CREATE SITE - */ - async createSite (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['write:sites', 'manage:sites'])) { - throw new Error('ERR_FORBIDDEN') - } - - // -> Validate inputs - if (!args.hostname || args.hostname.length < 1 || !/^(\\*)|([a-z0-9\-.:]+)$/.test(args.hostname)) { - throw new WIKI.Error.Custom('SiteCreateInvalidHostname', 'Invalid Site Hostname') - } - if (!args.title || args.title.length < 1 || !/^[^<>"]+$/.test(args.title)) { - throw new WIKI.Error.Custom('SiteCreateInvalidTitle', 'Invalid Site Title') - } - // -> Check for duplicate catch-all - if (args.hostname === '*') { - const site = await WIKI.db.sites.query().where({ - hostname: args.hostname - }).first() - if (site) { - throw new WIKI.Error.Custom('SiteCreateDuplicateCatchAll', 'A site with a catch-all hostname already exists! Cannot have 2 catch-all hostnames.') - } - } - // -> Create site - const newSite = await WIKI.db.sites.createSite(args.hostname, { - title: args.title - }) - return { - operation: generateSuccess('Site created successfully'), - site: newSite - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * UPDATE SITE - */ - async updateSite (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:sites'])) { - throw new Error('ERR_FORBIDDEN') - } - - // -> Load site - const site = await WIKI.db.sites.query().findById(args.id) - if (!site) { - throw new WIKI.Error.Custom('SiteInvalidId', 'Invalid Site ID') - } - // -> Check for bad input - if (_.has(args.patch, 'hostname') && _.trim(args.patch.hostname).length < 1) { - throw new WIKI.Error.Custom('SiteInvalidHostname', 'Hostname is invalid.') - } - // -> Check for duplicate catch-all - if (args.patch.hostname === '*' && site.hostname !== '*') { - const dupSite = await WIKI.db.sites.query().where({ hostname: '*' }).first() - if (dupSite) { - throw new WIKI.Error.Custom('SiteUpdateDuplicateCatchAll', `Site ${dupSite.config.title} with a catch-all hostname already exists! Cannot have 2 catch-all hostnames.`) - } - } - // -> Format Code - if (args.patch?.theme?.injectCSS) { - args.patch.theme.injectCSS = new CleanCSS({ inline: false }).minify(args.patch.theme.injectCSS).styles - } - // -> Format Page Extensions - if (args.patch?.pageExtensions) { - args.patch.pageExtensions = args.patch.pageExtensions.split(',').map(ext => ext.trim().toLowerCase()).filter(ext => ext.length > 0) - } - // -> Update site - await WIKI.db.sites.updateSite(args.id, { - hostname: args.patch.hostname ?? site.hostname, - isEnabled: args.patch.isEnabled ?? site.isEnabled, - config: _.defaultsDeep(_.omit(args.patch, ['hostname', 'isEnabled']), site.config) - }) - - return { - operation: generateSuccess('Site updated successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * DELETE SITE - */ - async deleteSite (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:sites'])) { - throw new Error('ERR_FORBIDDEN') - } - - // -> Ensure site isn't last one - const sitesCount = await WIKI.db.sites.query().count('id').first() - if (sitesCount?.count && _.toNumber(sitesCount?.count) <= 1) { - throw new WIKI.Error.Custom('SiteDeleteLastSite', 'Cannot delete the last site. At least 1 site must exists at all times.') - } - // -> Delete site - await WIKI.db.sites.deleteSite(args.id) - return { - operation: generateSuccess('Site deleted successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * UPLOAD LOGO - */ - async uploadSiteLogo (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:sites'])) { - throw new Error('ERR_FORBIDDEN') - } - - const { filename, mimetype, createReadStream } = await args.image - WIKI.logger.info(`Processing site logo ${filename} of type ${mimetype}...`) - if (!WIKI.extensions.ext.sharp.isInstalled) { - throw new Error('This feature requires the Sharp extension but it is not installed.') - } - if (!['.svg', '.png', '.jpg', 'webp', '.gif'].some(s => filename.endsWith(s))) { - throw new Error('Invalid File Extension. Must be svg, png, jpg, webp or gif.') - } - const destFormat = mimetype.startsWith('image/svg') ? 'svg' : 'png' - const destFolder = path.resolve( - process.cwd(), - WIKI.config.dataPath, - `assets` - ) - const destPath = path.join(destFolder, `logo-${args.id}.${destFormat}`) - await fs.ensureDir(destFolder) - // -> Resize - await WIKI.extensions.ext.sharp.resize({ - format: destFormat, - inputStream: createReadStream(), - outputPath: destPath, - height: 72 - }) - // -> Save logo meta to DB - const site = await WIKI.db.sites.query().findById(args.id) - if (!site.config.assets.logo) { - site.config.assets.logo = uuid() - } - site.config.assets.logoExt = destFormat - await WIKI.db.sites.query().findById(args.id).patch({ config: site.config }) - await WIKI.db.sites.reloadCache() - // -> Save image data to DB - const imgBuffer = await fs.readFile(destPath) - await WIKI.db.knex('assets').insert({ - id: site.config.assets.logo, - fileName: `_logo.${destFormat}`, - fileExt: `.${destFormat}`, - isSystem: true, - kind: 'image', - mimeType: (destFormat === 'svg') ? 'image/svg' : 'image/png', - fileSize: Math.ceil(imgBuffer.byteLength / 1024), - data: imgBuffer, - authorId: context.req.user.id, - siteId: site.id - }).onConflict('id').merge() - WIKI.logger.info('New site logo processed successfully.') - return { - operation: generateSuccess('Site logo uploaded successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * UPLOAD FAVICON - */ - async uploadSiteFavicon (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:sites'])) { - throw new Error('ERR_FORBIDDEN') - } - - const { filename, mimetype, createReadStream } = await args.image - WIKI.logger.info(`Processing site favicon ${filename} of type ${mimetype}...`) - if (!WIKI.extensions.ext.sharp.isInstalled) { - throw new Error('This feature requires the Sharp extension but it is not installed.') - } - if (!['.svg', '.png', '.jpg', '.webp', '.gif'].some(s => filename.endsWith(s))) { - throw new Error('Invalid File Extension. Must be svg, png, jpg, webp or gif.') - } - const destFormat = mimetype.startsWith('image/svg') ? 'svg' : 'png' - const destFolder = path.resolve( - process.cwd(), - WIKI.config.dataPath, - `assets` - ) - const destPath = path.join(destFolder, `favicon-${args.id}.${destFormat}`) - await fs.ensureDir(destFolder) - // -> Resize - await WIKI.extensions.ext.sharp.resize({ - format: destFormat, - inputStream: createReadStream(), - outputPath: destPath, - width: 64, - height: 64 - }) - // -> Save favicon meta to DB - const site = await WIKI.db.sites.query().findById(args.id) - if (!site.config.assets.favicon) { - site.config.assets.favicon = uuid() - } - site.config.assets.faviconExt = destFormat - await WIKI.db.sites.query().findById(args.id).patch({ config: site.config }) - await WIKI.db.sites.reloadCache() - // -> Save image data to DB - const imgBuffer = await fs.readFile(destPath) - await WIKI.db.knex('assets').insert({ - id: site.config.assets.favicon, - fileName: `_favicon.${destFormat}`, - fileExt: `.${destFormat}`, - isSystem: true, - kind: 'image', - mimeType: (destFormat === 'svg') ? 'image/svg' : 'image/png', - fileSize: Math.ceil(imgBuffer.byteLength / 1024), - data: imgBuffer, - authorId: context.req.user.id, - siteId: site.id - }).onConflict('id').merge() - WIKI.logger.info('New site favicon processed successfully.') - return { - operation: generateSuccess('Site favicon uploaded successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * UPLOAD LOGIN BG - */ - async uploadSiteLoginBg (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:sites'])) { - throw new Error('ERR_FORBIDDEN') - } - - const { filename, mimetype, createReadStream } = await args.image - WIKI.logger.info(`Processing site login bg ${filename} of type ${mimetype}...`) - if (!WIKI.extensions.ext.sharp.isInstalled) { - throw new Error('This feature requires the Sharp extension but it is not installed.') - } - if (!['.png', '.jpg', '.webp'].some(s => filename.endsWith(s))) { - throw new Error('Invalid File Extension. Must be png, jpg or webp.') - } - const destFolder = path.resolve( - process.cwd(), - WIKI.config.dataPath, - `assets` - ) - const destPath = path.join(destFolder, `loginbg-${args.id}.jpg`) - await fs.ensureDir(destFolder) - // -> Resize - await WIKI.extensions.ext.sharp.resize({ - format: 'jpg', - inputStream: createReadStream(), - outputPath: destPath, - width: 1920 - }) - // -> Save login bg meta to DB - const site = await WIKI.db.sites.query().findById(args.id) - if (!site.config.assets.loginBg) { - site.config.assets.loginBg = uuid() - await WIKI.db.sites.query().findById(args.id).patch({ config: site.config }) - await WIKI.db.sites.reloadCache() - } - // -> Save image data to DB - const imgBuffer = await fs.readFile(destPath) - await WIKI.db.knex('assets').insert({ - id: site.config.assets.loginBg, - filename: '_loginbg.jpg', - hash: '_loginbg', - ext: '.jpg', - isSystem: true, - kind: 'image', - mime: 'image/jpg', - fileSize: Math.ceil(imgBuffer.byteLength / 1024), - data: imgBuffer, - authorId: context.req.user.id, - siteId: site.id - }).onConflict('id').merge() - WIKI.logger.info('New site login bg processed successfully.') - return { - operation: generateSuccess('Site login bg uploaded successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - } - }, - SiteLocales: { - async active (obj, args, context) { - return obj.active.map(l => WIKI.cache.get(`locale:${l}`)) - } - } -} diff --git a/server/graph/resolvers/storage.mjs b/server/graph/resolvers/storage.mjs deleted file mode 100644 index dd5add870..000000000 --- a/server/graph/resolvers/storage.mjs +++ /dev/null @@ -1,229 +0,0 @@ -import _ from 'lodash-es' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import { v4 as uuid } from 'uuid' - -export default { - Query: { - async storageTargets (obj, args, context, info) { - const dbTargets = await WIKI.db.storage.getTargets({ siteId: args.siteId }) - // targets = _.sortBy(targets.map(tgt => { - // const targetInfo = _.find(WIKI.data.storage, ['module', tgt.key]) || {} - // return { - // ...targetInfo, - // ...tgt, - // hasSchedule: (targetInfo.schedule !== false), - // syncInterval: targetInfo.syncInterval || targetInfo.schedule || 'P0D', - // syncIntervalDefault: targetInfo.schedule, - // config: _.sortBy(_.transform(tgt.config, (res, value, key) => { - // const configData = _.get(targetInfo.props, key, false) - // if (configData) { - // res.push({ - // key, - // value: JSON.stringify({ - // ...configData, - // value: (configData.sensitive && value.length > 0) ? '********' : value - // }) - // }) - // } - // }, []), 'key') - // } - // }), ['title', 'key']) - return _.sortBy(WIKI.storage.defs.map(md => { - const dbTarget = dbTargets.find(tg => tg.module === md.key) - return { - id: dbTarget?.id ?? uuid(), - isEnabled: dbTarget?.isEnabled ?? false, - module: md.key, - title: md.title, - description: md.description, - icon: md.icon, - banner: md.banner, - vendor: md.vendor, - website: md.website, - contentTypes: { - activeTypes: dbTarget?.contentTypes?.activeTypes ?? md.contentTypes.defaultTypesEnabled, - largeThreshold: dbTarget?.contentTypes?.largeThreshold ?? md.contentTypes.defaultLargeThreshold - }, - assetDelivery: { - isStreamingSupported: md?.assetDelivery?.isStreamingSupported ?? false, - isDirectAccessSupported: md?.assetDelivery?.isDirectAccessSupported ?? false, - streaming: dbTarget?.assetDelivery?.streaming ?? md?.assetDelivery?.defaultStreamingEnabled ?? false, - directAccess: dbTarget?.assetDelivery?.directAccess ?? md?.assetDelivery?.defaultDirectAccessEnabled ?? false - }, - versioning: { - isSupported: md?.versioning?.isSupported ?? false, - isForceEnabled: md?.versioning?.isForceEnabled ?? false, - enabled: dbTarget?.versioning?.enabled ?? md?.versioning?.defaultEnabled ?? false - }, - sync: {}, - status: {}, - setup: { - handler: md?.setup?.handler, - state: dbTarget?.state?.setup ?? 'notconfigured', - values: md.setup?.handler ? - _.transform(md.setup.defaultValues, - (r, v, k) => { - r[k] = dbTarget?.config?.[k] ?? v - }, {}) : - {} - }, - config: _.transform(md.props, (r, v, k) => { - const cfValue = dbTarget?.config?.[k] ?? v.default - r[k] = { - ...v, - value: v.sensitive && cfValue ? '********' : cfValue, - ...v.enum && { - enum: v.enum.map(o => { - if (o.indexOf('|') > 0) { - const oParsed = o.split('|') - return { - value: oParsed[0], - label: oParsed[1] - } - } else { - return { - value: o, - label: o - } - } - }) - } - } - }, {}), - actions: md.actions - } - }), ['title']) - } - }, - Mutation: { - async updateStorageTargets (obj, args, context) { - WIKI.logger.debug(`Updating storage targets for site ${args.siteId}...`) - try { - const dbTargets = await WIKI.db.storage.getTargets({ siteId: args.siteId }) - for (const tgt of args.targets) { - const md = _.find(WIKI.storage.defs, ['key', tgt.module]) - if (!md) { - throw new Error('Invalid module key for non-existent storage target.') - } - - const dbTarget = _.find(dbTargets, ['id', tgt.id]) - - // -> Build update config object - const updatedConfig = dbTarget?.config ?? {} - if (tgt.config) { - for (const [key, prop] of Object.entries(md.props)) { - if (prop.readOnly) { continue } - if (!Object.prototype.hasOwnProperty.call(tgt.config, key)) { continue } - if (prop.sensitive && tgt.config[key] === '********') { continue } - updatedConfig[key] = tgt.config[key] - } - } - - // -> Target doesn't exist yet in the DB, let's create it - if (!dbTarget) { - WIKI.logger.debug(`No existing DB configuration for module ${tgt.module}. Creating a new one...`) - await WIKI.db.storage.query().insert({ - id: tgt.id, - module: tgt.module, - siteId: args.siteId, - isEnabled: tgt.isEnabled ?? false, - contentTypes: { - activeTypes: tgt.contentTypes ?? md.contentTypes.defaultTypesEnabled ?? [], - largeThreshold: tgt.largeThreshold ?? md.contentTypes.defaultLargeThreshold ?? '5MB' - }, - assetDelivery: { - streaming: tgt.assetDeliveryFileStreaming ?? md?.assetDelivery?.defaultStreamingEnabled ?? false, - directAccess: tgt.assetDeliveryDirectAccess ?? md?.assetDelivery?.defaultDirectAccessEnabled ?? false - }, - versioning: { - enabled: tgt.useVersioning ?? md?.versioning?.defaultEnabled ?? false - }, - state: { - current: 'ok' - }, - config: updatedConfig - }) - } else { - WIKI.logger.debug(`Updating DB configuration for module ${tgt.module}...`) - await WIKI.db.storage.query().patch({ - isEnabled: tgt.isEnabled ?? dbTarget.isEnabled ?? false, - contentTypes: { - activeTypes: tgt.contentTypes ?? dbTarget?.contentTypes?.activeTypes ?? [], - largeThreshold: tgt.largeThreshold ?? dbTarget?.contentTypes?.largeThreshold ?? '5MB' - }, - assetDelivery: { - streaming: tgt.assetDeliveryFileStreaming ?? dbTarget?.assetDelivery?.streaming ?? false, - directAccess: tgt.assetDeliveryDirectAccess ?? dbTarget?.assetDelivery?.directAccess ?? false - }, - versioning: { - enabled: tgt.useVersioning ?? dbTarget?.versioning?.enabled ?? false - }, - config: updatedConfig - }).where('id', tgt.id) - } - } - // await WIKI.db.storage.initTargets() - return { - operation: generateSuccess('Storage targets updated successfully') - } - } catch (err) { - return generateError(err) - } - }, - async setupStorageTarget (obj, args, context) { - try { - const tgt = await WIKI.db.storage.query().findById(args.targetId) - if (!tgt) { - throw new Error('Not storage target matching this ID') - } - const md = _.find(WIKI.storage.defs, ['key', tgt.module]) - if (!md) { - throw new Error('No matching storage module installed.') - } - if (!await WIKI.db.storage.ensureModule(md.key)) { - throw new Error('Failed to load storage module. Check logs for details.') - } - const result = await WIKI.storage.modules[md.key].setup(args.targetId, args.state) - - return { - operation: generateSuccess('Storage target setup step succeeded'), - state: result - } - } catch (err) { - return generateError(err) - } - }, - async destroyStorageTargetSetup (obj, args, context) { - try { - const tgt = await WIKI.db.storage.query().findById(args.targetId) - if (!tgt) { - throw new Error('Not storage target matching this ID') - } - const md = _.find(WIKI.storage.defs, ['key', tgt.module]) - if (!md) { - throw new Error('No matching storage module installed.') - } - if (!await WIKI.db.storage.ensureModule(md.key)) { - throw new Error('Failed to load storage module. Check logs for details.') - } - await WIKI.storage.modules[md.key].setupDestroy(args.targetId) - - return { - operation: generateSuccess('Storage target setup configuration destroyed succesfully.') - } - } catch (err) { - return generateError(err) - } - }, - async executeStorageAction (obj, args, context) { - try { - await WIKI.db.storage.executeAction(args.targetKey, args.handler) - return { - operation: generateSuccess('Action completed.') - } - } catch (err) { - return generateError(err) - } - } - } -} diff --git a/server/graph/resolvers/system.mjs b/server/graph/resolvers/system.mjs deleted file mode 100644 index 62a051804..000000000 --- a/server/graph/resolvers/system.mjs +++ /dev/null @@ -1,475 +0,0 @@ -import _ from 'lodash-es' -import util from 'node:util' -import getosSync from 'getos' -import os from 'node:os' -import { filesize } from 'filesize' -import path from 'node:path' -import fs from 'fs-extra' -import { DateTime } from 'luxon' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' - -const getos = util.promisify(getosSync) - -export default { - Query: { - /** - * Metrics Endpoint State - */ - metricsState () { - return WIKI.config.metrics?.isEnabled ?? false - }, - /** - * System Flags - */ - systemFlags () { - return WIKI.config.flags - }, - /** - * System Info - */ - async systemInfo (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:dashboard', 'manage:sites'])) { - throw new Error('ERR_FORBIDDEN') - } - - return {} - }, - /** - * System Extensions - */ - async systemExtensions (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - const exts = Object.values(WIKI.extensions.ext).map(ext => _.pick(ext, ['key', 'title', 'description', 'isInstalled', 'isInstallable'])) - for (const ext of exts) { - ext.isCompatible = await WIKI.extensions.ext[ext.key].isCompatible() - } - return exts - }, - /** - * List System Instances - */ - async systemInstances (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - const instRaw = await WIKI.db.knex('pg_stat_activity') - .select([ - 'usename', - 'client_addr', - 'application_name', - 'backend_start', - 'state_change' - ]) - .where('datname', WIKI.db.knex.client.connectionSettings.database) - .andWhereLike('application_name', 'Wiki.js%') - const insts = {} - for (const inst of instRaw) { - const instId = inst.application_name.substring(10, 20) - const conType = inst.application_name.includes(':MAIN') ? 'main' : 'sub' - const curInst = insts[instId] ?? { - activeConnections: 0, - activeListeners: 0, - dbFirstSeen: inst.backend_start, - dbLastSeen: inst.state_change - } - insts[instId] = { - id: instId, - activeConnections: conType === 'main' ? curInst.activeConnections + 1 : curInst.activeConnections, - activeListeners: conType === 'sub' ? curInst.activeListeners + 1 : curInst.activeListeners, - dbUser: inst.usename, - dbFirstSeen: curInst.dbFirstSeen > inst.backend_start ? inst.backend_start : curInst.dbFirstSeen, - dbLastSeen: curInst.dbLastSeen < inst.state_change ? inst.state_change : curInst.dbLastSeen, - ip: inst.client_addr - } - } - return _.values(insts) - }, - /** - * System Security Settings - */ - systemSecurity (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.config.security - }, - /** - * List System Jobs - */ - async systemJobs (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - const results = args.states?.length > 0 - ? await WIKI.db.knex('jobHistory').whereIn('state', args.states.map(s => s.toLowerCase())).orderBy('startedAt', 'desc') - : await WIKI.db.knex('jobHistory').orderBy('startedAt', 'desc') - return results.map(r => ({ - ...r, - state: r.state.toUpperCase() - })) - }, - /** - * List Scheduled Jobs - */ - async systemJobsScheduled (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.db.knex('jobSchedule').orderBy('task') - }, - /** - * List Upcoming Jobs - */ - async systemJobsUpcoming (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.db.knex('jobs').orderBy([ - { column: 'waitUntil', order: 'asc', nulls: 'first' }, - { column: 'createdAt', order: 'asc' } - ]) - }, - /** - * Search Settings - */ - systemSearch (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - return { - ...WIKI.config.search, - dictOverrides: JSON.stringify(WIKI.config.search.dictOverrides, null, 2) - } - } - }, - Mutation: { - async cancelJob (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.logger.info(`Admin requested cancelling job ${args.id}...`) - - const result = await WIKI.db.knex('jobs') - .where('id', args.id) - .del() - if (result === 1) { - WIKI.logger.info(`Cancelled job ${args.id} [ OK ]`) - } else { - throw new Error('Job has already entered active state or does not exist.') - } - return { - operation: generateSuccess('Cancelled job successfully.') - } - } catch (err) { - if (err.message !== 'ERR_FORBIDDEN') { - WIKI.logger.warn(err) - } - return generateError(err) - } - }, - async checkForUpdates (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['read:dashboard', 'manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - const renderJob = await WIKI.scheduler.addJob({ - task: 'checkVersion', - maxRetries: 0, - promise: true - }) - await renderJob.promise - return { - operation: generateSuccess('Checked for latest version successfully.'), - current: WIKI.version, - latest: WIKI.config.update.version, - latestDate: WIKI.config.update.versionDate - } - } catch (err) { - if (err.message !== 'ERR_FORBIDDEN') { - WIKI.logger.warn(err) - } - return generateError(err) - } - }, - async disconnectWS (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.servers.ws.disconnectSockets(true) - WIKI.logger.info('All active websocket connections have been terminated.') - return { - operation: generateSuccess('All websocket connections closed successfully.') - } - } catch (err) { - if (err.message !== 'ERR_FORBIDDEN') { - WIKI.logger.warn(err) - } - return generateError(err) - } - }, - async installExtension (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.extensions.ext[args.key].install() - // TODO: broadcast ext install - return { - operation: generateSuccess('Extension installed successfully') - } - } catch (err) { - return generateError(err) - } - }, - async rebuildSearchIndex (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.scheduler.addJob({ - task: 'rebuildSearchIndex', - maxRetries: 0 - }) - return { - operation: generateSuccess('Search index rebuild has been scheduled and will start shortly.') - } - } catch (err) { - return generateError(err) - } - }, - async retryJob (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.logger.info(`Admin requested rescheduling of job ${args.id}...`) - - const job = await WIKI.db.knex('jobHistory') - .where('id', args.id) - .first() - if (!job) { - throw new Error('No such job found.') - } else if (job.state === 'interrupted') { - throw new Error('Cannot reschedule a task that has been interrupted. It will automatically be retried shortly.') - } else if (job.state === 'failed' && job.attempt < job.maxRetries) { - throw new Error('Cannot reschedule a task that has not reached its maximum retry attempts.') - } - await WIKI.db.knex('jobs') - .insert({ - id: job.id, - task: job.task, - useWorker: job.useWorker, - payload: job.payload, - retries: job.attempt, - maxRetries: job.maxRetries, - isScheduled: job.wasScheduled, - createdBy: WIKI.INSTANCE_ID - }) - WIKI.logger.info(`Job ${args.id} has been rescheduled [ OK ]`) - return { - operation: generateSuccess('Job rescheduled successfully.') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * Set Metrics endpoint state - */ - async setMetricsState (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.config.metrics.isEnabled = args.enabled - await WIKI.configSvc.saveToDb(['metrics']) - return { - operation: generateSuccess('Metrics endpoint state changed successfully') - } - } catch (err) { - return generateError(err) - } - }, - async updateSystemFlags (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.config.flags = { - ...WIKI.config.flags, - ...args.flags - } - await WIKI.configSvc.applyFlags() - await WIKI.configSvc.saveToDb(['flags']) - return { - operation: generateSuccess('System Flags applied successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - async updateSystemSearch (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.config.search = { - ...WIKI.config.search, - termHighlighting: args.termHighlighting ?? WIKI.config.search.termHighlighting, - dictOverrides: args.dictOverrides ? JSON.parse(args.dictOverrides) : WIKI.config.search.dictOverrides - } - // TODO: broadcast config update - await WIKI.configSvc.saveToDb(['search']) - return { - operation: generateSuccess('System Search configuration applied successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - async updateSystemSecurity (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:system'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.config.security = _.defaultsDeep(_.omit(args, ['__typename']), WIKI.config.security) - // TODO: broadcast config update - await WIKI.configSvc.saveToDb(['security']) - return { - operation: generateSuccess('System Security configuration applied successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - } - }, - SystemInfo: { - configFile () { - return path.join(process.cwd(), 'config.yml') - }, - cpuCores () { - return os.cpus().length - }, - currentVersion () { - return WIKI.version - }, - dbHost () { - return WIKI.config.db.host - }, - dbVersion () { - return WIKI.db.VERSION - }, - hostname () { - return os.hostname() - }, - httpPort () { - return WIKI.servers.servers.http ? _.get(WIKI.servers.servers.http.address(), 'port', 0) : 0 - }, - httpRedirection () { - return _.get(WIKI.config, 'server.sslRedir', false) - }, - httpsPort () { - return WIKI.servers.servers.https ? _.get(WIKI.servers.servers.https.address(), 'port', 0) : 0 - }, - isMailConfigured () { - return WIKI.config?.mail?.host?.length > 2 - }, - async isSchedulerHealthy () { - const results = await WIKI.db.knex('jobHistory').count('* as total').whereIn('state', ['failed', 'interrupted']).andWhere('startedAt', '>=', DateTime.utc().minus({ days: 1 }).toISO()).first() - return _.toSafeInteger(results?.total) === 0 - }, - latestVersion () { - return WIKI.config.update.version - }, - latestVersionReleaseDate () { - return DateTime.fromISO(WIKI.config.update.versionDate).toJSDate() - }, - nodeVersion () { - return process.version.substring(1) - }, - async operatingSystem () { - let osLabel = `${os.type()} (${os.platform()}) ${os.release()} ${os.arch()}` - if (os.platform() === 'linux') { - const osInfo = await getos() - osLabel = `${os.type()} - ${osInfo.dist} (${osInfo.codename || os.platform()}) ${osInfo.release || os.release()} ${os.arch()}` - } - return osLabel - }, - async platform () { - const isDockerized = await fs.pathExists('/.dockerenv') - if (isDockerized) { - return 'docker' - } - return os.platform() - }, - ramTotal () { - return filesize(os.totalmem()) - }, - sslDomain () { - return WIKI.config.ssl.enabled && WIKI.config.ssl.provider === 'letsencrypt' ? WIKI.config.ssl.domain : null - }, - sslExpirationDate () { - return WIKI.config.ssl.enabled && WIKI.config.ssl.provider === 'letsencrypt' ? _.get(WIKI.config.letsencrypt, 'payload.expires', null) : null - }, - sslProvider () { - return WIKI.config.ssl.enabled ? WIKI.config.ssl.provider : null - }, - sslStatus () { - return 'OK' - }, - sslSubscriberEmail () { - return WIKI.config.ssl.enabled && WIKI.config.ssl.provider === 'letsencrypt' ? WIKI.config.ssl.subscriberEmail : null - }, - async upgradeCapable () { - return !_.isNil(process.env.UPGRADE_COMPANION) - }, - workingDirectory () { - return process.cwd() - }, - async groupsTotal () { - const total = await WIKI.db.groups.query().count('* as total').first() - return _.toSafeInteger(total.total) - }, - async pagesTotal () { - const total = await WIKI.db.pages.query().count('* as total').first() - return _.toSafeInteger(total.total) - }, - async tagsTotal () { - const total = await WIKI.db.tags.query().count('* as total').first() - return _.toSafeInteger(total.total) - }, - async usersTotal () { - const total = await WIKI.db.users.query().count('* as total').first() - return _.toSafeInteger(total.total) - }, - async loginsPastDay () { - const total = await WIKI.db.users.query().count('* as total').whereRaw('"lastLoginAt" >= NOW() - INTERVAL \'1 DAY\'').first() - return _.toSafeInteger(total.total) - } - } -} diff --git a/server/graph/resolvers/tree.mjs b/server/graph/resolvers/tree.mjs deleted file mode 100644 index efe0eba96..000000000 --- a/server/graph/resolvers/tree.mjs +++ /dev/null @@ -1,221 +0,0 @@ -import _ from 'lodash-es' -import { - decodeTreePath, - encodeTreePath -} from '../../helpers/common.mjs' -import { generateError, generateSuccess } from '../../helpers/graph.mjs' - -const typeResolvers = { - folder: 'TreeItemFolder', - page: 'TreeItemPage', - asset: 'TreeItemAsset' -} - -const rePathName = /^[a-z0-9-]+$/ -const reTitle = /^[^<>"]+$/ - -export default { - Query: { - /** - * FETCH TREE - */ - async tree (obj, args, context, info) { - // Offset - const offset = args.offset || 0 - if (offset < 0) { - throw new Error('Invalid Offset') - } - - // Limit - const limit = args.limit || 1000 - if (limit < 1 || limit > 1000) { - throw new Error('Invalid Limit') - } - - // Order By - const orderByDirection = args.orderByDirection || 'asc' - const orderBy = args.orderBy || 'title' - - // Parse depth - const depth = args.depth || 0 - if (depth < 0 || depth > 10) { - throw new Error('Invalid Depth') - } - const depthCondition = depth > 0 ? `*{,${depth}}` : '*{0}' - - // Get parent path - let parentPath = '' - if (args.parentId) { - const parent = await WIKI.db.knex('tree').where('id', args.parentId).first() - if (parent) { - parentPath = (parent.folderPath ? `${parent.folderPath}.${parent.fileName}` : parent.fileName) - } - } else if (args.parentPath) { - parentPath = encodeTreePath(args.parentPath) - } - const folderPathCondition = parentPath ? `${parentPath}.${depthCondition}` : depthCondition - - // Fetch Items - const items = await WIKI.db.knex('tree') - .select(WIKI.db.knex.raw('tree.*, nlevel(tree."folderPath") AS depth')) - .where(builder => { - builder.where('folderPath', '~', folderPathCondition) - // -> Include ancestors - if (args.includeAncestors) { - const parentPathParts = parentPath.split('.') - for (let i = 0; i <= parentPathParts.length; i++) { - builder.orWhere({ - folderPath: _.dropRight(parentPathParts, i).join('.'), - fileName: _.nth(parentPathParts, i * -1), - type: 'folder' - }) - } - } - // -> Include root items - if (args.includeRootFolders) { - builder.orWhere({ - folderPath: '', - type: 'folder' - }) - } - - // -> Filter by tags - if (args.tags && args.tags.length > 0) { - builder.where('tags', '@>', args.tags) - } - }) - .andWhere(builder => { - // -> Limit to specific types - if (args.types && args.types.length > 0) { - builder.whereIn('type', args.types) - } - }) - .limit(limit) - .offset(offset) - .orderBy([ - { column: 'depth' }, - { column: orderBy, order: orderByDirection } - ]) - - return items.map(item => ({ - id: item.id, - depth: item.depth, - type: item.type, - folderPath: decodeTreePath(item.folderPath), - fileName: item.fileName, - title: item.title, - tags: item.tags ?? [], - createdAt: item.createdAt, - updatedAt: item.updatedAt, - ...(item.type === 'folder') && { - childrenCount: item.meta?.children || 0, - isAncestor: item.folderPath.length < parentPath.length - }, - ...(item.type === 'asset') && { - fileSize: item.meta?.fileSize || 0, - fileExt: item.meta?.fileExt || '', - mimeType: item.meta?.mimeType || '' - }, - ...(item.type === 'page') && { - description: item.meta?.description || '' - } - })) - }, - /** - * FETCH SINGLE FOLDER BY ID - */ - async folderById (obj, args, context) { - const folder = await WIKI.db.knex('tree') - .select(WIKI.db.knex.raw('tree.*, nlevel(tree."folderPath") AS depth')) - .where('id', args.id) - .first() - - if (!folder) { - throw new Error('ERR_INVALID_FOLDER') - } - - return { - ...folder, - folderPath: folder.folderPath.replaceAll('.', '/').replaceAll('_', '-'), - childrenCount: folder.meta?.children || 0 - } - }, - /** - * FETCH SINGLE FOLDER BY PATH - */ - async folderByPath (obj, args, context) { - const parentPathParts = args.path.replaceAll('/', '.').replaceAll('-', '_').split('.') - const folder = await WIKI.db.knex('tree') - .select(WIKI.db.knex.raw('tree.*, nlevel(tree."folderPath") AS depth')) - .where({ - siteId: args.siteId, - locale: args.locale, - folderPath: _.dropRight(parentPathParts).join('.'), - fileName: _.last(parentPathParts) - }) - .first() - - if (!folder) { - throw new Error('ERR_INVALID_FOLDER') - } - - return { - ...folder, - folderPath: folder.folderPath.replaceAll('.', '/').replaceAll('_', '-'), - childrenCount: folder.meta?.children || 0 - } - } - }, - Mutation: { - /** - * CREATE FOLDER - */ - async createFolder (obj, args, context) { - try { - await WIKI.db.tree.createFolder(args) - - return { - operation: generateSuccess('Folder created successfully') - } - } catch (err) { - WIKI.logger.debug(`Failed to create folder: ${err.message}`) - return generateError(err) - } - }, - /** - * RENAME FOLDER - */ - async renameFolder (obj, args, context) { - try { - await WIKI.db.tree.renameFolder(args) - - return { - operation: generateSuccess('Folder renamed successfully') - } - } catch (err) { - WIKI.logger.debug(`Failed to rename folder ${args.folderId}: ${err.message}`) - return generateError(err) - } - }, - /** - * DELETE FOLDER - */ - async deleteFolder (obj, args, context) { - try { - await WIKI.db.tree.deleteFolder(args.folderId) - - return { - operation: generateSuccess('Folder deleted successfully') - } - } catch (err) { - WIKI.logger.debug(`Failed to delete folder ${args.folderId}: ${err.message}`) - return generateError(err) - } - } - }, - TreeItem: { - __resolveType (obj, context, info) { - return typeResolvers[obj.type] ?? null - } - } -} diff --git a/server/graph/resolvers/user.mjs b/server/graph/resolvers/user.mjs deleted file mode 100644 index 249247339..000000000 --- a/server/graph/resolvers/user.mjs +++ /dev/null @@ -1,475 +0,0 @@ -import { generateError, generateSuccess } from '../../helpers/graph.mjs' -import { find, isNil, mapValues, transform } from 'lodash-es' -import path from 'node:path' -import fs from 'fs-extra' -import { DateTime } from 'luxon' -import bcrypt from 'bcryptjs' - -export default { - Query: { - /** - * FETCH ALL USERS - */ - async users (obj, args, context, info) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:users', 'write:users', 'manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - // -> Sanitize limit - let limit = args.pageSize ?? 20 - if (limit < 1 || limit > 1000) { - limit = 1000 - } - - // -> Sanitize offset - let offset = args.page ?? 1 - if (offset < 1) { - offset = 1 - } - - // -> Fetch Users - const total = await WIKI.db.users.query().count('id').first() - const users = await WIKI.db.users.query() - .select('id', 'email', 'name', 'isSystem', 'isActive', 'createdAt', 'lastLoginAt') - .where(builder => { - if (args.filter) { - builder.where('email', 'like', `%${args.filter}%`) - .orWhere('name', 'like', `%${args.filter}%`) - } - }) - .orderBy(args.orderBy ?? 'name', args.orderByDirection ?? 'asc') - .offset((offset - 1) * limit) - .limit(limit) - - return { - users, - total: total.count - } - }, - /** - * FETCH A SINGLE USER - */ - async userById (obj, args, context, info) { - if (!context.req.isAuthenticated || context.req.user.id !== args.id) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:users', 'write:users', 'manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - } - - const usr = await WIKI.db.users.query().findById(args.id) - - if (!usr) { - throw new Error('ERR_INVALID_USER') - } - - // const str = _.get(WIKI.auth.strategies, usr.providerKey) - // str.strategy = _.find(WIKI.data.authentication, ['key', str.strategyKey]) - // usr.providerName = str.displayName - // usr.providerIs2FACapable = _.get(str, 'strategy.useForm', false) - - usr.auth = mapValues(usr.auth, (auth, providerKey) => { - if (auth.password) { - auth.password = 'redacted' - } - if (auth.tfaSecret) { - auth.tfaSecret = 'redacted' - } - return auth - }) - - usr.passkeys = usr.passkeys.authenticators?.map(a => ({ - id: a.id, - createdAt: DateTime.fromISO(a.createdAt).toJSDate(), - name: a.name, - siteHostname: a.rpID - })) ?? [] - - return usr - }, - - async userDefaults (obj, args, context) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:users', 'write:users', 'manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.config.userDefaults - }, - - async userEditorSettings (obj, args, context) { - if (!context.req.user || context.req.user.id === WIKI.auth.guest.id) { - throw new WIKI.Error.AuthRequired() - } - - const config = await WIKI.db.knex('userEditorSettings').first('config').where({ - id: context.req.user.id, - editor: args.editor - }) - return config ?? {} - }, - - async lastLogins (obj, args, context, info) { - if (!WIKI.auth.checkAccess(context.req.user, ['read:dashboard', 'read:users', 'write:users', 'manage:users'])) { - throw new Error('ERR_FORBIDDEN') - } - - return WIKI.db.users.query() - .select('id', 'name', 'lastLoginAt') - .whereNotNull('lastLoginAt') - .orderBy('lastLoginAt', 'desc') - .limit(10) - }, - - async userPermissions (obj, args, context) { - if (!context.req.user || context.req.user.id === WIKI.auth.guest.id) { - throw new WIKI.Error.AuthRequired() - } - - const currentUser = await WIKI.db.users.getById(context.req.user.id) - return currentUser.getPermissions() - }, - async userPermissionsAtPath (obj, args, context) { - return [] - } - }, - Mutation: { - async createUser (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['write:users', 'manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.users.createNewUser({ ...args, isVerified: true }) - - return { - operation: generateSuccess('User created successfully') - } - } catch (err) { - return generateError(err) - } - }, - async deleteUser (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - if (args.id === WIKI.auth.guest.id) { - throw new WIKI.Error.UserDeleteProtected() - } - await WIKI.db.users.deleteUser(args.id, args.replaceId) - - WIKI.auth.revokeUserTokens({ id: args.id, kind: 'u' }) - WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'u' }) - - return { - operation: generateSuccess('User deleted successfully') - } - } catch (err) { - return generateError(err) - } - }, - async updateUser (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.users.updateUser(args.id, args.patch) - - return { - operation: generateSuccess('User updated successfully') - } - } catch (err) { - return generateError(err) - } - }, - async verifyUser (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.users.query().patch({ isVerified: true }).findById(args.id) - - return { - operation: generateSuccess('User verified successfully') - } - } catch (err) { - return generateError(err) - } - }, - async activateUser (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.users.query().patch({ isActive: true }).findById(args.id) - - return { - operation: generateSuccess('User activated successfully') - } - } catch (err) { - return generateError(err) - } - }, - async deactivateUser (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - if (args.id <= 2) { - throw new Error('Cannot deactivate system accounts.') - } - await WIKI.db.users.query().patch({ isActive: false }).findById(args.id) - - WIKI.auth.revokeUserTokens({ id: args.id, kind: 'u' }) - WIKI.events.outbound.emit('addAuthRevoke', { id: args.id, kind: 'u' }) - - return { - operation: generateSuccess('User deactivated successfully') - } - } catch (err) { - return generateError(err) - } - }, - async enableUserTFA (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.users.query().patch({ tfaIsActive: true, tfaSecret: null }).findById(args.id) - - return { - operation: generateSuccess('User 2FA enabled successfully') - } - } catch (err) { - return generateError(err) - } - }, - async disableUserTFA (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - await WIKI.db.users.query().patch({ tfaIsActive: false, tfaSecret: null }).findById(args.id) - - return { - operation: generateSuccess('User 2FA disabled successfully') - } - } catch (err) { - return generateError(err) - } - }, - async changeUserPassword (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - if (args.newPassword?.length < 8) { - throw new Error('ERR_PASSWORD_TOO_SHORT') - } - - const usr = await WIKI.db.users.query().findById(args.id) - if (!usr) { - throw new Error('ERR_INVALID_USER') - } - const localAuth = await WIKI.db.authentication.getStrategy('local') - - usr.auth[localAuth.id].password = await bcrypt.hash(args.newPassword, 12) - if (!isNil(args.mustChangePassword)) { - usr.auth[localAuth.id].mustChangePwd = args.mustChangePassword - } - - await WIKI.db.users.query().patch({ - auth: usr.auth - }).findById(args.id) - - return { - operation: generateSuccess('User password updated successfully') - } - } catch (err) { - return generateError(err) - } - }, - async updateProfile (obj, args, context) { - try { - if (!context.req.user || context.req.user.id === WIKI.auth.guest.id) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - const usr = await WIKI.db.users.query().findById(context.req.user.id) - if (!usr.isActive) { - throw new Error('ERR_INACTIVE_USER') - } - if (!usr.isVerified) { - throw new Error('ERR_USER_NOT_VERIFIED') - } - - if (args.dateFormat && !['', 'DD/MM/YYYY', 'DD.MM.YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD', 'YYYY/MM/DD'].includes(args.dateFormat)) { - throw new Error('ERR_INVALID_INPUT') - } - - if (args.appearance && !['site', 'light', 'dark'].includes(args.appearance)) { - throw new Error('ERR_INVALID_INPUT') - } - - await WIKI.db.users.query().findById(usr.id).patch({ - name: args.name?.trim() ?? usr.name, - meta: { - ...usr.meta, - location: args.location?.trim() ?? usr.meta.location, - jobTitle: args.jobTitle?.trim() ?? usr.meta.jobTitle, - pronouns: args.pronouns?.trim() ?? usr.meta.pronouns - }, - prefs: { - ...usr.prefs, - timezone: args.timezone || usr.prefs.timezone, - dateFormat: args.dateFormat ?? usr.prefs.dateFormat, - timeFormat: args.timeFormat ?? usr.prefs.timeFormat, - appearance: args.appearance || usr.prefs.appearance, - cvd: args.cvd || usr.prefs.cvd - } - }) - - return { - operation: generateSuccess('User profile updated successfully') - } - } catch (err) { - return generateError(err) - } - }, - /** - * UPLOAD USER AVATAR - */ - async uploadUserAvatar (obj, args, context) { - try { - if (!context.req.user || context.req.user.id === WIKI.auth.guest.id) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - const usr = await WIKI.db.users.query().findById(context.req.user.id) - if (!usr) { - throw new Error('ERR_INVALID_USER') - } - - const { filename, mimetype, createReadStream } = await args.image - const lowercaseFilename = filename.toLowerCase() - WIKI.logger.debug(`Processing user ${args.id} avatar ${lowercaseFilename} of type ${mimetype}...`) - if (!WIKI.extensions.ext.sharp.isInstalled) { - throw new Error('This feature requires the Sharp extension but it is not installed. Contact your wiki administrator.') - } - if (!['.png', '.jpg', '.webp', '.gif'].some(s => lowercaseFilename.endsWith(s))) { - throw new Error('Invalid File Extension. Must be png, jpg, webp or gif.') - } - const destFolder = path.resolve( - process.cwd(), - WIKI.config.dataPath, - 'assets' - ) - const destPath = path.join(destFolder, `userav-${args.id}.jpg`) - await fs.ensureDir(destFolder) - // -> Resize - await WIKI.extensions.ext.sharp.resize({ - format: 'jpg', - inputStream: createReadStream(), - outputPath: destPath, - width: 180, - height: 180 - }) - // -> Set avatar flag for this user in the DB - usr.$query().patch({ hasAvatar: true }) - // -> Save image data to DB - const imgBuffer = await fs.readFile(destPath) - await WIKI.db.knex('userAvatars').insert({ - id: args.id, - data: imgBuffer - }).onConflict('id').merge() - WIKI.logger.debug(`Processed user ${args.id} avatar successfully.`) - return { - operation: generateSuccess('User avatar uploaded successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * CLEAR USER AVATAR - */ - async clearUserAvatar (obj, args, context) { - try { - if (!context.req.user || context.req.user.id === WIKI.auth.guest.id) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - const usr = await WIKI.db.users.query().findById(context.req.user.id) - if (!usr) { - throw new Error('ERR_INVALID_USER') - } - - WIKI.logger.debug(`Clearing user ${args.id} avatar...`) - usr.$query.patch({ hasAvatar: false }) - await WIKI.db.knex('userAvatars').where({ id: args.id }).del() - WIKI.logger.debug(`Cleared user ${args.id} avatar successfully.`) - return { - operation: generateSuccess('User avatar cleared successfully') - } - } catch (err) { - WIKI.logger.warn(err) - return generateError(err) - } - }, - /** - * UPDATE USER DEFAULTS - */ - async updateUserDefaults (obj, args, context) { - try { - if (!WIKI.auth.checkAccess(context.req.user, ['manage:users', 'manage:groups'])) { - throw new Error('ERR_FORBIDDEN') - } - - WIKI.config.userDefaults = { - timezone: args.timezone, - dateFormat: args.dateFormat, - timeFormat: args.timeFormat - } - await WIKI.configSvc.saveToDb(['userDefaults']) - return { - operation: generateSuccess('User defaults saved successfully') - } - } catch (err) { - return generateError(err) - } - } - }, - User: { - async auth (usr, args, context) { - const authStrategies = await WIKI.db.authentication.getStrategies({ enabledOnly: true }) - return transform(usr.auth, (result, value, key) => { - const authStrategy = find(authStrategies, ['id', key]) - const authModule = find(WIKI.data.authentication, ['key', authStrategy.module]) - if (!authStrategy || !authModule) { return } - result.push({ - authId: key, - authName: authStrategy.displayName, - strategyKey: authStrategy.module, - strategyIcon: authModule.icon, - config: authStrategy.module === 'local' - ? { - isPasswordSet: value.password?.length > 0, - isTfaSetup: value.tfaIsActive && value.tfaSecret?.length > 0, - isTfaRequired: (value.tfaRequired || authStrategy.config.enforceTfa) ?? false, - mustChangePwd: value.mustChangePwd ?? false, - restrictLogin: value.restrictLogin ?? false - } - : value - }) - }, []) - }, - groups (usr) { - return usr.$relatedQuery('groups') - } - } -} diff --git a/server/graph/scalars/date.mjs b/server/graph/scalars/date.mjs deleted file mode 100644 index 8b67f22a6..000000000 --- a/server/graph/scalars/date.mjs +++ /dev/null @@ -1,27 +0,0 @@ -import gql from 'graphql' -import { DateTime } from 'luxon' - -function parseDateTime (value) { - const nDate = DateTime.fromISO(value) - return nDate.isValid ? nDate : null -} - -export default new gql.GraphQLScalarType({ - name: 'Date', - description: 'ISO date-time string at UTC', - parseValue(value) { - if (typeof value !== 'string') { - throw new TypeError('Date value must be an string!') - } - return parseDateTime(value) - }, - serialize(value) { - return value.toISOString() - }, - parseLiteral(ast) { - if (ast.kind !== gql.Kind.STRING) { - throw new TypeError('Date value must be an string!') - } - return parseDateTime(ast.value) - } -}) diff --git a/server/graph/scalars/json.mjs b/server/graph/scalars/json.mjs deleted file mode 100644 index 1513bde03..000000000 --- a/server/graph/scalars/json.mjs +++ /dev/null @@ -1,57 +0,0 @@ -import { Kind, GraphQLScalarType } from 'graphql' - -function ensureObject (value) { - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - throw new TypeError(`JSONObject cannot represent non-object value: ${value}`) - } - - return value -} - -function parseLiteral (typeName, ast, variables) { - switch (ast.kind) { - case Kind.STRING: - case Kind.BOOLEAN: - return ast.value - case Kind.INT: - case Kind.FLOAT: - return parseFloat(ast.value) - case Kind.OBJECT: - return parseObject(typeName, ast, variables) - case Kind.LIST: - return ast.values.map((n) => parseLiteral(typeName, n, variables)) - case Kind.NULL: - return null - case Kind.VARIABLE: - return variables ? variables[ast.name.value] : undefined - default: - throw new TypeError(`${typeName} cannot represent value: ${ast}`) - } -} - -function parseObject (typeName, ast, variables) { - const value = Object.create(null) - ast.fields.forEach((field) => { - // eslint-disable-next-line no-use-before-define - value[field.name.value] = parseLiteral(typeName, field.value, variables) - }) - - return value -} - -export default new GraphQLScalarType({ - name: 'JSON', - description: - 'The `JSON` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).', - specifiedByUrl: - 'http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf', - serialize: ensureObject, - parseValue: ensureObject, - parseLiteral: (ast, variables) => { - if (ast.kind !== Kind.OBJECT) { - throw new TypeError(`JSONObject cannot represent non-object value: ${ast}`) - } - - return parseObject('JSONObject', ast, variables) - } -}) diff --git a/server/graph/scalars/uuid.mjs b/server/graph/scalars/uuid.mjs deleted file mode 100644 index 4311a0211..000000000 --- a/server/graph/scalars/uuid.mjs +++ /dev/null @@ -1,36 +0,0 @@ -import { Kind, GraphQLScalarType } from 'graphql' - -const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i -const nilUUID = '00000000-0000-0000-0000-000000000000' - -function isUUID (value) { - return uuidRegex.test(value) || nilUUID === value -} - -export default new GraphQLScalarType({ - name: 'UUID', - description: 'The `UUID` scalar type represents UUID values as specified by [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122).', - serialize: (value) => { - if (!isUUID(value)) { - throw new TypeError(`UUID cannot represent non-UUID value: ${value}`) - } - - return value.toLowerCase() - }, - parseValue: (value) => { - if (!isUUID(value)) { - throw new TypeError(`UUID cannot represent non-UUID value: ${value}`) - } - - return value.toLowerCase() - }, - parseLiteral: (ast) => { - if (ast.kind === Kind.STRING) { - if (isUUID(ast.value)) { - return ast.value - } - } - - return undefined - } -}) diff --git a/server/graph/schemas/analytics.graphql b/server/graph/schemas/analytics.graphql deleted file mode 100644 index 7fbd59415..000000000 --- a/server/graph/schemas/analytics.graphql +++ /dev/null @@ -1,73 +0,0 @@ -# =============================================== -# ANALYTICS -# =============================================== - -extend type Query { - """ - Fetch list of Analytics providers and their configuration - """ - analyticsProviders( - "Return only active providers" - isEnabled: Boolean - ): [AnalyticsProvider] -} - -extend type Mutation { - """ - Update a list of Analytics providers and their configuration - """ - updateAnalyticsProviders( - "List of providers" - providers: [AnalyticsProviderInput]! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -""" -Analytics Provider -""" -type AnalyticsProvider { - "Is the provider active" - isEnabled: Boolean! - - "Unique identifier for this provider" - key: String! - - "List of configuration properties, formatted as stringified JSON objects" - props: [String] - - "Name of the provider" - title: String! - - "Short description of the provider" - description: String - - "Is the provider available for use" - isAvailable: Boolean - - "Path to the provider logo" - logo: String - - "Website of the provider" - website: String - - "Configuration values for this provider" - config: [KeyValuePair] -} - -""" -Analytics Configuration Input -""" -input AnalyticsProviderInput { - "Is the provider active" - isEnabled: Boolean! - - "Unique identifier of the provider" - key: String! - - "Configuration values for this provider" - config: [KeyValuePairInput] -} diff --git a/server/graph/schemas/asset.graphql b/server/graph/schemas/asset.graphql deleted file mode 100644 index b396f1295..000000000 --- a/server/graph/schemas/asset.graphql +++ /dev/null @@ -1,57 +0,0 @@ -# =============================================== -# ASSETS -# =============================================== - -extend type Query { - assetById( - id: UUID! - ): AssetItem -} - -extend type Mutation { - renameAsset( - id: UUID! - fileName: String! - ): DefaultResponse - - deleteAsset( - id: UUID! - ): DefaultResponse - - """ - Upload one or more assets. - Must provide either `folderId` or a combination of `folderPath`, `locale` and `siteId`. - """ - uploadAssets( - folderId: UUID - folderPath: String - locale: String - siteId: UUID - files: [Upload!]! - ): DefaultResponse - - flushTempUploads: DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type AssetItem { - id: UUID - fileName: String - ext: String - kind: AssetKind - mime: String - fileSize: Int - metadata: JSON - createdAt: Date - updatedAt: Date - author: User -} - -enum AssetKind { - document - image - other -} diff --git a/server/graph/schemas/authentication.graphql b/server/graph/schemas/authentication.graphql deleted file mode 100644 index 13fcbae51..000000000 --- a/server/graph/schemas/authentication.graphql +++ /dev/null @@ -1,213 +0,0 @@ -# =============================================== -# AUTHENTICATION -# =============================================== - -extend type Query { - apiKeys: [AuthenticationApiKey] - - apiState: Boolean - - authStrategies: [AuthenticationStrategy] - - authActiveStrategies( - enabledOnly: Boolean - ): [AuthenticationActiveStrategy] - - authSiteStrategies( - siteId: UUID! - visibleOnly: Boolean - ): [AuthenticationSiteStrategy] -} - -extend type Mutation { - createApiKey( - name: String! - expiration: String! - groups: [UUID]! - ): AuthenticationCreateApiKeyResponse - - login( - username: String! - password: String! - strategyId: UUID! - siteId: UUID! - ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60) - - loginTFA( - continuationToken: String! - securityCode: String! - strategyId: UUID! - siteId: UUID! - setup: Boolean - ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60) - - setupTFA( - strategyId: UUID! - siteId: UUID! - ): AuthenticationSetupTFAResponse - - deactivateTFA( - strategyId: UUID! - ): DefaultResponse - - setupPasskey( - siteId: UUID! - ): AuthenticationSetupPasskeyResponse - - finalizePasskey( - registrationResponse: JSON! - name: String! - ): DefaultResponse - - deactivatePasskey( - id: UUID! - ): DefaultResponse - - authenticatePasskeyGenerate( - email: String! - siteId: UUID! - ): AuthenticationPasskeyResponse @rateLimit(limit: 5, duration: 60) - - authenticatePasskeyVerify( - authResponse: JSON! - ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60) - - changePassword( - continuationToken: String - currentPassword: String - newPassword: String! - strategyId: UUID! - siteId: UUID! - ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60) - - forgotPassword( - email: String! - ): DefaultResponse @rateLimit(limit: 3, duration: 60) - - register( - email: String! - password: String! - name: String! - ): AuthenticationAuthResponse @rateLimit(limit: 5, duration: 60) - - refreshToken( - token: String! - ): AuthenticationTokenResponse @rateLimit(limit: 30, duration: 60) - - revokeApiKey( - id: UUID! - ): DefaultResponse - - setApiState( - enabled: Boolean! - ): DefaultResponse - - updateAuthStrategies( - strategies: [AuthenticationStrategyInput]! - ): DefaultResponse - - regenerateCertificates: DefaultResponse - - resetGuestUser: DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type AuthenticationStrategy { - key: String - props: JSON - refs: JSON - title: String - description: String - isAvailable: Boolean - useForm: Boolean - usernameType: String - logo: String - color: String - vendor: String - website: String - icon: String -} - -type AuthenticationActiveStrategy { - id: UUID - strategy: AuthenticationStrategy - displayName: String - isEnabled: Boolean - config: JSON - registration: Boolean - allowedEmailRegex: String - autoEnrollGroups: [UUID] -} - -type AuthenticationSiteStrategy { - id: UUID - activeStrategy: AuthenticationActiveStrategy - isVisible: Boolean -} - -type AuthenticationAuthResponse { - operation: Operation - jwt: String - nextAction: AuthenticationNextAction - continuationToken: String - redirect: String - tfaQRImage: String -} - -type AuthenticationTokenResponse { - operation: Operation - jwt: String -} - -type AuthenticationSetupTFAResponse { - operation: Operation - continuationToken: String - tfaQRImage: String -} - -type AuthenticationSetupPasskeyResponse { - operation: Operation - registrationOptions: JSON -} - -type AuthenticationPasskeyResponse { - operation: Operation - authOptions: JSON -} - -input AuthenticationStrategyInput { - key: String! - strategyKey: String! - config: JSON! - displayName: String! - order: Int! - isEnabled: Boolean! - registration: Boolean! - allowedEmailRegex: String! - autoEnrollGroups: [UUID]! -} - -type AuthenticationApiKey { - id: UUID - name: String - keyShort: String - expiration: Date - createdAt: Date - updatedAt: Date - isRevoked: Boolean -} - -type AuthenticationCreateApiKeyResponse { - operation: Operation - key: String -} - -enum AuthenticationNextAction { - changePassword - setupTfa - provideTfa - redirect -} diff --git a/server/graph/schemas/block.graphql b/server/graph/schemas/block.graphql deleted file mode 100644 index 430e0f06b..000000000 --- a/server/graph/schemas/block.graphql +++ /dev/null @@ -1,40 +0,0 @@ -# =============================================== -# BLOCKS -# =============================================== - -extend type Query { - blocks( - siteId: UUID! - ): [Block] -} - -extend type Mutation { - setBlocksState( - siteId: UUID! - states: [BlockStateInput]! - ): DefaultResponse - - deleteBlock( - id: UUID! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type Block { - id: UUID - block: String - name: String - description: String - icon: String - isEnabled: Boolean - isCustom: Boolean - config: JSON -} - -input BlockStateInput { - id: UUID! - isEnabled: Boolean! -} diff --git a/server/graph/schemas/comment.graphql b/server/graph/schemas/comment.graphql deleted file mode 100644 index be30b7fe2..000000000 --- a/server/graph/schemas/comment.graphql +++ /dev/null @@ -1,82 +0,0 @@ -# =============================================== -# COMMENT -# =============================================== - -extend type Query { - commentsProviders: [CommentProvider] - - comments( - locale: String! - path: String! - ): [CommentPost]! - - commentById( - id: Int! - ): CommentPost -} - -extend type Mutation { - updateCommentsProviders( - providers: [CommentProviderInput] - ): DefaultResponse - - createComment( - pageId: Int! - replyTo: Int - content: String! - guestName: String - guestEmail: String - ): CommentCreateResponse @rateLimit(limit: 1, duration: 15) - - updateComment( - id: Int! - content: String! - ): CommentUpdateResponse - - deleteComment( - id: Int! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type CommentProvider { - isEnabled: Boolean - key: String - title: String - description: String - logo: String - website: String - isAvailable: Boolean - config: [KeyValuePair] -} - -input CommentProviderInput { - isEnabled: Boolean! - key: String! - config: [KeyValuePairInput] -} - -type CommentPost { - id: Int - content: String - render: String - authorId: Int - authorName: String - authorEmail: String - authorIP: String - createdAt: Date - updatedAt: Date -} - -type CommentCreateResponse { - operation: Operation - id: Int -} - -type CommentUpdateResponse { - operation: Operation - render: String -} diff --git a/server/graph/schemas/common.graphql b/server/graph/schemas/common.graphql deleted file mode 100644 index 0954f435f..000000000 --- a/server/graph/schemas/common.graphql +++ /dev/null @@ -1,48 +0,0 @@ -# ====================== # -# Wiki.js GraphQL Schema # -# ====================== # - -# DIRECTIVES (deprecated) -# ---------- - -directive @auth(requires: [String]) on QUERY | FIELD_DEFINITION | ARGUMENT_DEFINITION - -# TYPES -# ----- - -# Generic Key Value Pair -type KeyValuePair { - key: String - value: String -} -# General Key Value Pair Input -input KeyValuePairInput { - key: String! - value: String! -} - -# Generic Mutation Response -type DefaultResponse { - operation: Operation -} - -# Mutation Operation -type Operation { - succeeded: Boolean - slug: String - message: String -} - -enum OrderByDirection { - asc - desc -} - -# ROOT -# ---- - -# Query (Read) -type Query - -# Mutations (Create, Update, Delete) -type Mutation diff --git a/server/graph/schemas/group.graphql b/server/graph/schemas/group.graphql deleted file mode 100644 index 7a9a43a10..000000000 --- a/server/graph/schemas/group.graphql +++ /dev/null @@ -1,110 +0,0 @@ -# =============================================== -# GROUPS -# =============================================== - -extend type Query { - groups( - filter: String - orderBy: String - ): [Group] - - groupById( - id: UUID! - ): Group -} - -extend type Mutation { - createGroup( - name: String! - ): GroupResponse - - updateGroup( - id: UUID! - name: String! - redirectOnLogin: String! - permissions: [String]! - rules: [GroupRuleInput]! - ): DefaultResponse - - deleteGroup( - id: UUID! - ): DefaultResponse - - assignUserToGroup( - groupId: UUID! - userId: UUID! - ): DefaultResponse - - unassignUserFromGroup( - groupId: UUID! - userId: UUID! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type GroupResponse { - operation: Operation - group: Group -} - -type Group { - id: UUID - name: String - isSystem: Boolean - redirectOnLogin: String - redirectOnFirstLogin: String - redirectOnLogout: String - permissions: [String] - rules: [GroupRule] - users( - page: Int - pageSize: Int - orderBy: UserOrderBy - orderByDirection: OrderByDirection - # Filter by name / email - filter: String - ): [UserMinimal] - userCount: Int - createdAt: Date - updatedAt: Date -} - -type GroupRule { - id: UUID - name: String - mode: GroupRuleMode - match: GroupRuleMatch - roles: [String] - path: String - locales: [String] - sites: [UUID] -} - -input GroupRuleInput { - id: UUID! - name: String! - mode: GroupRuleMode! - match: GroupRuleMatch! - roles: [String]! - path: String! - locales: [String]! - sites: [UUID] -} - -enum GroupRuleMode { - ALLOW - DENY - FORCEALLOW -} - -enum GroupRuleMatch { - START - EXACT - END - REGEX - TAG - TAGALL -} diff --git a/server/graph/schemas/hooks.graphql b/server/graph/schemas/hooks.graphql deleted file mode 100644 index 23742729f..000000000 --- a/server/graph/schemas/hooks.graphql +++ /dev/null @@ -1,70 +0,0 @@ -# =============================================== -# WEBHOOKS -# =============================================== - -extend type Query { - hooks: [Hook] - - hookById( - id: UUID! - ): Hook -} - -extend type Mutation { - createHook( - name: String! - events: [String]! - url: String! - includeMetadata: Boolean! - includeContent: Boolean! - acceptUntrusted: Boolean! - authHeader: String - ): HookCreateResponse - - updateHook( - id: UUID! - patch: HookUpdateInput! - ): DefaultResponse - - deleteHook ( - id: UUID! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type Hook { - id: UUID - name: String - events: [String] - url: String - includeMetadata: Boolean - includeContent: Boolean - acceptUntrusted: Boolean - authHeader: String - state: HookState - lastErrorMessage: String -} - -input HookUpdateInput { - name: String - events: [String] - url: String - includeMetadata: Boolean - includeContent: Boolean - acceptUntrusted: Boolean - authHeader: String -} - -enum HookState { - pending - error - success -} - -type HookCreateResponse { - operation: Operation - hook: Hook -} diff --git a/server/graph/schemas/localization.graphql b/server/graph/schemas/localization.graphql deleted file mode 100644 index 0c6901519..000000000 --- a/server/graph/schemas/localization.graphql +++ /dev/null @@ -1,25 +0,0 @@ -# =============================================== -# LOCALIZATION -# =============================================== - -extend type Query { - locales: [LocalizationLocale] - localeStrings(locale: String!): JSON -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type LocalizationLocale { - completeness: Int - code: String - createdAt: Date - isRTL: Boolean - language: String - name: String - nativeName: String - region: String - script: String - updatedAt: Date -} diff --git a/server/graph/schemas/mail.graphql b/server/graph/schemas/mail.graphql deleted file mode 100644 index 94e9e0cc9..000000000 --- a/server/graph/schemas/mail.graphql +++ /dev/null @@ -1,51 +0,0 @@ -# =============================================== -# MAIL -# =============================================== - -extend type Query { - mailConfig: MailConfig -} - -extend type Mutation { - sendMailTest( - recipientEmail: String! - ): DefaultResponse - - updateMailConfig( - senderName: String! - senderEmail: String! - defaultBaseURL: String! - host: String! - port: Int! - name: String! - secure: Boolean! - verifySSL: Boolean! - user: String! - pass: String! - useDKIM: Boolean! - dkimDomainName: String! - dkimKeySelector: String! - dkimPrivateKey: String! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type MailConfig { - senderName: String - senderEmail: String - defaultBaseURL: String - host: String - port: Int - name: String - secure: Boolean - verifySSL: Boolean - user: String - pass: String - useDKIM: Boolean - dkimDomainName: String - dkimKeySelector: String - dkimPrivateKey: String -} diff --git a/server/graph/schemas/navigation.graphql b/server/graph/schemas/navigation.graphql deleted file mode 100644 index aa52fccd9..000000000 --- a/server/graph/schemas/navigation.graphql +++ /dev/null @@ -1,67 +0,0 @@ -# =============================================== -# NAVIGATION -# =============================================== - -extend type Query { - navigationById( - id: UUID! - ): [NavigationItem] -} - -# ----------------------------------------------- -# MUTATIONS -# ----------------------------------------------- - -extend type Mutation { - updateNavigation( - pageId: UUID! - mode: NavigationMode! - items: [NavigationItemInput!] - ): NavigationUpdateResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type NavigationItem { - id: UUID - type: NavigationItemType - label: String - icon: String - target: String - openInNewWindow: Boolean - visibilityGroups: [UUID] - children: [NavigationItem] -} - -input NavigationItemInput { - id: UUID! - type: NavigationItemType! - label: String - icon: String - target: String - openInNewWindow: Boolean - visibilityGroups: [UUID!]! - children: [NavigationItemInput!] -} - -enum NavigationItemType { - header - link - separator -} - -enum NavigationMode { - inherit - override - overrideExact - hide - hideExact -} - -type NavigationUpdateResponse { - operation: Operation - navigationMode: NavigationMode - navigationId: UUID -} diff --git a/server/graph/schemas/page.graphql b/server/graph/schemas/page.graphql deleted file mode 100644 index 47fe2a3a7..000000000 --- a/server/graph/schemas/page.graphql +++ /dev/null @@ -1,473 +0,0 @@ -# =============================================== -# PAGES -# =============================================== - -extend type Query { - pageHistoryById( - id: Int! - offsetPage: Int - offsetSize: Int - ): PageHistoryResult - - pageVersionById( - pageId: Int! - versionId: Int! - ): PageVersion - - searchPages( - """ - Site ID to search in (required) - """ - siteId: UUID! - """ - Search Query (required) - """ - query: String! - """ - The locale to perform the query as. Affects how the query is parsed by the search engine. - """ - queryLocale: String - """ - Only match pages that starts with the provided path. - """ - path: String - """ - Only match pages having one of the provided locales. - """ - locale: [String] - """ - Only match pages having one of the provided tags. - """ - tags: [String] - """ - Only match pages using the provided editor. - """ - editor: String - """ - Only match pages is the provided state. - """ - publishState: PagePublishState - """ - Result ordering. Defaults to relevancy. - """ - orderBy: PageSearchSort - """ - Result ordering direction. Defaults to descending. - """ - orderByDirection: OrderByDirection - """ - Result offset. Defaults to 0. - """ - offset: Int - """ - Results amount to return. Defaults to 25. Maximum 100. - """ - limit: Int - ): PageSearchResponse - - searchPagesAutocomplete( - siteId: UUID! - query: String! - ): [String] - - pages( - limit: Int - orderBy: PageOrderBy - orderByDirection: PageOrderByDirection - tags: [String!] - locale: String - creatorId: Int - authorId: Int - ): [PageListItem] - - pageById( - id: UUID! - password: String - ): Page - - pageByPath( - siteId: UUID! - path: String! - password: String - ): Page - - pageTree( - path: String - parent: Int - mode: PageTreeMode! - locale: String! - includeAncestors: Boolean - ): [PageTreeItem] - - pageLinks( - locale: String! - ): [PageLinkItem] - - pathFromAlias( - siteId: UUID! - alias: String! - ): PageAliasPath - - tags( - siteId: UUID! - ): [PageTag] - - checkConflicts( - id: Int! - checkoutDate: Date! - ): Boolean - - checkConflictsLatest( - id: Int! - ): PageConflictLatest -} - -extend type Mutation { - createPage( - alias: String - allowComments: Boolean - allowContributions: Boolean - allowRatings: Boolean - content: String! - description: String! - editor: String! - icon: String - isBrowsable: Boolean - isSearchable: Boolean - locale: String! - path: String! - publishState: PagePublishState! - publishEndDate: Date - publishStartDate: Date - relations: [PageRelationInput!] - scriptCss: String - scriptJsLoad: String - scriptJsUnload: String - showSidebar: Boolean - showTags: Boolean - showToc: Boolean - siteId: UUID! - tags: [String!] - title: String! - tocDepth: PageTocDepthInput - ): PageResponse - - updatePage( - id: UUID! - patch: PageUpdateInput! - ): PageResponse - - convertPage( - id: UUID! - editor: String! - ): DefaultResponse - - movePage( - id: UUID! - destinationLocale: String! - destinationPath: String! - title: String - ): DefaultResponse - - deletePage( - id: UUID! - ): DefaultResponse - - deleteTag( - id: Int! - ): DefaultResponse - - updateTag( - id: Int! - tag: String! - title: String! - ): DefaultResponse - - flushCache: DefaultResponse - - migrateToLocale( - sourceLocale: String! - targetLocale: String! - ): PageMigrationResponse - - rebuildPageTree: DefaultResponse - - rerenderPage( - id: UUID! - ): DefaultResponse - - restorePage( - pageId: Int! - versionId: Int! - ): DefaultResponse - - purgePagesHistory ( - olderThan: String! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type PageResponse { - operation: Operation - page: Page -} - -type PageMigrationResponse { - operation: Operation - count: Int -} - -type Page { - alias: String - allowComments: Boolean - allowContributions: Boolean - allowRatings: Boolean - author: User - content: String - contentType: String - createdAt: Date - creator: User - description: String - editor: String - hash: String - icon: String - id: UUID - isBrowsable: Boolean - isSearchable: Boolean - locale: String - navigationId: UUID - navigationMode: NavigationMode - password: String - path: String - publishEndDate: Date - publishStartDate: Date - publishState: PagePublishState - relations: [PageRelation] - render: String - scriptJsLoad: String - scriptJsUnload: String - scriptCss: String - showSidebar: Boolean - showTags: Boolean - showToc: Boolean - siteId: UUID - tags: [String] - title: String - toc: [JSON] - tocDepth: PageTocDepth - updatedAt: Date -} - -type PageTag { - id: UUID - tag: String - usageCount: Int - siteId: UUID - createdAt: Date - updatedAt: Date -} - -type PageHistory { - versionId: Int - versionDate: Date - authorId: Int - authorName: String - actionType: String - valueBefore: String - valueAfter: String -} - -type PageVersion { - action: String - authorId: String - authorName: String - content: String - contentType: String - createdAt: Date - versionDate: Date - description: String - editor: String - isPrivate: Boolean - isPublished: Boolean - locale: String - pageId: Int - path: String - publishEndDate: Date - publishStartDate: Date - render: String - tags: [String] - title: String - versionId: Int -} - -type PageHistoryResult { - trail: [PageHistory] - total: Int -} - -type PageSearchResponse { - results: [PageSearchResult] - totalHits: Int -} - -type PageSearchResult { - description: String - highlight: String - icon: String - id: UUID - locale: String - path: String - relevancy: Float - tags: [String] - title: String - updatedAt: Date -} - -type PageListItem { - id: Int - path: String - locale: String - title: String - description: String - contentType: String - isPublished: Boolean - isPrivate: Boolean - privateNS: String - createdAt: Date - updatedAt: Date - tags: [String] -} - -type PageTreeItem { - id: Int - path: String - depth: Int - title: String - isPrivate: Boolean - isFolder: Boolean - privateNS: String - parent: Int - pageId: Int - locale: String -} - -type PageLinkItem { - id: Int - path: String - title: String - links: [String] -} - -type PageConflictLatest { - id: Int - authorId: String - authorName: String - content: String - createdAt: Date - description: String - isPublished: Boolean - locale: String - path: String - tags: [String] - title: String - updatedAt: Date -} - -type PageRelation { - id: UUID - position: PageRelationPosition - label: String - caption: String - icon: String - target: String -} -input PageRelationInput { - id: UUID! - position: PageRelationPosition! - label: String! - caption: String - icon: String - target: String! -} - -input PageUpdateInput { - alias: String - allowComments: Boolean - allowContributions: Boolean - allowRatings: Boolean - content: String - description: String - icon: String - isBrowsable: Boolean - isSearchable: Boolean - password: String - publishEndDate: Date - publishStartDate: Date - publishState: PagePublishState - reasonForChange: String - relations: [PageRelationInput!] - scriptJsLoad: String - scriptJsUnload: String - scriptCss: String - showSidebar: Boolean - showTags: Boolean - showToc: Boolean - tags: [String!] - title: String - tocDepth: PageTocDepthInput -} - -type PageAliasPath { - id: UUID - path: String -} - -type PageTocDepth { - min: Int - max: Int -} - -input PageTocDepthInput { - min: Int! - max: Int! -} - -enum PageSearchSort { - relevancy - title - updatedAt -} - -enum PageOrderBy { - CREATED - ID - PATH - TITLE - UPDATED -} - -enum PageOrderByDirection { - ASC - DESC -} - -enum PageTreeMode { - FOLDERS - PAGES - ALL -} - -enum PagePublishState { - draft - published - scheduled -} - -enum PageRelationPosition { - left - center - right -} diff --git a/server/graph/schemas/rendering.graphql b/server/graph/schemas/rendering.graphql deleted file mode 100644 index 8bffa602d..000000000 --- a/server/graph/schemas/rendering.graphql +++ /dev/null @@ -1,38 +0,0 @@ -# =============================================== -# RENDERING -# =============================================== - -extend type Query { - renderers( - filter: String - orderBy: String - ): [Renderer] -} - -extend type Mutation { - updateRenderers( - renderers: [RendererInput]! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type Renderer { - isEnabled: Boolean - key: String - title: String - description: String - icon: String - dependsOn: String - input: String - output: String - config: [KeyValuePair] -} - -input RendererInput { - isEnabled: Boolean! - key: String! - config: [KeyValuePairInput] -} diff --git a/server/graph/schemas/scalars.graphql b/server/graph/schemas/scalars.graphql deleted file mode 100644 index 8a87430a5..000000000 --- a/server/graph/schemas/scalars.graphql +++ /dev/null @@ -1,6 +0,0 @@ -# SCALARS - -scalar Date -scalar JSON -scalar Upload -scalar UUID diff --git a/server/graph/schemas/site.graphql b/server/graph/schemas/site.graphql deleted file mode 100644 index 87603c559..000000000 --- a/server/graph/schemas/site.graphql +++ /dev/null @@ -1,246 +0,0 @@ -# =============================================== -# SITES -# =============================================== - -extend type Query { - sites: [Site] - - siteById ( - id: UUID! - ): Site - - siteByHostname ( - hostname: String! - exact: Boolean! - ): Site -} - -extend type Mutation { - createSite ( - hostname: String! - title: String! - ): SiteCreateResponse - - updateSite ( - id: UUID! - patch: SiteUpdateInput! - ): DefaultResponse - - uploadSiteLogo ( - id: UUID! - image: Upload! - ): DefaultResponse - - uploadSiteFavicon ( - id: UUID! - image: Upload! - ): DefaultResponse - - uploadSiteLoginBg ( - id: UUID! - image: Upload! - ): DefaultResponse - - deleteSite ( - id: UUID! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type Site { - id: UUID - hostname: String - isEnabled: Boolean - title: String - description: String - company: String - contentLicense: String - footerExtra: String - pageExtensions: String - pageCasing: Boolean - logoText: Boolean - sitemap: Boolean - robots: SiteRobots - features: SiteFeatures - discoverable: Boolean - defaults: SiteDefaults - uploads: SiteUploads - locales: SiteLocales - editors: SiteEditors - theme: SiteTheme -} - -type SiteRobots { - index: Boolean - follow: Boolean -} - -type SiteFeatures { - browse: Boolean - ratings: Boolean - ratingsMode: SitePageRatingMode - comments: Boolean - contributions: Boolean - profile: Boolean - reasonForChange: SiteReasonForChangeMode - search: Boolean -} - -type SiteDefaults { - tocDepth: PageTocDepth -} - -type SiteUploads { - conflictBehavior: SiteUploadConflictBehavior - normalizeFilename: Boolean -} - -type SiteLocales { - primary: String - active: [LocalizationLocale] -} - -type SiteEditors { - asciidoc: SiteEditor - markdown: SiteEditor - wysiwyg: SiteEditor -} - -type SiteEditor { - isActive: Boolean - config: JSON -} - -type SiteTheme { - dark: Boolean - codeBlocksTheme: String - colorPrimary: String - colorSecondary: String - colorAccent: String - colorHeader: String - colorSidebar: String - injectCSS: String - injectHead: String - injectBody: String - contentWidth: SiteThemeWidth - sidebarPosition: SiteThemePosition - tocPosition: SiteThemePosition - showSharingMenu: Boolean - showPrintBtn: Boolean - baseFont: String - contentFont: String -} - -enum SiteThemeWidth { - full - centered -} - -enum SiteThemePosition { - off - left - right -} - -enum SitePageRatingMode { - off - thumbs - stars -} - -enum SiteReasonForChangeMode { - off - optional - required -} - -enum SiteUploadConflictBehavior { - overwrite - reject - new -} - -type SiteCreateResponse { - operation: Operation - site: Site -} - -input SiteUpdateInput { - hostname: String - isEnabled: Boolean - title: String - description: String - company: String - contentLicense: String - footerExtra: String - pageExtensions: String - pageCasing: Boolean - logoText: Boolean - sitemap: Boolean - robots: SiteRobotsInput - features: SiteFeaturesInput - discoverable: Boolean - defaults: SiteDefaultsInput - uploads: SiteUploadsInput - editors: SiteEditorsInput - theme: SiteThemeInput -} - -input SiteRobotsInput { - index: Boolean - follow: Boolean -} - -input SiteFeaturesInput { - browse: Boolean - ratings: Boolean - ratingsMode: SitePageRatingMode - comments: Boolean - contributions: Boolean - profile: Boolean - reasonForChange: SiteReasonForChangeMode - search: Boolean -} - -input SiteDefaultsInput { - tocDepth: PageTocDepthInput -} - -input SiteThemeInput { - dark: Boolean - codeBlocksTheme: String - colorPrimary: String - colorSecondary: String - colorAccent: String - colorHeader: String - colorSidebar: String - injectCSS: String - injectHead: String - injectBody: String - contentWidth: SiteThemeWidth - sidebarPosition: SiteThemePosition - tocPosition: SiteThemePosition - showSharingMenu: Boolean - showPrintBtn: Boolean - baseFont: String - contentFont: String -} - -input SiteEditorsInput { - asciidoc: SiteEditorInput - markdown: SiteEditorInput - wysiwyg: SiteEditorInput -} - -input SiteEditorInput { - isActive: Boolean - config: JSON -} - -input SiteUploadsInput { - conflictBehavior: SiteUploadConflictBehavior - normalizeFilename: Boolean -} diff --git a/server/graph/schemas/storage.graphql b/server/graph/schemas/storage.graphql deleted file mode 100644 index b559fc796..000000000 --- a/server/graph/schemas/storage.graphql +++ /dev/null @@ -1,79 +0,0 @@ -# =============================================== -# STORAGE -# =============================================== - -extend type Query { - storageTargets( - siteId: UUID! - ): [StorageTarget] -} - -extend type Mutation { - updateStorageTargets( - siteId: UUID! - targets: [StorageTargetInput]! - ): DefaultResponse - - setupStorageTarget( - targetId: UUID! - state: JSON! - ): StorageTargetSetupResponse - - destroyStorageTargetSetup( - targetId: UUID! - ): DefaultResponse - - executeStorageAction( - targetId: UUID! - handler: String! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type StorageTarget { - id: UUID - isEnabled: Boolean - module: String - title: String - description: String - icon: String - banner: String - vendor: String - website: String - contentTypes: JSON - assetDelivery: JSON - versioning: JSON - sync: JSON - status: JSON - setup: JSON - config: JSON - actions: JSON -} - -type StorageTargetSetupResponse { - operation: Operation - state: JSON -} - -input StorageTargetInput { - id: UUID! - module: String! - isEnabled: Boolean - contentTypes: [String!] - largeThreshold: String - assetDeliveryFileStreaming: Boolean - assetDeliveryDirectAccess: Boolean - syncMode: StorageTargetSyncMode - syncInterval: String - useVersioning: Boolean - config: JSON -} - -enum StorageTargetSyncMode { - PULL - PUSH - SYNC -} diff --git a/server/graph/schemas/system.graphql b/server/graph/schemas/system.graphql deleted file mode 100644 index deff656d9..000000000 --- a/server/graph/schemas/system.graphql +++ /dev/null @@ -1,234 +0,0 @@ -# =============================================== -# SYSTEM -# =============================================== - -extend type Query { - metricsState: Boolean - systemExtensions: [SystemExtension] - systemFlags: JSON - systemInfo: SystemInfo - systemInstances: [SystemInstance] - systemSecurity: SystemSecurity - systemJobs( - states: [SystemJobState] - ): [SystemJob] - systemJobsScheduled: [SystemJobScheduled] - systemJobsUpcoming: [SystemJobUpcoming] - systemSearch: SystemSearch -} - -extend type Mutation { - cancelJob( - id: UUID! - ): DefaultResponse - - checkForUpdates: SystemCheckUpdateResponse - - disconnectWS: DefaultResponse - - installExtension( - key: String! - ): DefaultResponse - - rebuildSearchIndex: DefaultResponse - - retryJob( - id: UUID! - ): DefaultResponse - - setMetricsState( - enabled: Boolean! - ): DefaultResponse - - updateSystemSearch( - termHighlighting: Boolean - dictOverrides: String - ): DefaultResponse - - updateSystemFlags( - flags: JSON! - ): DefaultResponse - - updateSystemSecurity( - authJwtAudience: String - authJwtExpiration: String - authJwtRenewablePeriod: String - corsConfig: String - corsMode: SystemSecurityCorsMode - cspDirectives: String - disallowFloc: Boolean - disallowIframe: Boolean - disallowOpenRedirect: Boolean - enforceCsp: Boolean - enforceHsts: Boolean - enforceSameOriginReferrerPolicy: Boolean - forceAssetDownload: Boolean - hstsDuration: Int - trustProxy: Boolean - uploadMaxFiles: Int - uploadMaxFileSize: Int - uploadScanSVG: Boolean - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type SystemInfo { - configFile: String - cpuCores: Int - currentVersion: String - dbHost: String - dbType: String - dbVersion: String - groupsTotal: Int - hostname: String - httpPort: Int - httpRedirection: Boolean - httpsPort: Int - isMailConfigured: Boolean - isSchedulerHealthy: Boolean - latestVersion: String - latestVersionReleaseDate: Date - loginsPastDay: Int - nodeVersion: String - operatingSystem: String - pagesTotal: Int - platform: String - ramTotal: String - sslDomain: String - sslExpirationDate: Date - sslProvider: String - sslStatus: String - sslSubscriberEmail: String - tagsTotal: Int - upgradeCapable: Boolean - usersTotal: Int - workingDirectory: String -} - -type SystemInstance { - id: String - activeConnections: Int - activeListeners: Int - dbUser: String - dbFirstSeen: Date - dbLastSeen: Date - ip: String -} - -enum SystemImportUsersGroupMode { - MULTI - SINGLE - NONE -} - -type SystemImportUsersResponse { - operation: Operation - usersCount: Int - groupsCount: Int - failed: [SystemImportUsersResponseFailed] -} - -type SystemImportUsersResponseFailed { - provider: String - email: String - error: String -} - -type SystemExtension { - key: String - title: String - description: String - isInstalled: Boolean - isInstallable: Boolean - isCompatible: Boolean -} - -type SystemSecurity { - authJwtAudience: String - authJwtExpiration: String - authJwtRenewablePeriod: String - corsConfig: String - corsMode: SystemSecurityCorsMode - cspDirectives: String - disallowFloc: Boolean - disallowIframe: Boolean - disallowOpenRedirect: Boolean - enforceCsp: Boolean - enforceHsts: Boolean - enforceSameOriginReferrerPolicy: Boolean - forceAssetDownload: Boolean - hstsDuration: Int - trustProxy: Boolean - uploadMaxFiles: Int - uploadMaxFileSize: Int - uploadScanSVG: Boolean -} - -enum SystemSecurityCorsMode { - OFF - REFLECT - HOSTNAMES - REGEX -} - -type SystemJob { - id: UUID - task: String - state: SystemJobState - useWorker: Boolean - wasScheduled: Boolean - payload: JSON - attempt: Int - maxRetries: Int - lastErrorMessage: String - executedBy: String - createdAt: Date - startedAt: Date - completedAt: Date -} - -type SystemJobScheduled { - id: UUID - task: String - cron: String - type: String - payload: JSON - createdAt: Date - updatedAt: Date -} - -type SystemJobUpcoming { - id: UUID - task: String - useWorker: Boolean - payload: JSON - retries: Int - maxRetries: Int - waitUntil: Date - isScheduled: Boolean - createdBy: String - createdAt: Date - updatedAt: Date -} - -enum SystemJobState { - ACTIVE - COMPLETED - FAILED - INTERRUPTED -} - -type SystemCheckUpdateResponse { - operation: Operation - current: String - latest: String - latestDate: String -} - -type SystemSearch { - termHighlighting: Boolean - dictOverrides: String -} diff --git a/server/graph/schemas/tree.graphql b/server/graph/schemas/tree.graphql deleted file mode 100644 index b057802de..000000000 --- a/server/graph/schemas/tree.graphql +++ /dev/null @@ -1,132 +0,0 @@ -# =============================================== -# TREE -# =============================================== - -extend type Query { - """ - Browse the tree. - Must provide either `parentId` or a combination of `parentPath` and `locale`. - """ - tree( - siteId: UUID! - parentId: UUID - parentPath: String - locale: String - types: [TreeItemType] - tags: [String] - limit: Int - offset: Int - orderBy: TreeOrderBy - orderByDirection: OrderByDirection - """ - How many levels of children to include. Defaults to 1. - """ - depth: Int - """ - Include all parent folders up to root - """ - includeAncestors: Boolean - """ - Include all folders at root level - """ - includeRootFolders: Boolean - ): [TreeItem] - folderById( - id: UUID! - ): TreeItemFolder - folderByPath( - siteId: UUID! - locale: String! - path: String! - ): TreeItemFolder -} - -extend type Mutation { - createFolder( - siteId: UUID! - locale: String! - parentId: UUID - parentPath: String - pathName: String! - title: String! - ): DefaultResponse - deleteFolder( - folderId: UUID! - ): DefaultResponse - duplicateFolder( - folderId: UUID! - targetParentId: UUID - targetPathName: String! - targetTitle: String! - ): DefaultResponse - moveFolder( - folderId: UUID! - targetParentId: UUID - ): DefaultResponse - renameFolder( - folderId: UUID! - pathName: String! - title: String! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -enum TreeItemType { - asset - folder - page -} - -enum TreeOrderBy { - createdAt - fileName - title - updatedAt -} - -interface TreeItem { - id: UUID - folderPath: String - fileName: String - title: String -} - -type TreeItemFolder implements TreeItem { - id: UUID - childrenCount: Int - depth: Int - fileName: String - folderPath: String - title: String - isAncestor: Boolean -} - -type TreeItemPage implements TreeItem { - id: UUID - createdAt: Date - depth: Int - fileName: String - folderPath: String - editor: String - pageType: String - title: String - description: String - updatedAt: Date -} - -type TreeItemAsset implements TreeItem { - id: UUID - createdAt: Date - depth: Int - fileName: String - # In Bytes - fileSize: Int - fileExt: String - mimeType: String - folderPath: String - title: String - updatedAt: Date -} diff --git a/server/graph/schemas/user.graphql b/server/graph/schemas/user.graphql deleted file mode 100644 index 299070063..000000000 --- a/server/graph/schemas/user.graphql +++ /dev/null @@ -1,221 +0,0 @@ -# =============================================== -# USERS -# =============================================== - -extend type Query { - users ( - page: Int - pageSize: Int - orderBy: UserOrderBy - orderByDirection: OrderByDirection - # Filter by name / email - filter: String - ): UserResults - - userById( - id: UUID! - ): User - - userDefaults: UserDefaults - - userEditorSettings( - editor: String! - ): JSON - - lastLogins: [UserLastLogin] - - userPermissions: [String] - - userPermissionsAtPath( - siteId: UUID! - path: String! - ): [String] -} - -extend type Mutation { - createUser( - email: String! - name: String! - password: String! - groups: [UUID]! - mustChangePassword: Boolean! - sendWelcomeEmail: Boolean! - sendWelcomeEmailFromSiteId: UUID - ): UserResponse - - updateUser( - id: UUID! - patch: UserUpdateInput! - ): DefaultResponse - - deleteUser( - id: UUID! - replaceId: UUID! - ): DefaultResponse - - verifyUser( - id: UUID! - ): DefaultResponse - - activateUser( - id: UUID! - ): DefaultResponse - - deactivateUser( - id: UUID! - ): DefaultResponse - - enableUserTFA( - id: UUID! - ): DefaultResponse - - disableUserTFA( - id: UUID! - ): DefaultResponse - - changeUserPassword( - id: UUID! - newPassword: String! - mustChangePassword: Boolean - ): DefaultResponse - - updateProfile( - name: String - location: String - jobTitle: String - pronouns: String - timezone: String - dateFormat: String - timeFormat: String - appearance: UserSiteAppearance - cvd: UserCvdChoices - ): DefaultResponse - - uploadUserAvatar( - id: UUID! - image: Upload! - ): DefaultResponse - - clearUserAvatar( - id: UUID! - ): DefaultResponse - - updateUserDefaults( - timezone: String! - dateFormat: String! - timeFormat: String! - ): DefaultResponse -} - -# ----------------------------------------------- -# TYPES -# ----------------------------------------------- - -type UserResponse { - operation: Operation - user: User -} - -type UserLastLogin { - id: UUID - name: String - lastLoginAt: Date -} - -type UserResults { - users: [UserMinimal] - total: Int -} - -type UserMinimal { - id: UUID - name: String - email: String - isSystem: Boolean - isActive: Boolean - createdAt: Date - lastLoginAt: Date -} - -type User { - id: UUID - name: String - email: String - auth: [UserAuth] - passkeys: [UserPasskey] - hasAvatar: Boolean - isSystem: Boolean - isActive: Boolean - isVerified: Boolean - meta: JSON - prefs: JSON - createdAt: Date - updatedAt: Date - lastLoginAt: Date - groups: [Group] -} - -type UserAuth { - authId: UUID - authName: String - strategyKey: String - strategyIcon: String - config: JSON -} - -type UserPasskey { - id: String - name: String - createdAt: Date - siteHostname: String -} - -type UserDefaults { - timezone: String - dateFormat: String - timeFormat: String -} - -type UserTokenResponse { - operation: Operation - jwt: String -} - -enum UserOrderBy { - id - email - name - createdAt - updatedAt - lastLoginAt -} - -enum UserSiteAppearance { - site - light - dark -} - -enum UserCvdChoices { - none - protanopia - deuteranopia - tritanopia -} - -input UserUpdateInput { - email: String - name: String - groups: [UUID!] - auth: UserAuthUpdateInput - isActive: Boolean - isVerified: Boolean - meta: JSON - prefs: JSON -} - -input UserAuthUpdateInput { - tfaRequired: Boolean - mustChangePwd: Boolean - restrictLogin: Boolean -} diff --git a/server/helpers/brute-knex.mjs b/server/helpers/brute-knex.mjs deleted file mode 100644 index 49ba5e184..000000000 --- a/server/helpers/brute-knex.mjs +++ /dev/null @@ -1,150 +0,0 @@ -import AbstractClientStore from 'express-brute/lib/AbstractClientStore.js' - -const KnexStore = function (options) { - options = options || Object.create(null) - - AbstractClientStore.apply(this, arguments) - this.options = Object.assign(Object.create(null), KnexStore.defaults, options) - - if (this.options.knex) { - this.knex = this.options.knex - } else { - this.knex = require('knex')(KnexStore.defaultsKnex) - } - - if (options.createTable === false) { - this.ready = Promise.resolve() - } else { - this.ready = this.knex.schema.hasTable(this.options.tablename) - .then((exists) => { - if (exists) { - return - } - - return this.knex.schema.createTable(this.options.tablename, (table) => { - table.string('key') - table.bigInteger('firstRequest').nullable() - table.bigInteger('lastRequest').nullable() - table.bigInteger('lifetime').nullable() - table.integer('count') - }) - }) - } -} -KnexStore.prototype = Object.create(AbstractClientStore.prototype) -KnexStore.prototype.set = async function (key, value, lifetime, callback) { - try { - lifetime = lifetime || 0 - - await this.ready - const resp = await this.knex.transaction((trx) => { - return trx - .select('*') - .forUpdate() - .from(this.options.tablename) - .where('key', '=', key) - .then((foundKeys) => { - if (foundKeys.length === 0) { - return trx.from(this.options.tablename) - .insert({ - key: key, - lifetime: new Date(Date.now() + lifetime * 1000).getTime(), - lastRequest: new Date(value.lastRequest).getTime(), - firstRequest: new Date(value.firstRequest).getTime(), - count: value.count - }) - } else { - return trx(this.options.tablename) - .where('key', '=', key) - .update({ - lifetime: new Date(Date.now() + lifetime * 1000).getTime(), - count: value.count, - lastRequest: new Date(value.lastRequest).getTime() - }) - } - }) - }) - callback(null, resp) - } catch (err) { - callback(err, null) - } -} - -KnexStore.prototype.get = async function (key, callback) { - try { - await this.ready - await this.clearExpired() - const resp = await this.knex.select('*') - .from(this.options.tablename) - .where('key', '=', key) - let o = null - - if (resp[0]) { - o = {} - o.lastRequest = new Date(resp[0].lastRequest) - o.firstRequest = new Date(resp[0].firstRequest) - o.count = resp[0].count - } - - callback(null, o) - } catch (err) { - callback(err, null) - } -} -KnexStore.prototype.reset = async function (key, callback) { - try { - await this.ready - const resp = await this.knex(this.options.tablename) - .where('key', '=', key) - .del() - callback(null, resp) - } catch (err) { - callback(err, null) - } -} - -KnexStore.prototype.increment = async function (key, lifetime, callback) { - try { - const result = await this.get(key) - let resp = null - if (result) { - resp = await this.knex(this.options.tablename) - .increment('count', 1) - .where('key', '=', key) - } else { - resp = await this.knex(this.options.tablename) - .insert({ - key: key, - firstRequest: new Date().getTime(), - lastRequest: new Date().getTime(), - lifetime: new Date(Date.now() + lifetime * 1000).getTime(), - count: 1 - }) - } - callback(null, resp) - } catch (err) { - callback(err, null) - } -} - -KnexStore.prototype.clearExpired = async function (callback) { - await this.ready - return this.knex(this.options.tablename) - .del() - .where('lifetime', '<', new Date().getTime()) -} - -KnexStore.defaults = { - tablename: 'brute', - createTable: true -} - -KnexStore.defaultsKnex = { - client: 'sqlite3', - // debug: true, - connection: { - filename: './brute-knex.sqlite' - } -} - -export default KnexStore diff --git a/server/helpers/common.mjs b/server/helpers/common.mjs deleted file mode 100644 index 2c45ba501..000000000 --- a/server/helpers/common.mjs +++ /dev/null @@ -1,112 +0,0 @@ -import { isNil, isPlainObject, set, startCase, transform } from 'lodash-es' -import crypto from 'node:crypto' - -/* eslint-disable promise/param-names */ -export function createDeferred () { - let result, resolve, reject - return { - resolve: function (value) { - if (resolve) { - resolve(value) - } else { - result = result || new Promise(function (r) { r(value) }) - } - }, - reject: function (reason) { - if (reject) { - reject(reason) - } else { - result = result || new Promise(function (x, j) { j(reason) }) - } - }, - promise: new Promise(function (r, j) { - if (result) { - r(result) - } else { - resolve = r - reject = j - } - }) - } -} - -/** - * Decode a tree path - * - * @param {string} str String to decode - * @returns Decoded tree path - */ -export function decodeTreePath (str) { - return str?.replaceAll('.', '/') -} - -/** - * Encode a tree path - * - * @param {string} str String to encode - * @returns Encoded tree path - */ -export function encodeTreePath (str) { - return str?.toLowerCase()?.replaceAll('/', '.') || '' -} - -/** - * Generate SHA-1 Hash of a string - * - * @param {string} str String to hash - * @returns Hashed string - */ -export function generateHash (str) { - return crypto.createHash('sha1').update(str).digest('hex') -} - -/** - * Get default value of type - * - * @param {any} type primitive type name - * @returns Default value - */ -export function getTypeDefaultValue (type) { - switch (type.toLowerCase()) { - case 'string': - return '' - case 'number': - return 0 - case 'boolean': - return false - } -} - -export function parseModuleProps (props) { - return transform(props, (result, value, key) => { - let defaultValue = '' - if (isPlainObject(value)) { - defaultValue = !isNil(value.default) ? value.default : getTypeDefaultValue(value.type) - } else { - defaultValue = getTypeDefaultValue(value) - } - set(result, key, { - default: defaultValue, - type: (value.type || value).toLowerCase(), - title: value.title || startCase(key), - hint: value.hint || '', - enum: value.enum || false, - enumDisplay: value.enumDisplay || 'select', - multiline: value.multiline || false, - sensitive: value.sensitive || false, - icon: value.icon || 'rename', - order: value.order || 100, - if: value.if ?? [] - }) - return result - }, {}) -} - -export function getDictNameFromLocale (locale) { - const loc = locale.length > 2 ? locale.substring(0, 2) : locale - if (loc in WIKI.config.search.dictOverrides) { - return WIKI.config.search.dictOverrides[loc] - } else { - return WIKI.data.tsDictMappings[loc] ?? 'simple' - } -} diff --git a/server/helpers/config.mjs b/server/helpers/config.mjs deleted file mode 100644 index 352c24f80..000000000 --- a/server/helpers/config.mjs +++ /dev/null @@ -1,27 +0,0 @@ -import { replace } from 'lodash-es' - -const isoDurationReg = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/ - -export default { - /** - * Parse configuration value for environment vars - * - * Replaces `$(ENV_VAR_NAME)` with value of `ENV_VAR_NAME` environment variable. - * - * Also supports defaults by if provided as `$(ENV_VAR_NAME:default)` - * - * @param {any} cfg Configuration value - * @returns Parse configuration value - */ - parseConfigValue (cfg) { - return replace( - cfg, - /\$\(([A-Z0-9_]+)(?::(.+))?\)/g, - (fm, m, d) => { return process.env[m] || d } - ) - }, - - isValidDurationString (val) { - return isoDurationReg.test(val) - } -} diff --git a/server/helpers/error.mjs b/server/helpers/error.mjs deleted file mode 100644 index 976c55f5e..000000000 --- a/server/helpers/error.mjs +++ /dev/null @@ -1,187 +0,0 @@ -import CustomError from 'custom-error-instance' - -export default { - Custom (slug, message) { - return CustomError(slug, { message }) - }, - AssetDeleteForbidden: CustomError('AssetDeleteForbidden', { - message: 'You are not authorized to delete this asset.' - }), - AssetFolderExists: CustomError('AssetFolderExists', { - message: 'An asset folder with the same name already exists.' - }), - AssetGenericError: CustomError('AssetGenericError', { - message: 'An unexpected error occured during asset operation.' - }), - AssetInvalid: CustomError('AssetInvalid', { - message: 'This asset does not exist or is invalid.' - }), - AssetRenameCollision: CustomError('AssetRenameCollision', { - message: 'An asset with the same filename in the same folder already exists.' - }), - AssetRenameForbidden: CustomError('AssetRenameForbidden', { - message: 'You are not authorized to rename this asset.' - }), - AssetRenameInvalid: CustomError('AssetRenameInvalid', { - message: 'The new asset filename is invalid.' - }), - AssetRenameInvalidExt: CustomError('AssetRenameInvalidExt', { - message: 'The file extension cannot be changed on an existing asset.' - }), - AssetRenameTargetForbidden: CustomError('AssetRenameTargetForbidden', { - message: 'You are not authorized to rename this asset to the requested name.' - }), - AuthAccountBanned: CustomError('AuthAccountBanned', { - message: 'Your account has been disabled.' - }), - AuthAccountAlreadyExists: CustomError('AuthAccountAlreadyExists', { - message: 'An account already exists using this email address.' - }), - AuthAccountNotVerified: CustomError('AuthAccountNotVerified', { - message: 'You must verify your account before your can login.' - }), - AuthGenericError: CustomError('AuthGenericError', { - message: 'An unexpected error occured during login.' - }), - AuthLoginFailed: CustomError('AuthLoginFailed', { - message: 'Invalid email / username or password.' - }), - AuthPasswordInvalid: CustomError('AuthPasswordInvalid', { - message: 'Password is incorrect.' - }), - AuthProviderInvalid: CustomError('AuthProviderInvalid', { - message: 'Invalid authentication provider.' - }), - AuthRegistrationDisabled: CustomError('AuthRegistrationDisabled', { - message: 'Registration is disabled. Contact your system administrator.' - }), - AuthRegistrationDomainUnauthorized: CustomError('AuthRegistrationDomainUnauthorized', { - message: 'You are not authorized to register. Your domain is not whitelisted.' - }), - AuthRequired: CustomError('AuthRequired', { - message: 'You must be authenticated to access this resource.' - }), - AuthTFAFailed: CustomError('AuthTFAFailed', { - message: 'Incorrect TFA Security Code.' - }), - AuthTFAInvalid: CustomError('AuthTFAInvalid', { - message: 'Invalid TFA Security Code or Login Token.' - }), - AuthValidationTokenInvalid: CustomError('AuthValidationTokenInvalid', { - message: 'Invalid validation token.' - }), - BruteInstanceIsInvalid: CustomError('BruteInstanceIsInvalid', { - message: 'Invalid Brute Force Instance.' - }), - BruteTooManyAttempts: CustomError('BruteTooManyAttempts', { - message: 'Too many attempts! Try again later.' - }), - CommentContentMissing: CustomError('CommentContentMissing', { - message: 'Comment content is missing or too short.' - }), - CommentGenericError: CustomError('CommentGenericError', { - message: 'An unexpected error occured.' - }), - CommentManageForbidden: CustomError('CommentManageForbidden', { - message: 'You are not authorized to manage comments on this page.' - }), - CommentNotFound: CustomError('CommentNotFound', { - message: 'This comment does not exist.' - }), - CommentPostForbidden: CustomError('CommentPostForbidden', { - message: 'You are not authorized to post a comment on this page.' - }), - CommentViewForbidden: CustomError('CommentViewForbidden', { - message: 'You are not authorized to view comments for this page.' - }), - InputInvalid: CustomError('InputInvalid', { - message: 'Input data is invalid.' - }), - LocaleGenericError: CustomError('LocaleGenericError', { - message: 'An unexpected error occured during locale operation.' - }), - LocaleInvalidNamespace: CustomError('LocaleInvalidNamespace', { - message: 'Invalid locale or namespace.' - }), - MailGenericError: CustomError('MailGenericError', { - message: 'An unexpected error occured during mail operation.' - }), - MailInvalidRecipient: CustomError('MailInvalidRecipient', { - message: 'The recipient email address is invalid.' - }), - MailNotConfigured: CustomError('MailNotConfigured', { - message: 'The mail configuration is incomplete or invalid.' - }), - MailTemplateFailed: CustomError('MailTemplateFailed', { - message: 'Mail template failed to load.' - }), - PageCreateForbidden: CustomError('PageCreateForbidden', { - message: 'You are not authorized to create this page.' - }), - PageDeleteForbidden: CustomError('PageDeleteForbidden', { - message: 'You are not authorized to delete this page.' - }), - PageGenericError: CustomError('PageGenericError', { - message: 'An unexpected error occured during a page operation.' - }), - PageDuplicateCreate: CustomError('PageDuplicateCreate', { - message: 'Cannot create this page because an entry already exists at the same path.' - }), - PageEmptyContent: CustomError('PageEmptyContent', { - message: 'Page content cannot be empty.' - }), - PageHistoryForbidden: CustomError('PageHistoryForbidden', { - message: 'You are not authorized to view the history of this page.' - }), - PageIllegalPath: CustomError('PageIllegalPath', { - message: 'Page path cannot contains illegal characters.' - }), - PageMoveForbidden: CustomError('PageMoveForbidden', { - message: 'You are not authorized to move this page.' - }), - PageNotFound: CustomError('PageNotFound', { - message: 'This page does not exist.' - }), - PagePathCollision: CustomError('PagePathCollision', { - message: 'Destination page path already exists.' - }), - PageRestoreForbidden: CustomError('PageRestoreForbidden', { - message: 'You are not authorized to restore this page version.' - }), - PageUpdateForbidden: CustomError('PageUpdateForbidden', { - message: 'You are not authorized to update this page.' - }), - PageViewForbidden: CustomError('PageViewForbidden', { - message: 'You are not authorized to view this page.' - }), - SearchActivationFailed: CustomError('SearchActivationFailed', { - message: 'Search Engine activation failed.' - }), - SearchGenericError: CustomError('SearchGenericError', { - message: 'An unexpected error occured during search operation.' - }), - SystemGenericError: CustomError('SystemGenericError', { - message: 'An unexpected error occured.' - }), - SystemSSLDisabled: CustomError('SystemSSLDisabled', { - message: 'SSL is not enabled.' - }), - SystemSSLLEUnavailable: CustomError('SystemSSLLEUnavailable', { - message: 'Let\'s Encrypt is not initialized.' - }), - SystemSSLRenewInvalidProvider: CustomError('SystemSSLRenewInvalidProvider', { - message: 'Current provider does not support SSL certificate renewal.' - }), - UserCreationFailed: CustomError('UserCreationFailed', { - message: 'An unexpected error occured during user creation.' - }), - UserDeleteForeignConstraint: CustomError('UserDeleteForeignConstraint', { - message: 'Cannot delete user because of content relational constraints.' - }), - UserDeleteProtected: CustomError('UserDeleteProtected', { - message: 'Cannot delete a protected system account.' - }), - UserNotFound: CustomError('UserNotFound', { - message: 'This user does not exist.' - }) -} diff --git a/server/helpers/graph.mjs b/server/helpers/graph.mjs deleted file mode 100644 index 4c709f10a..000000000 --- a/server/helpers/graph.mjs +++ /dev/null @@ -1,20 +0,0 @@ -import { defaultTo, isFinite } from 'lodash-es' - -export function generateSuccess (msg) { - return { - succeeded: true, - errorCode: 0, - slug: 'ok', - message: defaultTo(msg, 'Operation succeeded.') - } -} - -export function generateError (err, complete = true) { - const error = { - succeeded: false, - errorCode: isFinite(err.code) ? err.code : 1, - slug: err.name, - message: err.message || 'An unexpected error occured.' - } - return (complete) ? { operation: error } : error -} diff --git a/server/helpers/page.mjs b/server/helpers/page.mjs deleted file mode 100644 index 246ee6d07..000000000 --- a/server/helpers/page.mjs +++ /dev/null @@ -1,153 +0,0 @@ -import qs from 'querystring' -import { fromPairs, get, head, initial, invert, isEmpty, last } from 'lodash-es' -import crypto from 'node:crypto' -import path from 'node:path' - -const localeSegmentRegex = /^[A-Z]{2}(-[A-Z]{2})?$/i -const localeFolderRegex = /^([a-z]{2}(?:-[a-z]{2})?\/)?(.*)/i -// eslint-disable-next-line no-control-regex -const unsafeCharsRegex = /[\x00-\x1f\x80-\x9f\\"|<>:*?]/ - -const contentToExt = { - markdown: 'md', - html: 'html' -} -const extToContent = invert(contentToExt) - -/** - * Parse raw url path and make it safe - */ -export function parsePath (rawPath, opts = {}) { - const pathObj = { - // TODO: use site base lang - locale: 'en', // WIKI.config.lang.code, - path: 'home', - explicitLocale: false - } - - // Clean Path - rawPath = qs.unescape(rawPath).trim() - if (rawPath.startsWith('/')) { rawPath = rawPath.substring(1) } - rawPath = rawPath.replace(unsafeCharsRegex, '') - if (rawPath === '') { rawPath = 'home' } - - rawPath = rawPath.replace(/\\/g, '').replace(/\/\//g, '').replace(/\.\.+/ig, '') - - // Extract Info - let pathParts = rawPath.split('/').filter(p => { - p = p.trim() - return !isEmpty(p) && p !== '..' && p !== '.' - }) - if (pathParts.length > 1 && pathParts[0].startsWith('_')) { - pathParts.shift() - } - if (localeSegmentRegex.test(pathParts[0])) { - pathObj.locale = pathParts[0] - pathObj.explicitLocale = true - pathParts.shift() - } - - // Strip extension - if (opts.stripExt && pathParts.length > 0) { - const lastPart = last(pathParts) - if (lastPart.indexOf('.') > 0) { - pathParts.pop() - const lastPartMeta = path.parse(lastPart) - pathParts.push(lastPartMeta.name) - } - } - - pathObj.path = pathParts.join('/') - return pathObj -} - -/** - * Generate unique hash from page - */ -export function generateHash(opts) { - return crypto.createHash('sha1').update(`${opts.locale}|${opts.path}|${opts.privateNS}`).digest('hex') -} - -/** - * Inject Page Metadata - */ -export function injectPageMetadata(page) { - const meta = [ - ['title', page.title], - ['description', page.description], - ['published', page.isPublished.toString()], - ['date', page.updatedAt], - ['tags', page.tags ? page.tags.map(t => t.tag).join(', ') : ''], - ['editor', page.editorKey], - ['dateCreated', page.createdAt] - ] - switch (page.contentType) { - case 'markdown': - return '---\n' + meta.map(mt => `${mt[0]}: ${mt[1]}`).join('\n') + '\n---\n\n' + page.content - case 'html': - return '\n\n' + page.content - case 'json': - return { - ...page.content, - _meta: fromPairs(meta) - } - default: - return page.content - } -} - -/** - * Check if path is a reserved path - */ -export function isReservedPath(rawPath) { - const firstSection = head(rawPath.split('/')) - if (firstSection.length < 1) { - return true - } else if (localeSegmentRegex.test(firstSection)) { - return true - } else if ( - WIKI.data.reservedPaths.some(p => { - return p === firstSection - })) { - return true - } else { - return false - } -} - -/** - * Get file extension from content type - */ -export function getFileExtension(contentType) { - return get(contentToExt, contentType, 'txt') -} - -/** - * Get content type from file extension - */ -export function getContentType (filePath) { - const ext = last(filePath.split('.')) - return get(extToContent, ext, false) -} - -/** - * Get Page Meta object from disk path - */ -export function getPagePath (filePath) { - let fpath = filePath - if (process.platform === 'win32') { - fpath = filePath.replace(/\\/g, '/') - } - let meta = { - locale: WIKI.config.lang.code, - path: initial(fpath.split('.')).join('') - } - const result = localeFolderRegex.exec(meta.path) - if (result[1]) { - meta = { - locale: result[1].replace('/', ''), - path: result[2] - } - } - return meta -} diff --git a/server/helpers/security.mjs b/server/helpers/security.mjs deleted file mode 100644 index a0f66c153..000000000 --- a/server/helpers/security.mjs +++ /dev/null @@ -1,38 +0,0 @@ -import util from 'node:util' -import crypto from 'node:crypto' -import passportJWT from 'passport-jwt' - -const randomBytes = util.promisify(crypto.randomBytes) - -export function sanitizeCommitUser (user) { - // let wlist = new RegExp('[^a-zA-Z0-9-_.\',& ' + appdata.regex.cjk + appdata.regex.arabic + ']', 'g') - // return { - // name: _.chain(user.name).replace(wlist, '').trim().value(), - // email: appconfig.git.showUserEmail ? user.email : appconfig.git.serverEmail - // } -} - -/** - * Generate a random token - * - * @param {any} length - * @returns - */ -export async function generateToken (length) { - return (await randomBytes(length)).toString('hex') -} - -export const extractJWT = passportJWT.ExtractJwt.fromExtractors([ - passportJWT.ExtractJwt.fromAuthHeaderAsBearerToken(), - (req) => { - let token = null - if (req && req.cookies) { - token = req.cookies['jwt'] - } - // Force uploads to use Auth headers - if (req.path.toLowerCase() === '/u') { - return null - } - return token - } -]) diff --git a/server/index.mjs b/server/index.mjs deleted file mode 100644 index 5fd414763..000000000 --- a/server/index.mjs +++ /dev/null @@ -1,75 +0,0 @@ -// =========================================== -// Wiki.js Server -// Licensed under AGPLv3 -// =========================================== - -import path from 'node:path' -import { DateTime } from 'luxon' -import semver from 'semver' -import { customAlphabet } from 'nanoid' -import fse from 'fs-extra' -import configSvc from './core/config.mjs' -import kernel from './core/kernel.mjs' -import logger from './core/logger.mjs' - -const nanoid = customAlphabet('1234567890abcdef', 10) - -if (!semver.satisfies(process.version, '>=24')) { - console.error('ERROR: Node.js 24.x or later required!') - process.exit(1) -} - -if (fse.pathExistsSync('./package.json')) { - console.error('ERROR: Must run server from the parent directory!') - process.exit(1) -} - -const WIKI = { - IS_DEBUG: process.env.NODE_ENV === 'development', - ROOTPATH: process.cwd(), - INSTANCE_ID: nanoid(10), - SERVERPATH: path.join(process.cwd(), 'server'), - configSvc, - kernel, - sites: {}, - sitesMappings: {}, - startedAt: DateTime.utc(), - storage: { - defs: [], - modules: [] - } -} -global.WIKI = WIKI - -if (WIKI.IS_DEBUG) { - process.on('warning', (warning) => { - console.log(warning.stack) - }) -} - -await WIKI.configSvc.init() - -// ---------------------------------------- -// Init Logger -// ---------------------------------------- - -WIKI.logger = logger.init() - -// ---------------------------------------- -// Start Kernel -// ---------------------------------------- - -WIKI.kernel.init() - -// ---------------------------------------- -// Register exit handler -// ---------------------------------------- - -process.on('SIGINT', () => { - WIKI.kernel.shutdown() -}) -process.on('message', (msg) => { - if (msg === 'shutdown') { - WIKI.kernel.shutdown() - } -}) diff --git a/server/locales/en.json b/server/locales/en.json deleted file mode 100644 index 09d146155..000000000 --- a/server/locales/en.json +++ /dev/null @@ -1,1911 +0,0 @@ -{ - "admin.adminArea": "Administration Area", - "admin.analytics.providerConfiguration": "Provider Configuration", - "admin.analytics.providerNoConfiguration": "This provider has no configuration options you can modify.", - "admin.analytics.providers": "Providers", - "admin.analytics.refreshSuccess": "List of providers refreshed successfully.", - "admin.analytics.saveSuccess": "Analytics configuration saved successfully", - "admin.analytics.subtitle": "Add analytics and tracking tools to your wiki", - "admin.analytics.title": "Analytics", - "admin.api.copyKeyTitle": "Copy API Key", - "admin.api.createInvalidData": "Some fields are missing or have invalid data.", - "admin.api.createSuccess": "API Key created successfully.", - "admin.api.disableButton": "Disable API", - "admin.api.disabled": "API Disabled", - "admin.api.enableButton": "Enable API", - "admin.api.enabled": "API Enabled", - "admin.api.expiration180d": "180 days", - "admin.api.expiration1y": "1 year", - "admin.api.expiration30d": "30 days", - "admin.api.expiration3y": "3 years", - "admin.api.expiration90d": "90 days", - "admin.api.groupSelected": "Use {group} group permissions", - "admin.api.groupsMissing": "You must select at least 1 group for this key.", - "admin.api.groupsSelected": "Use permissions from {count} groups", - "admin.api.headerCreated": "Created", - "admin.api.headerExpiration": "Expiration", - "admin.api.headerKeyEnding": "Key Ending", - "admin.api.headerLastUpdated": "Last Updated", - "admin.api.headerName": "Name", - "admin.api.headerRevoke": "Revoke", - "admin.api.key": "API Key", - "admin.api.nameInvalidChars": "Key name has invalid characters.", - "admin.api.nameMissing": "Key name is missing.", - "admin.api.newKeyButton": "New API Key", - "admin.api.newKeyCopyWarn": "Copy the key shown below as {bold}", - "admin.api.newKeyCopyWarnBold": "it will NOT be shown again.", - "admin.api.newKeyExpiration": "Expiration", - "admin.api.newKeyExpirationHint": "You can still revoke a key anytime regardless of the expiration.", - "admin.api.newKeyFullAccess": "Full Access", - "admin.api.newKeyGroup": "Group", - "admin.api.newKeyGroupError": "You must select a group.", - "admin.api.newKeyGroupHint": "The API key will have the same permissions as the selected group.", - "admin.api.newKeyGroupPermissions": "or use group permissions...", - "admin.api.newKeyGuestGroupError": "The guests group cannot be used for API keys.", - "admin.api.newKeyName": "Name", - "admin.api.newKeyNameError": "Name is missing or invalid.", - "admin.api.newKeyNameHint": "Purpose of this key", - "admin.api.newKeyPermissionScopes": "Permission Scopes", - "admin.api.newKeySuccess": "API key created successfully.", - "admin.api.newKeyTitle": "New API Key", - "admin.api.noKeyInfo": "No API keys have been generated yet.", - "admin.api.none": "There are no API keys yet.", - "admin.api.permissionGroups": "Group Permissions", - "admin.api.refreshSuccess": "List of API keys has been refreshed.", - "admin.api.revoke": "Revoke", - "admin.api.revokeConfirm": "Revoke API Key?", - "admin.api.revokeConfirmText": "Are you sure you want to revoke key {name}? This action cannot be undone!", - "admin.api.revokeSuccess": "The key has been revoked successfully.", - "admin.api.revoked": "Revoked", - "admin.api.revokedHint": "This key has been revoked and can no longer be used.", - "admin.api.subtitle": "Manage keys to access the API", - "admin.api.title": "API Access", - "admin.api.toggleStateDisabledSuccess": "API has been disabled successfully.", - "admin.api.toggleStateEnabledSuccess": "API has been enabled successfully.", - "admin.approval.title": "Approvals", - "admin.audit.title": "Audit Log", - "admin.auth.activeStrategies": "Active Strategies", - "admin.auth.addStrategy": "Add Strategy", - "admin.auth.allowedEmailRegex": "Allowed Email Address Regex", - "admin.auth.allowedEmailRegexHint": "(optional) Only allow users to register with an email address that matches the regex expression.", - "admin.auth.allowedWebOrigins": "Allowed Web Origins", - "admin.auth.autoEnrollGroups": "Assign to group(s)", - "admin.auth.autoEnrollGroupsHint": "(optional) Automatically assign new users to these groups. New users are always added to the Users group regardless of this setting.", - "admin.auth.callbackUrl": "Callback URL / Redirect URI", - "admin.auth.configReference": "Configuration Reference", - "admin.auth.configReferenceSubtitle": "Some strategies may require some configuration values to be set on your provider. These are provided for reference only and may not be needed by the current strategy.", - "admin.auth.displayName": "Display Name", - "admin.auth.displayNameHint": "The title shown to the end user for this authentication strategy.", - "admin.auth.emailValidation": "Email Validation", - "admin.auth.emailValidationHint": "Send a verification email to the user with a validation link when registering.", - "admin.auth.enabled": "Enabled", - "admin.auth.enabledForced": "This strategy cannot be disabled.", - "admin.auth.enabledHint": "Should this strategy be available to sites for login.", - "admin.auth.enforceTfa": "Enforce Two-Factor Authentication", - "admin.auth.enforceTfaHint": "Users will be required to setup 2FA the first time they login and cannot be disabled by the user.", - "admin.auth.globalAdvSettings": "Global Advanced Settings", - "admin.auth.info": "Info", - "admin.auth.infoName": "Name", - "admin.auth.infoNameHint": "Display name for this strategy.", - "admin.auth.loginUrl": "Login URL", - "admin.auth.logoutUrl": "Logout URL", - "admin.auth.noConfigOption": "This strategy has no configuration options you can modify.", - "admin.auth.refreshSuccess": "List of strategies has been refreshed.", - "admin.auth.registration": "Registration", - "admin.auth.registrationHint": "Allow any user successfully authorized by the strategy to access the wiki.", - "admin.auth.registrationLocalHint": "Whether to allow guests to register new accounts.", - "admin.auth.saveSuccess": "Authentication configuration saved successfully.", - "admin.auth.security": "Security", - "admin.auth.siteUrlNotSetup": "You must set a valid {siteUrl} first! Click on {general} in the left sidebar.", - "admin.auth.status": "Status", - "admin.auth.strategies": "Strategies", - "admin.auth.strategyConfiguration": "Strategy Configuration", - "admin.auth.strategyIsEnabled": "Active", - "admin.auth.strategyIsEnabledHint": "Are users able to login using this strategy?", - "admin.auth.strategyNoConfiguration": "This strategy has no configuration options you can modify.", - "admin.auth.strategyState": "This strategy is {state} {locked}", - "admin.auth.strategyStateActive": "active", - "admin.auth.strategyStateInactive": "not active", - "admin.auth.strategyStateLocked": "and cannot be disabled.", - "admin.auth.subtitle": "Configure the authentication settings of your wiki", - "admin.auth.title": "Authentication", - "admin.auth.vendor": "Vendor", - "admin.auth.vendorWebsite": "Website", - "admin.blocks.add": "Add Block", - "admin.blocks.builtin": "Built-in", - "admin.blocks.custom": "Custom", - "admin.blocks.isEnabled": "Enabled", - "admin.blocks.saveSuccess": "Blocks state saved successfully.", - "admin.blocks.subtitle": "Manage dynamic components available for use inside pages.", - "admin.blocks.title": "Content Blocks", - "admin.comments.provider": "Provider", - "admin.comments.providerConfig": "Provider Configuration", - "admin.comments.providerNoConfig": "This provider has no configuration options you can modify.", - "admin.comments.subtitle": "Add discussions to your wiki pages", - "admin.comments.title": "Comments", - "admin.contribute.title": "Donate", - "admin.dashboard.contributeHelp": "We need your help!", - "admin.dashboard.contributeLearnMore": "Learn More", - "admin.dashboard.contributeSubtitle": "Wiki.js is a free and open source project. There are several ways you can contribute to the project.", - "admin.dashboard.groups": "Groups", - "admin.dashboard.lastLogins": "Last Logins", - "admin.dashboard.mostPopularPages": "Most Popular Pages", - "admin.dashboard.pages": "Pages", - "admin.dashboard.recentPages": "Recent Pages", - "admin.dashboard.subtitle": "Wiki.js", - "admin.dashboard.title": "Dashboard", - "admin.dashboard.users": "Users", - "admin.dashboard.versionLatest": "You are running the latest version.", - "admin.dashboard.versionNew": "A new version is available: {version}", - "admin.dev.flags.title": "Flags", - "admin.dev.graphiql.title": "GraphiQL", - "admin.dev.title": "Developer Tools", - "admin.dev.voyager.title": "Voyager", - "admin.editors.apiDescription": "Document your REST / GraphQL APIs.", - "admin.editors.apiName": "API Docs Editor", - "admin.editors.asciidocDescription": "Use the AsciiDoc syntax to write content. Includes real-time preview.", - "admin.editors.asciidocName": "AsciiDoc Editor", - "admin.editors.blogDescription": "Write a series of posts over time.", - "admin.editors.blogName": "Blog Editor", - "admin.editors.channelDescription": "Create discussion channels to collaborate in real-time with your team.", - "admin.editors.channelName": "Discussion Channels", - "admin.editors.configuration": "Configuration", - "admin.editors.markdown.allowHTML": "Allow HTML", - "admin.editors.markdown.allowHTMLHint": "Allow HTML tags in content.", - "admin.editors.markdown.general": "General", - "admin.editors.markdown.kroki": "Kroki", - "admin.editors.markdown.krokiHint": "Enable Kroki Diagrams Parser", - "admin.editors.markdown.krokiServerUrl": "Kroki Server URL", - "admin.editors.markdown.krokiServerUrlHint": "URL to the Kroki server used for image generation.", - "admin.editors.markdown.latexEngine": "LaTeX Engine", - "admin.editors.markdown.latexEngineHint": "Which engine to use to process TeX/LaTeX expressions.", - "admin.editors.markdown.lineBreaks": "Auto Line Breaks", - "admin.editors.markdown.lineBreaksHint": "Automatically add linebreaks within paragraphs.", - "admin.editors.markdown.linkify": "Auto-linking", - "admin.editors.markdown.linkifyHint": "Automatically convert URLs into clickable links.", - "admin.editors.markdown.multimdTable": "MultiMarkdown Table", - "admin.editors.markdown.multimdTableHint": "Enable support for MultiMarkdown Table features.", - "admin.editors.markdown.plantuml": "PlantUML", - "admin.editors.markdown.plantumlHint": "Enable PlantUML Parser", - "admin.editors.markdown.plantumlServerUrl": "PlantUML Server URL", - "admin.editors.markdown.plantumlServerUrlHint": "URL to the PlantUML server used for image generation.", - "admin.editors.markdown.quotes": "Quotes Style", - "admin.editors.markdown.quotesHint": "When typographer is enabled. Double + single quotes replacement pairs. e.g. «»„“ for Russian, „“‚‘ for German, etc.", - "admin.editors.markdown.saveSuccess": "Markdown editor configuration saved successfully.", - "admin.editors.markdown.tabWidth": "Code Block Tab Width", - "admin.editors.markdown.tabWidthHint": "Amount of spaces for each tab in code blocks.", - "admin.editors.markdown.typographer": "Typographer", - "admin.editors.markdown.typographerHint": "Enable some language-neutral replacement + quotes beautification.", - "admin.editors.markdown.underline": "Underline Emphasis", - "admin.editors.markdown.underlineHint": "Enable text underlining by using _underline_ syntax.", - "admin.editors.markdownDescription": "Use the Markdown syntax to write content. Includes real-time preview and code completion features.", - "admin.editors.markdownName": "Markdown Editor", - "admin.editors.redirectDescription": "Create redirections to other pages / external links.", - "admin.editors.redirectName": "Redirection", - "admin.editors.saveSuccess": "Editors state saved successfully.", - "admin.editors.subtitle": "Manage editors and their configuration", - "admin.editors.title": "Editors", - "admin.editors.useRenderingPipeline": "Uses the rendering pipeline.", - "admin.editors.wysiwygDescription": "A visual WYSIWYG editor. The recommended editor for non-technical users.", - "admin.editors.wysiwygName": "Visual Editor", - "admin.extensions.incompatible": "not compatible", - "admin.extensions.install": "Install", - "admin.extensions.installFailed": "Failed to install extension.", - "admin.extensions.installSuccess": "Extension installed successfully.", - "admin.extensions.installed": "Installed", - "admin.extensions.installing": "Installing extension...", - "admin.extensions.installingHint": "This may take a while depending on your server.", - "admin.extensions.instructions": "Instructions", - "admin.extensions.instructionsHint": "Must be installed manually", - "admin.extensions.reinstall": "Reinstall", - "admin.extensions.requiresSharp": "Requires Sharp extension", - "admin.extensions.subtitle": "Install extensions for extra functionality", - "admin.extensions.title": "Extensions", - "admin.flags.advanced.hint": "Set custom configuration flags. Note that all values are public to all users! Do not insert senstive data.", - "admin.flags.advanced.label": "Custom Configuration", - "admin.flags.authDebug.hint": "Log detailed debug info of all login / registration attempts.", - "admin.flags.authDebug.label": "Auth Debug", - "admin.flags.experimental.hint": "Enable unstable / unfinished features. DO NOT enable in a production environment!", - "admin.flags.experimental.label": "Experimental Features", - "admin.flags.getTokenHint": "Copy your current authentication token for use in GraphQL API testing.", - "admin.flags.getTokenLabel": "Get Current Token", - "admin.flags.saveSuccess": "Flags have been updated successfully.", - "admin.flags.sqlLog.hint": "Log all queries made to the database to console.", - "admin.flags.sqlLog.label": "SQL Query Logging", - "admin.flags.subtitle": "Low-level system flags for debugging or experimental purposes", - "admin.flags.title": "Flags", - "admin.flags.warn.hint": "Doing so may result in data loss, performance issues or a broken installation!", - "admin.flags.warn.label": "Do NOT enable these flags unless you know what you're doing!", - "admin.general.allowBrowse": "Allow Browsing", - "admin.general.allowBrowseHint": "Can users browse using the tree structure of the site to pages they have access to?", - "admin.general.allowComments": "Allow Comments", - "admin.general.allowCommentsHint": "Can users leave comments on pages? Can be restricted using Page Rules.", - "admin.general.allowContributions": "Allow Contributions", - "admin.general.allowContributionsHint": "Can users with read access permissions propose changes for pages? Can be restricted using Page Rules.", - "admin.general.allowProfile": "Allow Profile Editing", - "admin.general.allowProfileHint": "Can users edit their own profile? If profile data is managed by an external identity provider, you should turn this off.", - "admin.general.allowRatings": "Allow Ratings", - "admin.general.allowRatingsHint": "Can users leave ratings on pages? Can be restricted using Page Rules.", - "admin.general.allowSearch": "Allow Search", - "admin.general.allowSearchHint": "Can users search for content they have read access to?", - "admin.general.companyName": "Company / Organization Name", - "admin.general.companyNameHint": "Name to use when displaying copyright notice in the footer. Leave empty to hide.", - "admin.general.contentLicense": "Content License", - "admin.general.contentLicenseHint": "License shown in the footer of all content pages.", - "admin.general.defaultBaseURLHint": "The default base URL to use when a site URL is not available. (e.g. https://wiki.example.com)", - "admin.general.defaultDateFormat": "Default Date Format", - "admin.general.defaultDateFormatHint": "The default date format for new users.", - "admin.general.defaultTimeFormat": "Default Time Format", - "admin.general.defaultTimeFormat12h": "12 hour", - "admin.general.defaultTimeFormat24h": "24 hour", - "admin.general.defaultTimeFormatHint": "The default time format for new users.", - "admin.general.defaultTimezone": "Default Timezone", - "admin.general.defaultTimezoneHint": "The default timezone for new users.", - "admin.general.defaultTocDepth": "Default ToC Depth", - "admin.general.defaultTocDepthHint": "The default minimum and maximum header levels to show in the table of contents.", - "admin.general.defaults": "Site Defaults", - "admin.general.discoverable": "Make Discoverable in the Wiki Directory", - "admin.general.discoverableHint": "Add your wiki to the Wiki Directory so that it can be discovered by other users and wikis.", - "admin.general.discovery": "Discovery", - "admin.general.displaySiteTitle": "Display Site Title", - "admin.general.displaySiteTitleHint": "Should the site title be displayed next to the logo? If your logo isn't square and contain your brand name, turn this option off.", - "admin.general.favicon": "Favicon", - "admin.general.faviconHint": "Favicon image file, in SVG, PNG, JPG, WEBP or GIF format. Must be a square image.", - "admin.general.faviconUploadSuccess": "Site Favicon uploaded successfully.", - "admin.general.features": "Features", - "admin.general.footerCopyright": "Footer / Copyright", - "admin.general.footerExtra": "Additional Footer Text", - "admin.general.footerExtraHint": "Optionally add more content to the footer, such as additional copyright terms or mandatory regulatory info.", - "admin.general.general": "General", - "admin.general.logo": "Logo", - "admin.general.logoUpl": "Site Logo", - "admin.general.logoUplHint": "Logo image file, in SVG, PNG, JPG, WEBP or GIF format.", - "admin.general.logoUploadSuccess": "Site logo uploaded successfully.", - "admin.general.pageCasing": "Case Sensitive Paths", - "admin.general.pageCasingHint": "Treat paths with different casing as distinct pages.", - "admin.general.pageExtensions": "Page Extensions", - "admin.general.pageExtensionsHint": "A comma-separated list of URL extensions that will be treated as pages. For example, adding md will treat /foobar.md the same as /foobar.", - "admin.general.ratingsOff": "Off", - "admin.general.ratingsStars": "Stars", - "admin.general.ratingsThumbs": "Thumbs", - "admin.general.reasonForChange": "Reason for Change", - "admin.general.reasonForChangeHint": "Should users be prompted the reason for changes made to a page?", - "admin.general.reasonForChangeOff": "Off", - "admin.general.reasonForChangeOptional": "Optional", - "admin.general.reasonForChangeRequired": "Required", - "admin.general.saveSuccess": "Site configuration saved successfully.", - "admin.general.searchAllowFollow": "Allow Search Engines to Follow Links", - "admin.general.searchAllowFollowHint": "This sets the meta-robots property to follow or nofollow.", - "admin.general.searchAllowIndexing": "Allow Indexing by Search Engines", - "admin.general.searchAllowIndexingHint": "This sets the meta-robots property to index or noindex.", - "admin.general.senderEmailHint": "Email address of the sender.", - "admin.general.senderNameHint": "Name of the sender.", - "admin.general.siteBranding": "Site Branding", - "admin.general.siteDescription": "Site Description", - "admin.general.siteDescriptionHint": "Default description when none is provided for a page.", - "admin.general.siteHostname": "Site Hostname", - "admin.general.siteHostnameHint": "Hostname this site should respond to. Set * for catch-all / fallback domain.", - "admin.general.siteHostnameInvalid": "Invalid Hostname", - "admin.general.siteInfo": "Site Info", - "admin.general.siteTitle": "Site Title", - "admin.general.siteTitleHint": "Displayed in the top bar and appended to all pages meta title.", - "admin.general.siteTitleInvalidChars": "Site Title contains invalid characters.", - "admin.general.sitemap": "Allow Sitemap", - "admin.general.sitemapHint": "Make a sitemap.xml available to search engines with all pages accessible to guests.", - "admin.general.subtitle": "Main settings of your wiki", - "admin.general.title": "General", - "admin.general.uploadClear": "Clear", - "admin.general.uploadConflictBehavior": "Upload Conflict Behavior", - "admin.general.uploadConflictBehaviorHint": "How should uploads for a file that already exists be handled?", - "admin.general.uploadConflictBehaviorNew": "Append Time to Filename", - "admin.general.uploadConflictBehaviorOverwrite": "Overwrite", - "admin.general.uploadConflictBehaviorReject": "Reject", - "admin.general.uploadLogo": "Upload Logo", - "admin.general.uploadNormalizeFilename": "Normalize Filenames", - "admin.general.uploadNormalizeFilenameHint": "Automatically transform filenames to a standard URL-friendly format.", - "admin.general.uploadSizeHint": "An image of {size} pixels is recommended for best results.", - "admin.general.uploadTypesHint": "{typeList} or {lastType} files only", - "admin.general.uploads": "Uploads", - "admin.general.urlHandling": "URL Handling", - "admin.groups.assignUser": "Assign User", - "admin.groups.authBehaviors": "Authentication Behaviors", - "admin.groups.create": "New Group", - "admin.groups.createSuccess": "Group created successfully.", - "admin.groups.delete": "Delete Group", - "admin.groups.deleteConfirm": "Are you sure you want delete group {groupName}? Any user currently assigned to this group will be unassigned from it.", - "admin.groups.deleteConfirmWarn": "This action cannot be undone!", - "admin.groups.deleteSuccess": "Group was deleted successfully.", - "admin.groups.edit": "Edit Group", - "admin.groups.exportRules": "Export Rules", - "admin.groups.exportRulesNoneError": "This group has no rule to export!", - "admin.groups.filterUsers": "Filter...", - "admin.groups.general": "General", - "admin.groups.importFailed": "Something went wrong while importing this file. Making sure it is a valid rules JSON file.", - "admin.groups.importModeAdd": "Add to Existing", - "admin.groups.importModeReplace": "Replace All", - "admin.groups.importModeText": "Do you want to replace all existing rules with these ones or add these rules to the existing ones?", - "admin.groups.importModeTitle": "Add or replace?", - "admin.groups.importRules": "Import Rules", - "admin.groups.importSuccess": "Rules imported successfully!", - "admin.groups.info": "Group Info", - "admin.groups.name": "Group Name", - "admin.groups.nameHint": "Name of the group", - "admin.groups.overview": "Overview", - "admin.groups.permissions": "Permissions", - "admin.groups.redirectOnFirstLogin": "First-time Login Redirect", - "admin.groups.redirectOnFirstLoginHint": "Optionally redirect the user to a specific page when he/she login for the first time. Leave empty to use the site-defined value.", - "admin.groups.redirectOnLogin": "Redirect on Login", - "admin.groups.redirectOnLoginHint": "The path / URL where the user will be redirected upon successful login. Leave empty to use the site-defined value.", - "admin.groups.redirectOnLogout": "Redirect on Logout", - "admin.groups.redirectOnLogoutHint": "The path / URL where the user will be redirected upon logout. Leave empty to use the site-defined value.", - "admin.groups.refreshSuccess": "Groups refreshed successfully.", - "admin.groups.ruleAllow": "Allow", - "admin.groups.ruleDeny": "Deny", - "admin.groups.ruleForceAllow": "Force Allow", - "admin.groups.ruleLocales": "Locale(s)", - "admin.groups.ruleMatchEnd": "Path Ends With...", - "admin.groups.ruleMatchExact": "Path Is Exactly...", - "admin.groups.ruleMatchRegex": "Path Matches Regex...", - "admin.groups.ruleMatchStart": "Path Starts With...", - "admin.groups.ruleMatchTag": "Has Any Tag...", - "admin.groups.ruleMatchTagAll": "Has All Tags...", - "admin.groups.ruleSites": "Site(s)", - "admin.groups.ruleUntitled": "Untitled Rule", - "admin.groups.rules": "Rules", - "admin.groups.rulesNone": "This group doesn't have any rules yet.", - "admin.groups.selectedLocales": "Any Locale | {n} locale only | {count} locales selected", - "admin.groups.selectedSites": "Any Site | 1 site selected | {count} sites selected", - "admin.groups.subtitle": "Manage user groups and permissions", - "admin.groups.title": "Groups", - "admin.groups.userCount": "User Count", - "admin.groups.users": "Users", - "admin.groups.usersCount": "0 user | 1 user | {count} users", - "admin.groups.usersNone": "This group doesn't have any user yet.", - "admin.icons.mandatory": "Used by the system and cannot be disabled.", - "admin.icons.reference": "Reference", - "admin.icons.subtitle": "Configure the icon packs available for use", - "admin.icons.title": "Icons", - "admin.icons.warnHint": "Only activate the icon packs you actually use.", - "admin.icons.warnLabel": "Enabling additional icon packs can significantly increase page load times!", - "admin.instances.activeConnections": "Active Connections", - "admin.instances.activeListeners": "Active Listeners", - "admin.instances.firstSeen": "First Seen", - "admin.instances.lastSeen": "Last Seen", - "admin.instances.subtitle": "View a list of active instances", - "admin.instances.title": "Instances", - "admin.locale.active": "Active Locales", - "admin.locale.activeNamespaces": "Active Namespaces", - "admin.locale.autoUpdate.hint": "Automatically download updates to this locale as they become available.", - "admin.locale.autoUpdate.hintWithNS": "Automatically download updates to all namespaced locales enabled below.", - "admin.locale.autoUpdate.label": "Update Automatically", - "admin.locale.availability": "Availability", - "admin.locale.base.hint": "All UI text elements will be displayed in selected language.", - "admin.locale.base.label": "Site Locale", - "admin.locale.base.labelWithNS": "Base Locale", - "admin.locale.code": "Code", - "admin.locale.download": "Download", - "admin.locale.downloadNew": "Install New Locale", - "admin.locale.downloadTitle": "Download Locale", - "admin.locale.forcePrefix": "Force Locale Prefix", - "admin.locale.forcePrefixHint": "Paths without a locale code will always be redirected to the primary locale.", - "admin.locale.name": "Name", - "admin.locale.namespaces.hint": "Enables multiple language versions of the same page.", - "admin.locale.namespaces.label": "Multilingual Namespaces", - "admin.locale.namespacing": "Multilingual Namespacing", - "admin.locale.namespacingPrefixWarning.subtitle": "Paths without a locale code will be automatically redirected to the base locale defined above.", - "admin.locale.namespacingPrefixWarning.title": "The locale code will be prefixed to all paths. (e.g. /{langCode}/page-name)", - "admin.locale.nativeName": "Native Name", - "admin.locale.primary": "Primary Locale", - "admin.locale.primaryHint": "The locale to use as default / fallback for this site.", - "admin.locale.rtl": "RTL", - "admin.locale.settings": "Locale Settings", - "admin.locale.sideload": "Sideload Locale Package", - "admin.locale.sideloadHelp": "If you are not connected to the internet or cannot download locale files using the method above, you can instead sideload packages manually by uploading them below.", - "admin.locale.subtitle": "Set localization options for your wiki", - "admin.locale.title": "Locale", - "admin.logging.title": "Logging", - "admin.login.background": "Background Image", - "admin.login.backgroundHint": "Specify an image to use as the login background. PNG and JPG are supported, 1920x1080 recommended. Leave empty for default.", - "admin.login.bgUploadSuccess": "Login background image uploaded successfully.", - "admin.login.bypassScreen": "Bypass Login Screen", - "admin.login.bypassScreenHint": "Should the user be redirected automatically to the first authentication provider. Has no effect if the first provider is a username/password provider type.", - "admin.login.bypassUnauthorized": "Bypass Unauthorized Screen", - "admin.login.bypassUnauthorizedHint": "Always redirect the user to the login screen instead of showing an unauthorized error page when the user is not logged in.", - "admin.login.experience": "User Experience", - "admin.login.loginRedirect": "Login Redirect", - "admin.login.loginRedirectHint": "Optionally redirect the user to a specific page when he/she logins (except if first time login which is defined below). This can be overridden at the group level.", - "admin.login.logoutRedirect": "Logout Redirect", - "admin.login.logoutRedirectHint": "Optionally redirect the user to a specific page when he/she logouts. This can be overridden at the group level.", - "admin.login.providers": "Login Providers", - "admin.login.providersVisbleWarning": "Note that you can always temporarily show all hidden providers by adding ?all=1 to the url. This is useful to login as local admin while hiding it from normal users.", - "admin.login.saveSuccess": "Login configuration saved successfully.", - "admin.login.subtitle": "Configure the login user experience of your wiki site", - "admin.login.title": "Login", - "admin.login.welcomeRedirect": "First-time Login Redirect", - "admin.login.welcomeRedirectHint": "Optionally redirect the user to a specific page when he/she login for the first time. This can be overridden at the group level.", - "admin.mail.configuration": "Configuration", - "admin.mail.defaultBaseURL": "Default Base URL", - "admin.mail.dkim": "DKIM (optional)", - "admin.mail.dkimDomainName": "Domain Name", - "admin.mail.dkimDomainNameHint": "Domain name used for DKIM validation.", - "admin.mail.dkimHint": "DKIM (DomainKeys Identified Mail) provides a layer of security on all emails sent from Wiki.js by providing the means for recipients to validate the domain name and ensure the message authenticity.", - "admin.mail.dkimKeySelector": "Key Selector", - "admin.mail.dkimKeySelectorHint": "Determines which key to use for DKIM in your DNS records.", - "admin.mail.dkimPrivateKey": "Private Key", - "admin.mail.dkimPrivateKeyHint": "Private key for the selector in PEM format", - "admin.mail.dkimUse": "Use DKIM", - "admin.mail.dkimUseHint": "Should DKIM be used when sending emails.", - "admin.mail.saveSuccess": "Configuration saved successfully.", - "admin.mail.sendTestSuccess": "A test email was sent successfully.", - "admin.mail.sender": "Sender", - "admin.mail.senderEmail": "Sender Email", - "admin.mail.senderName": "Sender Name", - "admin.mail.smtp": "SMTP Settings", - "admin.mail.smtpHost": "Host", - "admin.mail.smtpHostHint": "Hostname or IP address of the SMTP server.", - "admin.mail.smtpName": "Client Identifying Name", - "admin.mail.smtpNameHint": "An optional name to send to the SMTP server to identify your mailer. Leave empty to use server hostname. For Google Workspace customers, this should be your main domain name.", - "admin.mail.smtpPort": "Port", - "admin.mail.smtpPortHint": "Usually 465 (recommended), 587 or 25.", - "admin.mail.smtpPwd": "Password", - "admin.mail.smtpPwdHint": "Password used for authenticating to the SMTP server.", - "admin.mail.smtpTLS": "Secure (TLS)", - "admin.mail.smtpTLSHint": "Should be enabled when using port 465, otherwise turned off (587 or 25).", - "admin.mail.smtpUser": "Username", - "admin.mail.smtpUserHint": "Username used for authenticating to the SMTP server.", - "admin.mail.smtpVerifySSL": "Verify SSL Certificate", - "admin.mail.smtpVerifySSLHint": "Some hosts requires SSL certificate checking to be disabled. Leave enabled for proper security.", - "admin.mail.subtitle": "Configure mail settings", - "admin.mail.templateEditor": "Mail Template Editor", - "admin.mail.templateResetPwd": "Password Reset Email", - "admin.mail.templateWelcome": "Welcome Email", - "admin.mail.templates": "Mail Templates", - "admin.mail.test": "Send a test email", - "admin.mail.testHint": "Send a test email to ensure your SMTP configuration is working.", - "admin.mail.testRecipient": "Recipient Email Address", - "admin.mail.testRecipientHint": "Email address that should receive the test email.", - "admin.mail.testSend": "Send Email", - "admin.mail.title": "Mail", - "admin.metrics.auth": "You must provide the {headerName} header with a {tokenType} token. Generate an API key with the {permission} permission and use it as the token.", - "admin.metrics.disabled": "Endpoint Disabled", - "admin.metrics.enabled": "Endpoint Enabled", - "admin.metrics.endpoint": "The metrics endpoint can be scraped at {endpoint}", - "admin.metrics.endpointWarning": "Note that this override any page at this path.", - "admin.metrics.refreshSuccess": "Metrics endpoint state has been refreshed.", - "admin.metrics.subtitle": "Manage the Prometheus metrics endpoint", - "admin.metrics.title": "Metrics", - "admin.metrics.toggleStateDisabledSuccess": "Metrics endpoint disabled successfully.", - "admin.metrics.toggleStateEnabledSuccess": "Metrics endpoint enabled successfully.", - "admin.nav.modules": "Modules", - "admin.nav.site": "Site", - "admin.nav.system": "System", - "admin.nav.users": "Users", - "admin.navigation.copyFromLocale": "Copy from locale...", - "admin.navigation.copyFromLocaleInfoText": "Select the locale from which items will be copied from. Items will be appended to the current list of items in the active locale.", - "admin.navigation.delete": "Delete {kind}", - "admin.navigation.divider": "Divider", - "admin.navigation.edit": "Edit {kind}", - "admin.navigation.emptyList": "Navigation is empty", - "admin.navigation.header": "Header", - "admin.navigation.icon": "Icon", - "admin.navigation.label": "Label", - "admin.navigation.link": "Link", - "admin.navigation.mode": "Navigation Mode", - "admin.navigation.modeCustom.description": "Static Navigation Menu + Site Tree Button", - "admin.navigation.modeCustom.title": "Custom Navigation", - "admin.navigation.modeNone.description": "Disable Site Navigation", - "admin.navigation.modeNone.title": "None", - "admin.navigation.modeSiteTree.description": "Classic Tree-based Navigation", - "admin.navigation.modeSiteTree.title": "Site Tree", - "admin.navigation.modeStatic.description": "Static Navigation Menu Only", - "admin.navigation.modeStatic.title": "Static Navigation", - "admin.navigation.navType.external": "External Link", - "admin.navigation.navType.externalblank": "External Link (New Window)", - "admin.navigation.navType.home": "Home", - "admin.navigation.navType.page": "Page", - "admin.navigation.navType.searchQuery": "Search Query", - "admin.navigation.noItemsText": "Click the Add button to add your first navigation item.", - "admin.navigation.noSelectionText": "Select a navigation item on the left.", - "admin.navigation.saveSuccess": "Navigation saved successfully.", - "admin.navigation.selectPageButton": "Select Page...", - "admin.navigation.sourceLocale": "Source Locale", - "admin.navigation.sourceLocaleHint": "The locale from which navigation items will be copied from.", - "admin.navigation.subtitle": "Manage the site navigation", - "admin.navigation.target": "Target", - "admin.navigation.targetType": "Target Type", - "admin.navigation.title": "Navigation", - "admin.navigation.untitled": "Untitled {kind}", - "admin.navigation.visibilityMode.all": "Visible to everyone", - "admin.navigation.visibilityMode.restricted": "Visible to select groups...", - "admin.pages.title": "Pages", - "admin.rendering.subtitle": "Configure the content rendering pipeline", - "admin.rendering.title": "Rendering", - "admin.scheduler.active": "Active", - "admin.scheduler.activeNone": "There are no active jobs at the moment.", - "admin.scheduler.attempt": "Attempt", - "admin.scheduler.cancelJob": "Cancel Job", - "admin.scheduler.cancelJobSuccess": "Job cancelled successfully.", - "admin.scheduler.completed": "Completed", - "admin.scheduler.completedIn": "Completed in {duration}", - "admin.scheduler.completedNone": "There are no recently completed job to display.", - "admin.scheduler.createdAt": "Created", - "admin.scheduler.createdBy": "by instance {instance}", - "admin.scheduler.cron": "Cron", - "admin.scheduler.error": "Error", - "admin.scheduler.failed": "Failed", - "admin.scheduler.failedNone": "There are no recently failed job to display.", - "admin.scheduler.interrupted": "Interrupted", - "admin.scheduler.pending": "Pending", - "admin.scheduler.result": "Result", - "admin.scheduler.retryJob": "Retry Job", - "admin.scheduler.retryJobSuccess": "Job has been rescheduled and will execute shortly.", - "admin.scheduler.schedule": "Schedule", - "admin.scheduler.scheduled": "Scheduled", - "admin.scheduler.scheduledNone": "There are no scheduled jobs at the moment.", - "admin.scheduler.startedAt": "Started", - "admin.scheduler.state": "State", - "admin.scheduler.subtitle": "View scheduled and completed jobs", - "admin.scheduler.title": "Scheduler", - "admin.scheduler.type": "Type", - "admin.scheduler.upcoming": "Upcoming", - "admin.scheduler.upcomingNone": "There are no upcoming job for the moment.", - "admin.scheduler.updatedAt": "Last Updated", - "admin.scheduler.useWorker": "Execution Mode", - "admin.scheduler.waitUntil": "Start", - "admin.search.configSaveSuccess": "Search engine configuration saved successfully.", - "admin.search.dictOverrides": "PostgreSQL Dictionary Mapping Overrides", - "admin.search.dictOverridesHint": "JSON object of 2 letters locale codes and their PostgreSQL dictionary association. e.g. {0}", - "admin.search.engineConfig": "Engine Configuration", - "admin.search.engineNoConfig": "This engine has no configuration options you can modify.", - "admin.search.highlighting": "Enable Term Highlighting", - "admin.search.highlightingHint": "Whether to show the highlighted terms in search results. There is a slight performance impact when enabled.", - "admin.search.indexRebuildSuccess": "Index rebuilt successfully.", - "admin.search.listRefreshSuccess": "List of search engines has been refreshed.", - "admin.search.rebuildIndex": "Rebuild Index", - "admin.search.rebuildInitSuccess": "A search index rebuild has been initiated and will start shortly.", - "admin.search.saveSuccess": "Search engine configuration saved successfully", - "admin.search.searchEngine": "Search Engine", - "admin.search.subtitle": "Configure the search capabilities of your wiki", - "admin.search.title": "Search Engine", - "admin.searchRebuildIndex": "Rebuild Index", - "admin.security.cors": "CORS (Cross-Origin Resource Sharing)", - "admin.security.corsHostnames": "Hostnames Whitelist", - "admin.security.corsHostnamesHint": "Enter one hostname per line", - "admin.security.corsMode": "CORS Mode", - "admin.security.corsModeHint": "How the GraphQL server should handle preflight requests?", - "admin.security.corsRegex": "Regex Pattern", - "admin.security.corsRegexHint": "Pattern against which the request hostname is matched.", - "admin.security.disallowFloc": "Disallow Google FLoC", - "admin.security.disallowFlocHint": "Broadcast that this website should be opted-out of Google Federed Learning of Cohorts (FLoC). Recommended for privacy.", - "admin.security.disallowIframe": "Disallow iFrame Embedding", - "admin.security.disallowIframeHint": "Prevents other websites from embedding your wiki in an iframe. This provides clickjacking protection.", - "admin.security.disallowOpenRedirect": "Block Open Redirect", - "admin.security.disallowOpenRedirectHint": "Prevents user controlled URLs from directing to websites outside of your wiki. This provides Open Redirect protection.", - "admin.security.enforce2fa": "Enforce 2FA", - "admin.security.enforce2faHint": "Force all users to use Two-Factor Authentication when using an authentication provider with a user / password form.", - "admin.security.enforceHsts": "Enforce HSTS", - "admin.security.enforceHstsHint": "This ensures the connection cannot be established through an insecure HTTP connection.", - "admin.security.enforceSameOriginReferrerPolicy": "Enforce Same-Origin Referrer Policy", - "admin.security.enforceSameOriginReferrerPolicyHint": "Whether the referrer information should be included to requests to external endpoints.", - "admin.security.forceAssetDownload": "Force Asset Download for Unsafe Extensions", - "admin.security.forceAssetDownloadHint": "Should non-image files be forced as downloads when accessed directly. This prevents potential XSS attacks.", - "admin.security.hsts": "HSTS (HTTP Strict Transport Security)", - "admin.security.hstsDuration": "HSTS Max Age", - "admin.security.hstsDurationHint": "Defines the duration for which the server should only deliver content through HTTPS. It's a good idea to start with small values and make sure that nothing breaks on your wiki before moving to longer values.", - "admin.security.jwt": "JWT Configuration", - "admin.security.jwtAudience": "JWT Audience", - "admin.security.jwtAudienceHint": "Audience URN used in JWT issued upon login. Usually your domain name. (e.g. urn:your.domain.com)", - "admin.security.loginScreen": "Login Screen", - "admin.security.maxUploadBatch": "Max Files per Upload", - "admin.security.maxUploadBatchHint": "How many files can be uploaded in a single batch?", - "admin.security.maxUploadBatchSuffix": "files", - "admin.security.maxUploadSize": "Max Upload Size", - "admin.security.maxUploadSizeHint": "The maximum size for a single file. Final value in base 2.", - "admin.security.maxUploadSizeSuffix": "bytes", - "admin.security.saveSuccess": "Security configuration updated successfully.", - "admin.security.scanSVG": "Scan and Sanitize SVG Uploads", - "admin.security.scanSVGHint": "Should SVG uploads be scanned for vulnerabilities and stripped of any potentially unsafe content.", - "admin.security.subtitle": "Configure security settings", - "admin.security.title": "Security", - "admin.security.tokenEndpointAuthMethod": "Token Endpoint Authentication Method", - "admin.security.tokenExpiration": "Token Expiration", - "admin.security.tokenExpirationHint": "The expiration period of a token until it must be renewed. (default: 30m)", - "admin.security.tokenRenewalPeriod": "Token Renewal Period", - "admin.security.tokenRenewalPeriodHint": "The maximum period a token can be renewed when expired. (default: 14d)", - "admin.security.trustProxy": "Trust X-Forwarded-* Proxy Headers", - "admin.security.trustProxyHint": "Should be enabled when using a reverse-proxy like nginx, apache, CloudFlare, etc in front of Wiki.js. Turn off otherwise.", - "admin.security.uploads": "Uploads", - "admin.security.uploadsInfo": "These settings only affect Wiki.js. If you're using a reverse-proxy (e.g. nginx, Apache, Cloudflare), you must also change its settings to match.", - "admin.security.warn": "Make sure to understand the implications before turning on / off a security feature.", - "admin.sites.activate": "Activate Site", - "admin.sites.activateConfirm": "Are you sure you want activate site {siteTitle}? The site will become accessible to users with read access.", - "admin.sites.createSuccess": "Site created successfully.", - "admin.sites.deactivate": "Deactivate Site", - "admin.sites.deactivateConfirm": "Are you sure you want deactivate site {siteTitle}? The site will no longer be accessible to users.", - "admin.sites.delete": "Delete Site", - "admin.sites.deleteConfirm": "Are you sure you want delete site {siteTitle}? This will permanently delete all site content (including pages, history, comments and assets) and configuration!", - "admin.sites.deleteConfirmWarn": "This action cannot be undone!", - "admin.sites.deleteSuccess": "Site was deleted successfully.", - "admin.sites.edit": "Edit Site", - "admin.sites.hostname": "Hostname", - "admin.sites.hostnameHint": "Must be a fully-qualified domain name (e.g. wiki.example.com) or * for a catch-all site. Note that there can only be 1 catch-all site.", - "admin.sites.isActive": "Active", - "admin.sites.new": "New Site", - "admin.sites.refreshSuccess": "List of sites refreshed successfully.", - "admin.sites.subtitle": "Manage your wiki sites", - "admin.sites.title": "Sites", - "admin.ssl.currentState": "Current State", - "admin.ssl.domain": "Domain", - "admin.ssl.domainHint": "Enter the fully qualified domain pointing to your wiki. (e.g. wiki.example.com)", - "admin.ssl.expiration": "Certificate Expiration", - "admin.ssl.httpPort": "HTTP Port", - "admin.ssl.httpPortHint": "Non-SSL port the server will listen to for HTTP requests. Usually 80 or 3000.", - "admin.ssl.httpPortRedirect": "Redirect HTTP requests to HTTPS", - "admin.ssl.httpPortRedirectHint": "Will automatically redirect any requests on the HTTP port to HTTPS.", - "admin.ssl.httpPortRedirectSaveSuccess": "HTTP Redirection changed successfully.", - "admin.ssl.httpPortRedirectTurnOff": "Turn Off", - "admin.ssl.httpPortRedirectTurnOn": "Turn On", - "admin.ssl.httpsPort": "HTTPS Port", - "admin.ssl.httpsPortHint": "SSL port the server will listen to for HTTPS requests. Usually 443.", - "admin.ssl.ports": "Ports", - "admin.ssl.provider": "Provider", - "admin.ssl.providerCustomCertificate": "Custom Certificate", - "admin.ssl.providerDisabled": "Disabled", - "admin.ssl.providerHint": "Select Custom Certificate if you have your own certificate already.", - "admin.ssl.providerLetsEncrypt": "Let's Encrypt", - "admin.ssl.providerOptions": "Provider Options", - "admin.ssl.renewCertificate": "Renew Certificate", - "admin.ssl.renewCertificateLoadingSubtitle": "Do not leave this page.", - "admin.ssl.renewCertificateLoadingTitle": "Renewing Certificate...", - "admin.ssl.renewCertificateSuccess": "Certificate renewed successfully.", - "admin.ssl.status": "Certificate Status", - "admin.ssl.subscriberEmail": "Subscriber Email", - "admin.ssl.subtitle": "Manage SSL configuration", - "admin.ssl.title": "SSL", - "admin.ssl.writableConfigFileWarning": "Note that your config file must be writable in order to persist ports configuration.", - "admin.stats.title": "Statistics", - "admin.storage.actionRun": "Run", - "admin.storage.actions": "Actions", - "admin.storage.actionsInactiveWarn": "You must enable this storage target and apply changes before you can run actions.", - "admin.storage.addTarget": "Add Storage Target", - "admin.storage.assetDelivery": "Asset Delivery", - "admin.storage.assetDeliveryHint": "Select how uploaded assets should be delivered to the user. Note that not all storage origins support asset delivery and some can only be used for backup purposes.", - "admin.storage.assetDirectAccess": "Direct Access", - "admin.storage.assetDirectAccessHint": "Assets are accessed directly by the user using a secure / signed link. When enabled, takes priority over file streaming.", - "admin.storage.assetDirectAccessNotSupported": "Not supported by this storage target.", - "admin.storage.assetStreaming": "File Streaming", - "admin.storage.assetStreamingHint": "Assets will be streamed from the storage target, through the server, to the user.", - "admin.storage.assetStreamingNotSupported": "Not supported by this storage target.", - "admin.storage.assetsOnly": "Assets Only", - "admin.storage.cancelSetup": "Cancel", - "admin.storage.config": "Configuration", - "admin.storage.contentTypeDocuments": "Documents", - "admin.storage.contentTypeDocumentsHint": "Text or presentation documents in PDF, TXT, Word, Excel and Powerpoint formats.", - "admin.storage.contentTypeImages": "Images", - "admin.storage.contentTypeImagesHint": "Image Assets in JPG, PNG, GIF, WebP and SVG formats.", - "admin.storage.contentTypeLargeFiles": "Large Files", - "admin.storage.contentTypeLargeFilesDBWarn": "For performance reasons, large files should not be stored in the database. Consider using another storage type for these files.", - "admin.storage.contentTypeLargeFilesHint": "Large files such as videos, zip archives and binaries. Pages never fall into this category, irrespective of their size.", - "admin.storage.contentTypeLargeFilesThreshold": "Size Threshold", - "admin.storage.contentTypeOthers": "Others", - "admin.storage.contentTypeOthersHint": "Any other file types that don't match the other categories.", - "admin.storage.contentTypePages": "Pages", - "admin.storage.contentTypePagesHint": "Page content source, in Markdown, HTML or JSON format depending on the editor.", - "admin.storage.contentTypes": "Content Types", - "admin.storage.contentTypesHint": "Select the type of content that should be stored to this storage target:", - "admin.storage.currentState": "Current State", - "admin.storage.deliveryPaths": "Delivery Paths", - "admin.storage.deliveryPathsLegend": "Legend:", - "admin.storage.deliveryPathsPushToOrigin": "Push to Origin", - "admin.storage.deliveryPathsUser": "User", - "admin.storage.deliveryPathsUserRequest": "User Request", - "admin.storage.destroyConfirm": "Confirm Setup Reset", - "admin.storage.destroyConfirmInfo": "Are you sure you want to reset the storage target setup configuration? Note that this action cannot be undone and you will need to start the setup process over.", - "admin.storage.destroyingSetup": "Resetting storage target setup configuration...", - "admin.storage.enabled": "Enabled", - "admin.storage.enabledForced": "Cannot be disabled on the database target.", - "admin.storage.enabledHint": "Should this storage target be used for storing and accessing assets.", - "admin.storage.errorMsg": "Error Message", - "admin.storage.finishSetup": "Finish Setup", - "admin.storage.githubAccTypeOrg": "Organization", - "admin.storage.githubAccTypePersonal": "Personal", - "admin.storage.githubFinish": "Once you have installed the application on the GitHub repository of your choice, click the Finish Setup button below to validate the installation and start using it. Otherwise, click Destroy to delete any pending configuration and start over.", - "admin.storage.githubInstallApp": "Setup GitHub Connection - Step 2", - "admin.storage.githubInstallAppHint": "On the next screen, you will be prompted to install the app you just created onto one or more repositories. You may select a single one or all repositories.", - "admin.storage.githubOrg": "GitHub Organization", - "admin.storage.githubOrgHint": "Enter the GitHub organization account to be used.", - "admin.storage.githubPreparingManifest": "Preparing manifest...", - "admin.storage.githubPublicUrl": "Wiki Public URL", - "admin.storage.githubPublicUrlHint": "Enter the full URL to your wiki (e.g. https://wiki.example.com). Note that your wiki MUST be accessible from the internet!", - "admin.storage.githubRedirecting": "Redirecting to GitHub...", - "admin.storage.githubRepo": "GitHub Repository", - "admin.storage.githubRepoCreating": "Creating GitHub Repository...", - "admin.storage.githubRepoHint": "Enter the name of the repository to create on GitHub and use for this wiki:", - "admin.storage.githubSetupContinue": "Continue Setup", - "admin.storage.githubSetupDestroyFailed": "Failed to destroy setup configuration.", - "admin.storage.githubSetupDestroySuccess": "Setup configuration has been reset successfully.", - "admin.storage.githubSetupFailed": "GitHub Setup failed.", - "admin.storage.githubSetupInstallApp": "GitHub Connection Setup - Step 2", - "admin.storage.githubSetupInstallAppInfo": "On the next screen, you'll be prompted to install the app you just created onto one or more GitHub repositories.", - "admin.storage.githubSetupInstallAppReturn": "Once the installation on GitHub is completed, you will need to manually return to this page to finish the setup.", - "admin.storage.githubSetupInstallAppSelect": "IMPORTANT: Select only the repository that will be used to sync with this wiki.", - "admin.storage.githubSetupSuccess": "Success! Wiki.js is now connected to GitHub.", - "admin.storage.githubVerifying": "Verifying GitHub configuration...", - "admin.storage.inactiveTarget": "Inactive", - "admin.storage.lastSync": "Last synchronization {time}", - "admin.storage.lastSyncAttempt": "Last attempt was {time}", - "admin.storage.missingOrigin": "Missing Origin", - "admin.storage.noActions": "This storage target has no actions that you can execute.", - "admin.storage.noConfigOption": "This storage target has no configuration options you can modify.", - "admin.storage.noSyncModes": "This storage target has no synchronization options you can modify.", - "admin.storage.noTarget": "You don't have any active storage target.", - "admin.storage.notConfigured": "Not Configured", - "admin.storage.pagesAndAssets": "Pages and Assets", - "admin.storage.pagesOnly": "Pages Only", - "admin.storage.saveFailed": "Failed to save storage configuration.", - "admin.storage.saveSuccess": "Storage configuration saved successfully.", - "admin.storage.setup": "Setup", - "admin.storage.setupConfiguredHint": "This module is already configured. You can uninstall this module to start over.", - "admin.storage.setupHint": "This module requires a setup process to be completed in order to use it. Follow the instructions below to get started.", - "admin.storage.setupRequired": "Setup required", - "admin.storage.startSetup": "Start Setup", - "admin.storage.status": "Status", - "admin.storage.subtitle": "Set backup and sync targets for your content", - "admin.storage.sync": "Synchronization", - "admin.storage.syncDirBi": "Bi-directional", - "admin.storage.syncDirBiHint": "In bi-directional mode, content is first pulled from the storage target. Any newer content overwrites local content. New content since last sync is then pushed to the storage target, overwriting any content on target if present.", - "admin.storage.syncDirPull": "Pull from target", - "admin.storage.syncDirPullHint": "Content is always pulled from the storage target, overwriting any local content which already exists. This choice is usually reserved for single-use content import. Caution with this option as any local content will always be overwritten!", - "admin.storage.syncDirPush": "Push to target", - "admin.storage.syncDirPushHint": "Content is always pushed to the storage target, overwriting any existing content. This is safest choice for backup scenarios.", - "admin.storage.syncDirection": "Sync Direction", - "admin.storage.syncDirectionSubtitle": "Choose how content synchronization is handled for this storage target.", - "admin.storage.syncSchedule": "Sync Schedule", - "admin.storage.syncScheduleCurrent": "Currently set to every {schedule}.", - "admin.storage.syncScheduleDefault": "The default is every {schedule}.", - "admin.storage.syncScheduleHint": "For performance reasons, this storage target synchronize changes on an interval-based schedule, instead of on every change. Define at which interval should the synchronization occur.", - "admin.storage.targetConfig": "Target Configuration", - "admin.storage.targetState": "This storage target is {state}", - "admin.storage.targetStateActive": "active", - "admin.storage.targetStateInactive": "inactive", - "admin.storage.targets": "Targets", - "admin.storage.title": "Storage", - "admin.storage.uninstall": "Uninstall", - "admin.storage.unsupported": "Unsupported", - "admin.storage.useVersioning": "Use Versioning", - "admin.storage.useVersioningHint": "Should previous versions of assets be retained on the storage target.", - "admin.storage.vendor": "Vendor", - "admin.storage.vendorWebsite": "Website", - "admin.storage.versioning": "Asset Versioning", - "admin.storage.versioningForceEnabled": "Cannot be disabled on this storage target.", - "admin.storage.versioningHint": "Asset versioning allows for storage of all previous versions of the same file. Unless you have a requirement to store all versions of uploaded assets, it's recommended to leave this oftion off as it can consume significant storage space over time.", - "admin.storage.versioningNotSupported": "Not supported by this storage target.", - "admin.system.browser": "Browser", - "admin.system.browserHint": "The browser name and version.", - "admin.system.checkForUpdates": "Check", - "admin.system.checkUpdate": "Check / Upgrade", - "admin.system.checkingForUpdates": "Checking for Updates...", - "admin.system.client": "Client", - "admin.system.clientCookies": "Cookies Support", - "admin.system.clientCookiesHint": "Whether cookies are enabled on this browser.", - "admin.system.clientLanguage": "Primary Language", - "admin.system.clientLanguageHint": "The main language advertised by the browser.", - "admin.system.clientPlatform": "Platform", - "admin.system.clientPlatformHint": "The OS platform the browser is running on.", - "admin.system.clientViewport": "Viewport", - "admin.system.clientViewportHint": "The viewport dimensions available to the website.", - "admin.system.configFile": "Configuration File", - "admin.system.configFileHint": "The path to the Wiki.js configuration file.", - "admin.system.cpuCores": "CPU Cores", - "admin.system.cpuCoresHint": "The number of CPU cores available to Wiki.js.", - "admin.system.currentVersion": "Current Version", - "admin.system.currentVersionHint": "The currently installed version.", - "admin.system.database": "Database", - "admin.system.databaseHint": "The version of the database in use.", - "admin.system.databaseHost": "Database Host", - "admin.system.databaseHostHint": "The hostname used to access the database.", - "admin.system.dbPartialSupport": "Your database version is not fully supported. Some functionality may be limited or not work as expected.", - "admin.system.engines": "Server Engines", - "admin.system.fetchingLatestVersionInfo": "Fetching latest version info...", - "admin.system.hostInfo": "Server Host Information", - "admin.system.hostname": "Hostname", - "admin.system.hostnameHint": "The hostname of the server / container.", - "admin.system.latestVersion": "Latest Version", - "admin.system.latestVersionHint": "The latest version available to install.", - "admin.system.newVersionAvailable": "A new version is available.", - "admin.system.nodejsHint": "The version of Node.js installed.", - "admin.system.os": "Operating System", - "admin.system.osHint": "The OS Wiki.js is running on.", - "admin.system.published": "Published", - "admin.system.ramUsage": "RAM Usage: {used} / {total}", - "admin.system.refreshSuccess": "System Info has been refreshed.", - "admin.system.runningLatestVersion": "You're running the latest version.", - "admin.system.subtitle": "Information about your server / client", - "admin.system.title": "System Info", - "admin.system.totalRAM": "Total RAM", - "admin.system.totalRAMHint": "The total amount of RAM available to Wiki.js.", - "admin.system.upgrade": "Upgrade", - "admin.system.workingDirectory": "Working Directory", - "admin.system.workingDirectoryHint": "The directory path where Wiki.js is currently running from.", - "admin.tags.date": "Created {created} and last updated {updated}.", - "admin.tags.delete": "Delete this tag", - "admin.tags.deleteConfirm": "Delete Tag?", - "admin.tags.deleteConfirmText": "Are you sure you want to delete tag {tag}? The tag will also be unlinked from all pages.", - "admin.tags.deleteSuccess": "Tag deleted successfully.", - "admin.tags.edit": "Edit Tag", - "admin.tags.emptyList": "No tags to display.", - "admin.tags.filter": "Filter...", - "admin.tags.label": "Label", - "admin.tags.noItemsText": "Add a tag to a page to get started.", - "admin.tags.noSelectionText": "Select a tag from the list on the left.", - "admin.tags.refreshSuccess": "Tags have been refreshed.", - "admin.tags.saveSuccess": "Tag has been saved successfully.", - "admin.tags.subtitle": "Manage page tags", - "admin.tags.tag": "Tag", - "admin.tags.title": "Tags", - "admin.tags.viewLinkedPages": "View Linked Pages", - "admin.terminal.clear": "Clear", - "admin.terminal.command": "Command", - "admin.terminal.connect": "Connect", - "admin.terminal.connectError": "Connection Error:", - "admin.terminal.connected": "Connected.", - "admin.terminal.connecting": "Connecting to server...", - "admin.terminal.disconnect": "Disconnect", - "admin.terminal.disconnected": "Disconnected.", - "admin.terminal.logs": "Logs", - "admin.terminal.subtitle": "View process logs in real-time", - "admin.terminal.title": "Terminal", - "admin.theme.accentColor": "Accent Color", - "admin.theme.accentColorHint": "The accent color for elements that need to stand out or grab the user attention.", - "admin.theme.appearance": "Appearance", - "admin.theme.baseFont": "Base Font", - "admin.theme.baseFontHint": "The font used across the site for the interface.", - "admin.theme.bodyHtmlInjection": "Body HTML Injection", - "admin.theme.bodyHtmlInjectionHint": "HTML code to be injected just before the closing body tag.", - "admin.theme.codeBlocks": "Code Blocks", - "admin.theme.codeBlocksAppearance": "Code Blocks Appearance", - "admin.theme.codeBlocksAppearanceHint": "The color theme used to display code blocks on pages.", - "admin.theme.codeInjection": "Code Injection", - "admin.theme.contentFont": "Content Font", - "admin.theme.contentFontHint": "The font used specifically for page content.", - "admin.theme.contentWidth": "Content Width", - "admin.theme.contentWidthHint": "Should the content use all available viewport space or stay centered.", - "admin.theme.cssOverride": "CSS Override", - "admin.theme.cssOverrideHint": "CSS code to inject after system default CSS. Injecting too much CSS code can result in poor page load performance! CSS will automatically be minified.", - "admin.theme.cssOverrideWarning": "{caution} When adding styles for page content, you must scope them to the {cssClass} class. Omitting this could break the layout of the editor!", - "admin.theme.cssOverrideWarningCaution": "CAUTION:", - "admin.theme.darkMode": "Dark Mode", - "admin.theme.darkModeHint": "Not recommended for accessibility. Can always be turned off by the user.", - "admin.theme.downloadAuthor": "Author", - "admin.theme.downloadDownload": "Download", - "admin.theme.downloadName": "Name", - "admin.theme.downloadThemes": "Download Themes", - "admin.theme.fonts": "Fonts", - "admin.theme.headHtmlInjection": "Head HTML Injection", - "admin.theme.headHtmlInjectionHint": "HTML code to be injected just before the closing head tag. Usually for script tags.", - "admin.theme.headerColor": "Header Color", - "admin.theme.headerColorHint": "The background color for the site top header. Does not apply to the administration area.", - "admin.theme.iconset": "Icon Set", - "admin.theme.iconsetHint": "Set of icons to use for the sidebar navigation.", - "admin.theme.layout": "Layout", - "admin.theme.options": "Theme Options", - "admin.theme.primaryColor": "Primary Color", - "admin.theme.primaryColorHint": "The main color for primary action buttons and most form elements.", - "admin.theme.reduceMotion": "Reduce Motion", - "admin.theme.reduceMotionHint": "Disable most site animations. This setting is automatically enforced when the reduced motion flag is enabled on the user OS.", - "admin.theme.resetDefaults": "Reset Defaults", - "admin.theme.saveSuccess": "Theme configuration saved successfully!", - "admin.theme.secondaryColor": "Secondary Color", - "admin.theme.secondaryColorHint": "The alternate color for secondary action buttons and for some other elements.", - "admin.theme.showPrintBtn": "Show Print Button", - "admin.theme.showPrintBtnHint": "Should the print button be displayed on all pages. Note that this doesn't prevent the user from printing the page using the system dialog.", - "admin.theme.showSharingMenu": "Show Sharing Menu", - "admin.theme.showSharingMenuHint": "Should the sharing menu be displayed on all pages.", - "admin.theme.sidebarColor": "Sidebar Color", - "admin.theme.sidebarColorHint": "The background color for the side navigation menu on content pages. Does not apply to the administration area.", - "admin.theme.sidebarPosition": "Sidebar Position", - "admin.theme.sidebarPositionHint": "On which side should the main site navigation sidebar be displayed.", - "admin.theme.siteTheme": "Site Theme", - "admin.theme.siteThemeHint": "Themes affect how content pages are displayed. Other site sections (such as the editor or admin area) are not affected.", - "admin.theme.subtitle": "Modify the look & feel of your wiki", - "admin.theme.title": "Theme", - "admin.theme.tocPosition": "TOC Position", - "admin.theme.tocPositionHint": "On which side should the Table of Contents sidebar be displayed for content pages.", - "admin.users.active": "Active", - "admin.users.activity": "Activity", - "admin.users.appearance": "Site Appearance", - "admin.users.assignGroup": "Assign Group", - "admin.users.auth": "Authentication", - "admin.users.authProvider": "Provider", - "admin.users.authProviderId": "Provider Id", - "admin.users.authentication": "Authentication", - "admin.users.ban": "Ban User", - "admin.users.banHint": "Block the user from signing in and invalidate any active sessions.", - "admin.users.banned": "Banned", - "admin.users.basicInfo": "Basic Info", - "admin.users.changePassword": "Change Password", - "admin.users.changePasswordHint": "Change the user password. Note that the current password cannot be recovered.", - "admin.users.changePasswordSuccess": "User password was updated successfully.", - "admin.users.create": "Create User", - "admin.users.createInvalidData": "Cannot create user as some fields are invalid or missing.", - "admin.users.createKeepOpened": "Keep dialog opened after create", - "admin.users.createSendEmailMissingSiteId": "You must specify the wiki site to reference for the welcome email.", - "admin.users.createSuccess": "User created successfully!", - "admin.users.createdAt": "Created on {date}", - "admin.users.darkMode": "Dark Mode", - "admin.users.darkModeHint": "Display the user interface using dark mode.", - "admin.users.dateFormat": "Date Format", - "admin.users.dateFormatHint": "How dates should be formatted when displayed to the user.", - "admin.users.defaults": "Manage User Defaults", - "admin.users.defaultsSaveSuccess": "User defaults saved successfully.", - "admin.users.delete": "Delete User", - "admin.users.deleteConfirmForeignNotice": "Note that you cannot delete a user that already created content. You must instead either deactivate the user or delete all content that was created by that user.", - "admin.users.deleteConfirmReplaceWarn": "Any content (pages, uploads, comments, etc.) that was created by this user will be reassigned to the user selected below. It is recommended to create a dummy target user (e.g. Deleted User) if you don't want the content to be reassigned to any current active user.", - "admin.users.deleteConfirmText": "Are you sure you want to delete user {username}?", - "admin.users.deleteConfirmTitle": "Delete User?", - "admin.users.deleteHint": "Permanently remove the user from the database. This action cannot be undone!", - "admin.users.displayName": "Display Name", - "admin.users.edit": "Edit User", - "admin.users.email": "Email", - "admin.users.emailHint": "Email address of the user.", - "admin.users.emailInvalid": "Email address is invalid.", - "admin.users.emailMissing": "Email address is missing.", - "admin.users.extendedMetadata": "Extended Metadata", - "admin.users.groupAlreadyAssigned": "User is already assigned to this group.", - "admin.users.groupAssign": "Assign", - "admin.users.groupAssignNotice": "Note that you cannot assign users to the Administrators or Guests groups from this panel.", - "admin.users.groupSelected": "Assign to {group}", - "admin.users.groups": "Groups", - "admin.users.groupsMissing": "You must assign the user to at least 1 group.", - "admin.users.groupsSelected": "Assign to {count} groups", - "admin.users.id": "ID", - "admin.users.inactive": "Inactive", - "admin.users.info": "User Info", - "admin.users.invalidJSON": "Invalid JSON", - "admin.users.jobTitle": "Job Title", - "admin.users.jobTitleHint": "The job title of the user.", - "admin.users.joined": "Joined", - "admin.users.lastLoginAt": "Last login {date}", - "admin.users.lastUpdated": "Last Updated", - "admin.users.linkedAccounts": "Linked Accounts", - "admin.users.linkedProviders": "Linked Providers", - "admin.users.loading": "Loading User...", - "admin.users.location": "Location", - "admin.users.locationHint": "The city / country of the user or the office location.", - "admin.users.metadata": "Metadata", - "admin.users.minimumGroupRequired": "Cannot unassign because user must be assigned to at least 1 group.", - "admin.users.mustChangePwd": "Must Change Password", - "admin.users.mustChangePwdHint": "User will be prompted to choose a new password upon login.", - "admin.users.name": "Display Name", - "admin.users.nameHint": "Usually the full name or nickname of the user.", - "admin.users.nameInvalidChars": "Name has invalid characters.", - "admin.users.nameMissing": "Name is missing.", - "admin.users.newPassword": "New Password", - "admin.users.noGroupAssigned": "This user is not assigned to any group yet. You must assign at least 1 group to a user.", - "admin.users.noGroupSelected": "You must select a group first.", - "admin.users.noLinkedProviders": "This user isn't linked to any authentication providers.", - "admin.users.noteHint": "Notes are not shown to the user and can only be edited here.", - "admin.users.notes": "Notes", - "admin.users.operations": "Operations", - "admin.users.overview": "Overview", - "admin.users.passAuth": "Password Authentication", - "admin.users.password": "Password", - "admin.users.passwordMissing": "Password is missing.", - "admin.users.passwordTooShort": "Password is too short.", - "admin.users.preferences": "User Preferences", - "admin.users.profile": "User Profile", - "admin.users.pronouns": "Pronouns", - "admin.users.pronounsHint": "The pronouns used to address this user.", - "admin.users.pwdAuthActive": "Can Use Password Authentication", - "admin.users.pwdAuthActiveHint": "Whether the user can login using the password authentication.", - "admin.users.pwdAuthRestrict": "Restrict Password Authentication", - "admin.users.pwdAuthRestrictHint": "Prevent the user from using password authentication for login.", - "admin.users.pwdNotSet": "Password Not Set", - "admin.users.pwdSet": "Password is set", - "admin.users.pwdStrengthGood": "Good", - "admin.users.pwdStrengthMedium": "Medium", - "admin.users.pwdStrengthPoor": "Poor", - "admin.users.pwdStrengthStrong": "Strong", - "admin.users.pwdStrengthWeak": "Weak", - "admin.users.refreshSuccess": "Users refreshed successfully.", - "admin.users.saveSuccess": "User saved successfully.", - "admin.users.selectGroup": "Select Group...", - "admin.users.sendWelcomeEmail": "Send Welcome Email", - "admin.users.sendWelcomeEmailAltHint": "An email will be sent to the user with link(s) to the wiki(s) the user has read access to.", - "admin.users.sendWelcomeEmailFromSiteId": "Site to use for the Welcome Email", - "admin.users.sendWelcomeEmailHint": "An email will be sent to the user with his login details.", - "admin.users.subtitle": "Manage Users", - "admin.users.tfa": "Two Factor Authentication (2FA)", - "admin.users.tfaInvalidate": "Invalidate 2FA", - "admin.users.tfaInvalidateConfirm": "Are you sure you want to invalidate the user current 2FA configuration? This action cannot be undone.", - "admin.users.tfaInvalidateHint": "Force the user to setup 2FA again. Any active configuration will no longer work.", - "admin.users.tfaInvalidateSuccess": "User TFA configuration has been invalidated.", - "admin.users.tfaNotSet": "2FA is awaiting setup", - "admin.users.tfaRequired": "Require 2FA", - "admin.users.tfaRequiredHint": "User will be forced to use 2FA during the next login. This setting will have no effect if 2FA is already enforced by the login provider.", - "admin.users.tfaSet": "2FA configured", - "admin.users.timeFormat": "Time Format", - "admin.users.timeFormatHint": "How time should be formatted when displayed to the user.", - "admin.users.timezone": "Timezone", - "admin.users.timezoneHint": "Used to adjust date and time displayed to the user.", - "admin.users.title": "Users", - "admin.users.toggle2FA": "Toggle 2FA", - "admin.users.unassignGroup": "Unassign from Group", - "admin.users.unban": "Unban User", - "admin.users.unbanHint": "Allow the user to sign in.", - "admin.users.unverified": "Unverified", - "admin.users.unverify": "Unverify User", - "admin.users.unverifyHint": "Set the user as unverified (state where the email has not been validated).", - "admin.users.updateUser": "Update User", - "admin.users.userActivateSuccess": "User has been activated successfully.", - "admin.users.userAlreadyAssignedToGroup": "User is already assigned to this group!", - "admin.users.userDeactivateSuccess": "User deactivated successfully.", - "admin.users.userTFADisableSuccess": "2FA was disabled successfully.", - "admin.users.userTFAEnableSuccess": "2FA was enabled successfully.", - "admin.users.userUpdateSuccess": "User updated successfully.", - "admin.users.userVerifySuccess": "User has been verified successfully.", - "admin.users.verified": "Verified", - "admin.users.verify": "Verify User", - "admin.users.verifyHint": "Set the user as verified (state where the email has been validated).", - "admin.utilities.authSubtitle": "Various tools for authentication / users", - "admin.utilities.authTitle": "Authentication", - "admin.utilities.cacheSubtitle": "Flush cache of various components", - "admin.utilities.cacheTitle": "Flush Cache", - "admin.utilities.contentSubtitle": "Various tools for pages", - "admin.utilities.contentTitle": "Content", - "admin.utilities.disconnectWS": "Disconnect WebSocket Sessions", - "admin.utilities.disconnectWSHint": "Force all active websocket connections to be closed.", - "admin.utilities.disconnectWSSuccess": "All active websocket connections have been terminated.", - "admin.utilities.export": "Export", - "admin.utilities.exportHint": "Export content to tarball for backup / migration.", - "admin.utilities.flushCache": "Flush Cache", - "admin.utilities.flushCacheHint": "Pages and Assets are cached to disk for better performance. You can flush the cache to force all content to be fetched from the DB again.", - "admin.utilities.graphEndpointSubtitle": "Change the GraphQL endpoint for Wiki.js", - "admin.utilities.graphEndpointTitle": "GraphQL Endpoint", - "admin.utilities.import": "Import", - "admin.utilities.importHint": "Import content from a tarball backup or a 2.X backup.", - "admin.utilities.importv1Subtitle": "Migrate data from a previous 1.x installation", - "admin.utilities.importv1Title": "Import from Wiki.js 1.x", - "admin.utilities.invalidAuthCertificates": "Invalidate Authentication Certificates", - "admin.utilities.invalidAuthCertificatesHint": "Regenerate the public and private keys used for authentication. This will instantly log everyone out.", - "admin.utilities.purgeHistory": "Purge History", - "admin.utilities.purgeHistoryHint": "Delete history (content versioning) older than the selected timeframe.", - "admin.utilities.purgeHistoryTimeframe": "Delete older than...", - "admin.utilities.scanPageProblems": "Scan for Page Problems", - "admin.utilities.scanPageProblemsHint": "Scan all pages for invalid, missing or corrupted data.", - "admin.utilities.subtitle": "Maintenance and miscellaneous tools", - "admin.utilities.telemetrySubtitle": "Enable/Disable telemetry or reset the client ID", - "admin.utilities.telemetryTitle": "Telemetry", - "admin.utilities.title": "Utilities", - "admin.utilities.tools": "Tools", - "admin.utitilies.purgeHistoryMonth": "1 Month | {count} Months", - "admin.utitilies.purgeHistoryToday": "Today", - "admin.utitilies.purgeHistoryYear": "1 Year | {count} Years", - "admin.webhooks.acceptUntrusted": "Accept untrusted SSL certificates", - "admin.webhooks.acceptUntrustedHint": "It is recommended that you leave this off for proper security.", - "admin.webhooks.authHeader": "Authentication Header", - "admin.webhooks.authHeaderHint": "(Optional) The value of the Authorization header to send along the request.", - "admin.webhooks.createInvalidData": "The webhook has some invalid or missing data.", - "admin.webhooks.createSuccess": "Webhook created successfully!", - "admin.webhooks.delete": "Delete Webhook", - "admin.webhooks.deleteConfirm": "Are you sure you want to delete webhook {name}?", - "admin.webhooks.deleteConfirmWarn": "This action cannot be undone!", - "admin.webhooks.deleteSuccess": "Webhook deleted successfully.", - "admin.webhooks.edit": "Edit Webhook", - "admin.webhooks.eventCreatePage": "Create a new page", - "admin.webhooks.eventDeleteAsset": "Delete an asset", - "admin.webhooks.eventDeleteComment": "Delete a comment", - "admin.webhooks.eventDeletePage": "Delete a page", - "admin.webhooks.eventEditAsset": "Edit an existing asset", - "admin.webhooks.eventEditComment": "Edit an existing comment", - "admin.webhooks.eventEditPage": "Update an existing page", - "admin.webhooks.eventNewComment": "Post a new comment", - "admin.webhooks.eventRenameAsset": "Rename / move an asset", - "admin.webhooks.eventRenamePage": "Rename / move a page", - "admin.webhooks.eventUploadAsset": "Upload a new asset", - "admin.webhooks.eventUserJoin": "Create / register a new user", - "admin.webhooks.eventUserLogin": "User logins", - "admin.webhooks.eventUserLogout": "User logouts", - "admin.webhooks.events": "Events", - "admin.webhooks.eventsMissing": "You must select at least 1 event.", - "admin.webhooks.eventsSelected": "No event selected | 1 event selected | {count} events selected", - "admin.webhooks.includeContent": "Include Content", - "admin.webhooks.includeContentHint": "Should the payload include content (e.g. the full page body). Make sure that your remote endpoint can accept large payloads!", - "admin.webhooks.includeMetadata": "Include Metadata", - "admin.webhooks.includeMetadataHint": "Should the payload include metadata such as title, description, author, etc.", - "admin.webhooks.nameInvalidChars": "The name contains invalid characters.", - "admin.webhooks.nameMissing": "A name for this webhook is required.", - "admin.webhooks.new": "New Webhook", - "admin.webhooks.none": "There are no webhooks yet.", - "admin.webhooks.stateError": "Failed", - "admin.webhooks.stateErrorExplain": "The last trigger failed to call the endpoint.", - "admin.webhooks.stateErrorHint": "The last event failed to call your endpoint. Click Edit for more details.", - "admin.webhooks.statePending": "Pending", - "admin.webhooks.statePendingHint": "Waiting for an event to trigger this webhook for the first time.", - "admin.webhooks.stateSuccess": "Healthy", - "admin.webhooks.stateSuccessHint": "The last webhook trigger completed successfully.", - "admin.webhooks.subtitle": "Manage webhooks to external services", - "admin.webhooks.title": "Webhooks", - "admin.webhooks.typeAsset": "asset", - "admin.webhooks.typeComment": "comment", - "admin.webhooks.typePage": "page", - "admin.webhooks.typeUser": "user", - "admin.webhooks.updateSuccess": "Webhook updated successfully.", - "admin.webhooks.url": "URL", - "admin.webhooks.urlHint": "Enter the remote endpoint URL", - "admin.webhooks.urlInvalidChars": "The URL contains invalid characters.", - "admin.webhooks.urlMissing": "The URL is missing or is not valid.", - "auth.actions.login": "Log In", - "auth.actions.register": "Register", - "auth.changePwd.currentPassword": "Current Password", - "auth.changePwd.instructions": "You must choose a new password:", - "auth.changePwd.loading": "Changing password...", - "auth.changePwd.newPassword": "New Password", - "auth.changePwd.newPasswordVerify": "Verify New Password", - "auth.changePwd.proceed": "Change Password", - "auth.changePwd.subtitle": "Choose a new password", - "auth.changePwd.success": "Password updated successfully.", - "auth.enterCredentials": "Enter your credentials", - "auth.errors.fields": "One or more fields are invalid.", - "auth.errors.forgotPassword": "Missing or invalid email address.", - "auth.errors.invalidEmail": "Email is invalid.", - "auth.errors.invalidLogin": "Invalid Login", - "auth.errors.invalidLoginMsg": "The email or password is invalid.", - "auth.errors.invalidName": "Name is invalid.", - "auth.errors.invalidUserEmail": "Invalid User Email", - "auth.errors.login": "Missing or invalid login fields.", - "auth.errors.loginError": "Login error", - "auth.errors.missingEmail": "Email is missing.", - "auth.errors.missingName": "Name is missing.", - "auth.errors.missingPassword": "Password is missing.", - "auth.errors.missingUsername": "Username is missing.", - "auth.errors.missingVerifyPassword": "Password Verification is missing.", - "auth.errors.notYetAuthorized": "You have not been authorized to login to this site yet.", - "auth.errors.passwordTooShort": "Password is too short.", - "auth.errors.passwordsNotMatch": "Passwords do not match.", - "auth.errors.register": "One or more fields are invalid.", - "auth.errors.tfaMissing": "Missing or incomplete security code.", - "auth.errors.tooManyAttempts": "Too many attempts!", - "auth.errors.tooManyAttemptsMsg": "You've made too many failed attempts in a short period of time, please try again {time}.", - "auth.errors.userNotFound": "User not found", - "auth.fields.email": "Email Address", - "auth.fields.emailUser": "Email / Username", - "auth.fields.name": "Name", - "auth.fields.password": "Password", - "auth.fields.username": "Username", - "auth.fields.verifyPassword": "Verify Password", - "auth.forgotPasswordCancel": "Cancel", - "auth.forgotPasswordLink": "Forgot Password", - "auth.forgotPasswordLoading": "Requesting password reset...", - "auth.forgotPasswordSubtitle": "Enter your email address to receive the instructions to reset your password:", - "auth.forgotPasswordSuccess": "Check your emails for password reset instructions!", - "auth.forgotPasswordTitle": "Forgot your password", - "auth.genericError": "Authentication is unavailable.", - "auth.invalidEmail": "Email address is invalid.", - "auth.invalidEmailUsername": "Enter a valid email / username.", - "auth.invalidPassword": "Enter a valid password.", - "auth.login.title": "Login", - "auth.loginRequired": "Login required", - "auth.loginSuccess": "Login Successful! Redirecting...", - "auth.loginUsingStrategy": "Login using {strategy}", - "auth.logoutSuccess": "You've been logged out successfully.", - "auth.missingEmail": "Missing email address.", - "auth.missingName": "Name is missing.", - "auth.missingPassword": "Missing password.", - "auth.nameTooLong": "Name is too long.", - "auth.nameTooShort": "Name is too short.", - "auth.orLoginUsingStrategy": "or login using...", - "auth.passkeys.signin": "Log In with a Passkey", - "auth.passkeys.signinHint": "Enter your email address to login with a passkey:", - "auth.passwordNotMatch": "Both passwords do not match.", - "auth.passwordTooShort": "Password is too short.", - "auth.pleaseWait": "Please wait", - "auth.registerCheckEmail": "Check your emails to activate your account.", - "auth.registerSubTitle": "Fill-in the form below to create an account.", - "auth.registerSuccess": "Account created successfully!", - "auth.registerTitle": "Create an account", - "auth.registering": "Creating account...", - "auth.selectAuthProvider": "Sign in with", - "auth.sendResetPassword": "Reset Password", - "auth.signingIn": "Signing In...", - "auth.switchToLogin.link": "Back to Login", - "auth.switchToRegister.link": "Create an Account", - "auth.tfa.subtitle": "Security code required:", - "auth.tfa.verifyToken": "Verify", - "auth.tfaFormTitle": "Enter the security code generated from your trusted device:", - "auth.tfaSetupInstrFirst": "Scan the QR code below from your mobile 2FA application:", - "auth.tfaSetupInstrSecond": "Enter the security code generated from your trusted device:", - "auth.tfaSetupSuccess": "2FA enabled successfully on your account.", - "auth.tfaSetupTitle": "Your administrator has required Two-Factor Authentication (2FA) to be enabled on your account.", - "auth.tfaSetupVerifying": "Verifying...", - "common.actions.activate": "Activate", - "common.actions.add": "Add", - "common.actions.apply": "Apply", - "common.actions.browse": "Browse...", - "common.actions.cancel": "Cancel", - "common.actions.clear": "Clear", - "common.actions.close": "Close", - "common.actions.commit": "Commit", - "common.actions.confirm": "Confirm", - "common.actions.copy": "Copy", - "common.actions.copyURL": "Copy URL", - "common.actions.create": "Create", - "common.actions.deactivate": "Deactivate", - "common.actions.delete": "Delete", - "common.actions.discard": "Discard", - "common.actions.discardChanges": "Discard Changes", - "common.actions.download": "Download", - "common.actions.duplicate": "Duplicate", - "common.actions.edit": "Edit", - "common.actions.exit": "Exit", - "common.actions.fetch": "Fetch", - "common.actions.filter": "Filter", - "common.actions.generate": "Generate", - "common.actions.goback": "Go Back", - "common.actions.howItWorks": "How it works", - "common.actions.insert": "Insert", - "common.actions.login": "Login", - "common.actions.manage": "Manage", - "common.actions.move": "Move", - "common.actions.moveTo": "Move To", - "common.actions.new": "New", - "common.actions.newFolder": "New Folder", - "common.actions.newPage": "New Page", - "common.actions.ok": "OK", - "common.actions.optimize": "Optimize", - "common.actions.page": "Page", - "common.actions.preview": "Preview", - "common.actions.proceed": "Proceed", - "common.actions.properties": "Properties", - "common.actions.refresh": "Refresh", - "common.actions.rename": "Rename", - "common.actions.rerender": "Rerender", - "common.actions.returnToTop": "Return to top", - "common.actions.save": "Save", - "common.actions.saveAndClose": "Save and Close", - "common.actions.saveChanges": "Save Changes", - "common.actions.select": "Select", - "common.actions.update": "Update", - "common.actions.upload": "Upload", - "common.actions.view": "View", - "common.actions.viewDocs": "View Documentation", - "common.clipboard.failure": "Failed to copy to clipboard.", - "common.clipboard.success": "Copied to clipboard successfully.", - "common.clipboard.uuid": "Copy UUID to clipboard.", - "common.clipboard.uuidFailure": "Failed to copy UUID to clipboard.", - "common.clipboard.uuidSuccess": "Copied UUID to clipboard successfully.", - "common.comments.beFirst": "Be the first to comment.", - "common.comments.contentMissingError": "Comment is empty or too short!", - "common.comments.deleteConfirmTitle": "Confirm Delete", - "common.comments.deletePermanentWarn": "This action cannot be undone!", - "common.comments.deleteSuccess": "Comment was deleted successfully.", - "common.comments.deleteWarn": "Are you sure you want to permanently delete this comment?", - "common.comments.fieldContent": "Comment Content", - "common.comments.fieldEmail": "Your Email Address", - "common.comments.fieldName": "Your Name", - "common.comments.loading": "Loading comments...", - "common.comments.markdownFormat": "Markdown Format", - "common.comments.modified": "modified {reldate}", - "common.comments.newComment": "New Comment", - "common.comments.newPlaceholder": "Write a new comment...", - "common.comments.none": "No comments yet.", - "common.comments.postComment": "Post Comment", - "common.comments.postSuccess": "New comment posted successfully.", - "common.comments.postingAs": "Posting as {name}", - "common.comments.sdTitle": "Talk", - "common.comments.title": "Comments", - "common.comments.updateComment": "Update Comment", - "common.comments.updateSuccess": "Comment was updated successfully.", - "common.comments.viewDiscussion": "View Discussion", - "common.datetime": "{date} 'at' {time}", - "common.duration.days": "Day(s)", - "common.duration.every": "Every", - "common.duration.hours": "Hour(s)", - "common.duration.minutes": "Minute(s)", - "common.duration.months": "Month(s)", - "common.duration.years": "Year(s)", - "common.error.generic.hint": "Oops, something went wrong...", - "common.error.generic.title": "Unexpected Error", - "common.error.notfound.hint": "That page doesn't exist or is not available.", - "common.error.notfound.title": "Not Found", - "common.error.title": "Error", - "common.error.unauthorized.hint": "You don't have the required permissions to access this page.", - "common.error.unauthorized.title": "Unauthorized", - "common.error.unexpected": "An unexpected error occurred.", - "common.error.unknownsite.hint": "There's no wiki site at this host.", - "common.error.unknownsite.title": "Unknown Site", - "common.field.createdOn": "Created On", - "common.field.id": "ID", - "common.field.lastUpdated": "Last Updated", - "common.field.name": "Name", - "common.field.task": "Task", - "common.field.title": "Title", - "common.footerCopyright": "© {year} {company}. All rights reserved.", - "common.footerGeneric": "Powered by {link}, an open source project.", - "common.footerLicense": "Content is available under the {license}, by {company}.", - "common.footerPoweredBy": "Powered by {link}", - "common.header.account": "Account", - "common.header.admin": "Administration", - "common.header.assets": "Assets", - "common.header.browseTags": "Browse by Tags", - "common.header.currentPage": "Current Page", - "common.header.delete": "Delete", - "common.header.duplicate": "Duplicate", - "common.header.edit": "Edit", - "common.header.history": "History", - "common.header.home": "Home", - "common.header.imagesFiles": "Images & Files", - "common.header.language": "Language", - "common.header.login": "Login", - "common.header.logout": "Logout", - "common.header.move": "Move / Rename", - "common.header.myWiki": "My Wiki", - "common.header.newPage": "New Page", - "common.header.pageActions": "Page Actions", - "common.header.profile": "Profile", - "common.header.search": "Search...", - "common.header.searchClose": "Close", - "common.header.searchCopyLink": "Copy Search Link", - "common.header.searchDidYouMean": "Did you mean...", - "common.header.searchHint": "Type at least 2 characters to start searching...", - "common.header.searchLoading": "Searching...", - "common.header.searchNoResult": "No pages matching your query.", - "common.header.searchResultsCount": "Found {total} results", - "common.header.siteMap": "Site Map", - "common.header.view": "View", - "common.header.viewSource": "View Source", - "common.license.alr": "All Rights Reserved", - "common.license.cc0": "Public Domain", - "common.license.ccby": " Creative Commons Attribution License", - "common.license.ccbync": "Creative Commons Attribution-NonCommercial License", - "common.license.ccbyncnd": "Creative Commons Attribution-NonCommercial-NoDerivs License", - "common.license.ccbyncsa": "Creative Commons Attribution-NonCommercial-ShareAlike License", - "common.license.ccbynd": "Creative Commons Attribution-NoDerivs License", - "common.license.ccbysa": "Creative Commons Attribution-ShareAlike License", - "common.license.none": "None", - "common.loading": "Loading...", - "common.modernBrowser": "modern browser", - "common.newpage.create": "Create Page", - "common.newpage.goback": "Go back", - "common.newpage.subtitle": "Would you like to create it now?", - "common.newpage.title": "This page does not exist yet.", - "common.notfound.gohome": "Home", - "common.notfound.subtitle": "This page does not exist.", - "common.notfound.title": "Not Found", - "common.outdatedBrowserWarning": "Your browser is outdated. Upgrade to a {modernBrowser}.", - "common.page.bookmark": "Bookmark", - "common.page.delete": "Delete Page", - "common.page.deleteSubtitle": "The page can be restored from the administration area.", - "common.page.deleteTitle": "Are you sure you want to delete page {title}?", - "common.page.editPage": "Edit Page", - "common.page.global": "Global", - "common.page.id": "ID {id}", - "common.page.lastEditedBy": "Last edited by", - "common.page.loading": "Loading Page...", - "common.page.printFormat": "Print Format", - "common.page.private": "Private", - "common.page.published": "Published", - "common.page.returnNormalView": "Return to Normal View", - "common.page.share": "Share", - "common.page.tags": "Tags", - "common.page.tagsMatching": "Pages matching tags", - "common.page.toc": "Table of Contents", - "common.page.unpublished": "Unpublished", - "common.page.unpublishedWarning": "This page is not published.", - "common.page.versionId": "Version ID {id}", - "common.page.viewingSource": "Viewing source of page {path}", - "common.page.viewingSourceVersion": "Viewing source as of {date} of page {path}", - "common.pageSelector.createTitle": "Select New Page Location", - "common.pageSelector.folderEmptyWarning": "This folder is empty.", - "common.pageSelector.moveTitle": "Move / Rename Page Location", - "common.pageSelector.pages": "Pages", - "common.pageSelector.selectTitle": "Select a Page", - "common.pageSelector.virtualFolders": "Virtual Folders", - "common.password.average": "Average", - "common.password.good": "Good", - "common.password.poor": "Poor", - "common.password.strong": "Strong", - "common.password.weak": "Weak", - "common.sidebar.browse": "Browse", - "common.sidebar.currentDirectory": "Current Directory", - "common.sidebar.mainMenu": "Main Menu", - "common.sidebar.root": "(root)", - "common.unauthorized.action.create": "You cannot create the page.", - "common.unauthorized.action.download": "You cannot download the page content.", - "common.unauthorized.action.downloadVersion": "You cannot download the content for this page version.", - "common.unauthorized.action.edit": "You cannot edit the page.", - "common.unauthorized.action.history": "You cannot view the page history.", - "common.unauthorized.action.source": "You cannot view the page source.", - "common.unauthorized.action.sourceVersion": "You cannot view the source of this version of the page.", - "common.unauthorized.action.view": "You cannot view this page.", - "common.unauthorized.goback": "Go Back", - "common.unauthorized.login": "Login As...", - "common.unauthorized.title": "Unauthorized", - "common.user.search": "Search User", - "common.user.searchPlaceholder": "Search Users...", - "common.welcome.createhome": "Create Home Page", - "common.welcome.subtitle": "Let's get started and create the home page.", - "common.welcome.title": "Welcome to your wiki!", - "editor.assets.deleteAsset": "Delete Asset", - "editor.assets.deleteAssetConfirm": "Are you sure you want to delete asset", - "editor.assets.deleteAssetWarn": "This action cannot be undone!", - "editor.assets.deleteSuccess": "Asset deleted successfully.", - "editor.assets.fetchImage": "Fetch Remote Image", - "editor.assets.fileCount": "{count} files", - "editor.assets.folderCreateSuccess": "Asset folder created successfully.", - "editor.assets.folderEmpty": "This asset folder is empty.", - "editor.assets.folderName": "Folder Name", - "editor.assets.folderNameNamingRules": "Must follow the asset folder {namingRules}.", - "editor.assets.folderNameNamingRulesLink": "naming rules", - "editor.assets.headerActions": "Actions", - "editor.assets.headerAdded": "Added", - "editor.assets.headerFileSize": "File Size", - "editor.assets.headerFilename": "Filename", - "editor.assets.headerId": "ID", - "editor.assets.headerType": "Type", - "editor.assets.imageAlign": "Image Alignment", - "editor.assets.newFolder": "New Folder", - "editor.assets.noUploadError": "You must choose a file to upload first!", - "editor.assets.refreshSuccess": "List of assets refreshed successfully.", - "editor.assets.renameAsset": "Rename Asset", - "editor.assets.renameAssetSubtitle": "Enter the new name for this asset:", - "editor.assets.renameSuccess": "Asset renamed successfully.", - "editor.assets.title": "Assets", - "editor.assets.uploadAssets": "Upload Assets", - "editor.assets.uploadAssetsDropZone": "Browse or Drop files here...", - "editor.assets.uploadFailed": "File upload failed.", - "editor.backToEditor": "Back to Editor", - "editor.ckeditor.stats": "{chars} chars, {words} words", - "editor.conflict.editable": "(editable)", - "editor.conflict.infoGeneric": "A more recent version of this page was saved by {authorName}, {date}", - "editor.conflict.leftPanelInfo": "Your current edit, based on page version from {date}", - "editor.conflict.localVersion": "Local Version {refEditable}", - "editor.conflict.overwrite.description": "Are you sure you want to replace your current version with the latest remote content? {refEditsLost}", - "editor.conflict.overwrite.editsLost": "Your current edits will be lost.", - "editor.conflict.overwrite.title": "Overwrite with Remote Version?", - "editor.conflict.pageDescription": "Description:", - "editor.conflict.pageTitle": "Title:", - "editor.conflict.readonly": "(read-only)", - "editor.conflict.remoteVersion": "Remote Version {refReadOnly}", - "editor.conflict.rightPanelInfo": "Last edited by {authorName}, {date}", - "editor.conflict.title": "Resolve Save Conflict", - "editor.conflict.useLocal": "Use Local", - "editor.conflict.useLocalHint": "Use content in the left panel", - "editor.conflict.useRemote": "Use Remote", - "editor.conflict.useRemoteHint": "Discard local changes and use latest version", - "editor.conflict.viewLatestVersion": "View Latest Version", - "editor.conflict.warning": "Save conflict! Another user has already modified this page.", - "editor.conflict.whatToDo": "What do you want to do?", - "editor.conflict.whatToDoLocal": "Use your current local version and ignore the latest changes.", - "editor.conflict.whatToDoRemote": "Use the remote version (latest) and discard your changes.", - "editor.createPage": "Create Page", - "editor.markup.admonitionDanger": "Danger / Important Admonition", - "editor.markup.admonitionInfo": "Info / Note Admonition", - "editor.markup.admonitionSuccess": "Tip / Success Admonition", - "editor.markup.admonitionWarning": "Warning Admonition", - "editor.markup.blockquote": "Blockquote", - "editor.markup.blockquoteAdmonitions": "Blockquote / Admonition", - "editor.markup.blockquoteError": "Error Blockquote", - "editor.markup.blockquoteInfo": "Info Blockquote", - "editor.markup.blockquoteSuccess": "Success Blockquote", - "editor.markup.blockquoteWarning": "Warning Blockquote", - "editor.markup.bold": "Bold", - "editor.markup.distractionFreeMode": "Distraction Free Mode", - "editor.markup.header": "Header", - "editor.markup.headerLevel": "Header {level}", - "editor.markup.heading": "Heading {level}", - "editor.markup.inlineCode": "Inline Code", - "editor.markup.insertAssets": "Insert Assets", - "editor.markup.insertBlock": "Insert Block", - "editor.markup.insertCodeBlock": "Insert Code Block", - "editor.markup.insertDiagram": "Insert Diagram", - "editor.markup.insertEmoji": "Insert Emoji", - "editor.markup.insertFootnote": "Insert Footnote", - "editor.markup.insertHorizontalBar": "Insert Horizontal Bar", - "editor.markup.insertLink": "Insert Link", - "editor.markup.insertMathExpression": "Insert Math Expression", - "editor.markup.insertTable": "Insert Table", - "editor.markup.insertTabset": "Insert Tabset", - "editor.markup.insertVideoAudio": "Insert Video / Audio", - "editor.markup.italic": "Italic", - "editor.markup.keyboardKey": "Keyboard Key", - "editor.markup.markdownFormattingHelp": "Markdown Formatting Help", - "editor.markup.noSelectionError": "Text must be selected first!", - "editor.markup.orderedList": "Ordered List", - "editor.markup.strikethrough": "Strikethrough", - "editor.markup.subscript": "Subscript", - "editor.markup.superscript": "Superscript", - "editor.markup.tableHelper": "Table Helper", - "editor.markup.taskList": "Task List", - "editor.markup.taskListChecked": "Checked List Item", - "editor.markup.taskListUnchecked": "Unchecked List Item", - "editor.markup.togglePreviewPane": "Hide / Show Preview Pane", - "editor.markup.toggleSpellcheck": "Toggle Spellcheck", - "editor.markup.unorderedList": "Unordered List", - "editor.page": "Page", - "editor.pageData.data": "Data", - "editor.pageData.dragDropHint": "Drag-n-drop fields from the left onto this area to build your template structure.", - "editor.pageData.duplicateTemplateKeys": "One or more fields have duplicate unique keys!", - "editor.pageData.emptyTemplateStructure": "Template Structure is empty!", - "editor.pageData.fieldTypeBoolean": "Boolean", - "editor.pageData.fieldTypeHeader": "Header", - "editor.pageData.fieldTypeImage": "Image", - "editor.pageData.fieldTypeLink": "Link", - "editor.pageData.fieldTypeNumber": "Number", - "editor.pageData.fieldTypeText": "Text", - "editor.pageData.invalidTemplateKeys": "One or more fields have missing or invalid unique keys!", - "editor.pageData.invalidTemplateLabels": "One or more fields have missing or invalid labels!", - "editor.pageData.invalidTemplateName": "Template name is missing or invalid!", - "editor.pageData.label": "Label", - "editor.pageData.manageTemplates": "Manage Templates", - "editor.pageData.noTemplate": "You don't have any template yet. Create one to get started.", - "editor.pageData.selectTemplateAbove": "Select a template to edit from the dropdown menu above.", - "editor.pageData.template": "Template", - "editor.pageData.templateDeleteConfirmText": "Any page currently using this template will revert to basic template rendering.", - "editor.pageData.templateDeleteConfirmTitle": "Are you sure?", - "editor.pageData.templateFullRowTypes": "Full Row Types", - "editor.pageData.templateKeyValueTypes": "Key-Value Types", - "editor.pageData.templateStructure": "Structure", - "editor.pageData.templateTitle": "Template Title", - "editor.pageData.templateUntitled": "Untitled Template", - "editor.pageData.title": "Page Data", - "editor.pageData.uniqueKey": "Unique Key", - "editor.pageRel.button": "Button Appearance", - "editor.pageRel.caption": "Caption (optional)", - "editor.pageRel.center": "Center", - "editor.pageRel.label": "Label", - "editor.pageRel.left": "Left", - "editor.pageRel.position": "Button Position", - "editor.pageRel.preview": "Preview", - "editor.pageRel.right": "Right", - "editor.pageRel.selectIcon": "Select Icon...", - "editor.pageRel.selectPage": "Select Page...", - "editor.pageRel.target": "Target", - "editor.pageRel.title": "Add Page Relation", - "editor.pageRel.titleEdit": "Edit Page Relation", - "editor.pageScripts.title": "Page Scripts", - "editor.pendingAssetsUploading": "Uploading assets...", - "editor.props.alias": "Alias", - "editor.props.allowComments": "Allow Comments", - "editor.props.allowCommentsHint": "Enable commenting abilities on this page.", - "editor.props.allowContributions": "Allow Contributions", - "editor.props.allowRatings": "Allow Ratings", - "editor.props.allowRatingsHint": "Enable rating capabilities on this page.", - "editor.props.dateRange": "Date Range", - "editor.props.dateRangeHint": "Select the start and end date for this page publication. The page will only be accessible to users with read access within the selected date range.", - "editor.props.draft": "Draft", - "editor.props.draftHint": "Visible to users with write access only.", - "editor.props.icon": "Icon", - "editor.props.info": "Info", - "editor.props.isSearchable": "Include in Search Results", - "editor.props.jsLoad": "Javascript - On Load", - "editor.props.jsLoadHint": "Execute javascript once the page is loaded", - "editor.props.jsUnload": "Javascript - On Unload", - "editor.props.jsUnloadHint": "Execute javascript before the page content is destroyed", - "editor.props.pageProperties": "Page Properties", - "editor.props.password": "Password", - "editor.props.passwordHint": "The page must be published and the user must have read access rights.", - "editor.props.publishState": "Publishing State", - "editor.props.published": "Published", - "editor.props.publishedHint": "Visible to all users with read access.", - "editor.props.relationAdd": "Add Relation...", - "editor.props.relationAddHint": "Add links to other pages in the footer (e.g. as part of a series of articles)", - "editor.props.relations": "Relations", - "editor.props.requirePassword": "Require Password", - "editor.props.scripts": "Scripts", - "editor.props.shortDescription": "Short Description", - "editor.props.showInTree": "Show in Site Navigation", - "editor.props.showSidebar": "Show Sidebar", - "editor.props.showTags": "Show Tags", - "editor.props.showToc": "Show Table of Contents", - "editor.props.sidebar": "Sidebar", - "editor.props.social": "Social", - "editor.props.styles": "CSS Styles", - "editor.props.stylesHint": "CSS Rules to add to the page", - "editor.props.tags": "Tags", - "editor.props.tagsHint": "Use tags to categorize your pages and make them easier to find.", - "editor.props.title": "Title", - "editor.props.tocMinMaxDepth": "Min/Max Depth", - "editor.props.visibility": "Visibility", - "editor.reasonForChange.field": "Reason", - "editor.reasonForChange.optional": "Enter a short description of the reason for this change. This is optional but recommended.", - "editor.reasonForChange.reasonMissing": "A reason is missing.", - "editor.reasonForChange.required": "You must provide a reason for this change. Enter a small description of what changed.", - "editor.reasonForChange.title": "Reason For Change", - "editor.renderPreview": "Render Preview", - "editor.save.createSuccess": "Page created successfully.", - "editor.save.error": "An error occurred while creating the page", - "editor.save.pleaseWait": "Please wait...", - "editor.save.processing": "Rendering", - "editor.save.saved": "Saved", - "editor.save.updateSuccess": "Page updated successfully.", - "editor.saveAndCloseTip": "Ctrl / Cmd + Click to save and close", - "editor.select.cannotChange": "This cannot be changed once the page is created.", - "editor.select.customView": "or create a custom view?", - "editor.select.title": "Which editor do you want to use for this page?", - "editor.settings": "Editor Settings", - "editor.settings.markdown": "Markdown Editor Settings", - "editor.settings.markdownFontSize": "Editor Font Size", - "editor.settings.markdownFontSizeHint": "The font size to use in the editor.", - "editor.settings.markdownPreviewShown": "Display Render Preview", - "editor.settings.markdownPreviewShownHint": "Whether to display a preview of the rendered content.", - "editor.tableEditor.title": "Table Editor", - "editor.togglePreviewPane": "Toggle Preview Pane", - "editor.toggleScrollSync": "Toggle Scroll Sync", - "editor.unsaved.body": "You have unsaved changes. Are you sure you want to leave the editor and discard any modifications you made since the last save?", - "editor.unsaved.title": "Discard Unsaved Changes?", - "editor.unsavedWarning": "You have unsaved edits. Are you sure you want to leave the editor?", - "error.ERR_PK_ALREADY_REGISTERED": "It looks like this authenticator is already registered.", - "error.ERR_PK_HOSTNAME_MISSING": "Your administrator must set a valid site hostname before passkeys can be used.", - "error.ERR_PK_USER_CANCELLED": "Passkey registration aborted. Make sure to remove the key from your device.", - "fileman.7zFileType": "7zip Archive", - "fileman.aacFileType": "AAC Audio File", - "fileman.aiFileType": "Adobe Illustrator Document", - "fileman.aifFileType": "AIF Audio File", - "fileman.apkFileType": "Android Package", - "fileman.assetDelete": "Confirm Delete Asset", - "fileman.assetDeleteConfirm": "Are you sure you want to delete {name}?", - "fileman.assetDeleteId": "Asset ID {id}", - "fileman.assetDeleteSuccess": "Asset deleted successfully.", - "fileman.assetFileName": "Asset Name", - "fileman.assetFileNameHint": "Filename of the asset, including the file extension.", - "fileman.assetRename": "Rename Asset", - "fileman.aviFileType": "AVI Video File", - "fileman.binFileType": "Binary File", - "fileman.bz2FileType": "BZIP2 Archive", - "fileman.copyURLSuccess": "URL has been copied to the clipboard.", - "fileman.createFolderInvalidData": "One or more fields are invalid.", - "fileman.createFolderSuccess": "Folder created successfully.", - "fileman.cssFileType": "Cascade Style Sheet", - "fileman.csvFileType": "Comma Separated Values Document", - "fileman.dataFileType": "Data File", - "fileman.detailsAssetSize": "File Size", - "fileman.detailsAssetType": "Type", - "fileman.detailsPageCreated": "Created", - "fileman.detailsPageEditor": "Editor", - "fileman.detailsPageType": "Type", - "fileman.detailsPageUpdated": "Last Updated", - "fileman.detailsTitle": "Title", - "fileman.dmgFileType": "Apple Disk Image File", - "fileman.docxFileType": "Microsoft Word Document", - "fileman.epsFileType": "EPS Image", - "fileman.exeFileType": "Windows Executable", - "fileman.flacFileType": "FLAC Audio File", - "fileman.folderChildrenCount": "Empty folder | 1 child | {count} children", - "fileman.folderCreate": "New Folder", - "fileman.folderFileName": "Path Name", - "fileman.folderFileNameHint": "URL friendly version of the folder name. Must consist of lowercase alphanumerical or hypen characters only.", - "fileman.folderFileNameInvalid": "Invalid Characters in Folder Path Name. Lowercase alphanumerical and hyphen characters only.", - "fileman.folderFileNameMissing": "Missing Folder Path Name", - "fileman.folderRename": "Rename Folder", - "fileman.folderTitle": "Title", - "fileman.folderTitleInvalidChars": "Invalid Characters in Folder Name", - "fileman.folderTitleMissing": "Missing Folder Title", - "fileman.gifFileType": "Animated GIF Image", - "fileman.gzFileType": "GZipped Archive", - "fileman.heicFileType": "HEIC Image", - "fileman.icoFileType": "Icon File", - "fileman.icsFileType": "ICS Calendar Event", - "fileman.isoFileType": "Optical Disk Image File", - "fileman.jpegFileType": "JPEG Image", - "fileman.jpgFileType": "JPEG Image", - "fileman.jsonFileType": "JSON Document", - "fileman.m4aFileType": "M4A Audio File", - "fileman.markdownPageType": "Markdown Page", - "fileman.midFileType": "MIDI Audio File", - "fileman.movFileType": "QuickTime Video File", - "fileman.mp3FileType": "MP3 Audio File", - "fileman.mp4FileType": "MP4 Video File", - "fileman.mpegFileType": "MPEG Video File", - "fileman.mpgFileType": "MPEG Video File", - "fileman.oggFileType": "OGG Audio File", - "fileman.otfFileType": "OpenType Font File", - "fileman.pdfFileType": "PDF Document", - "fileman.pngFileType": "PNG Image", - "fileman.pptxFileType": "Microsoft Powerpoint Presentation", - "fileman.psdFileType": "Adobe Photoshop Document", - "fileman.rarFileType": "RAR Archive", - "fileman.renameAssetInvalid": "Asset name is invalid.", - "fileman.renameAssetSuccess": "Asset renamed successfully", - "fileman.renameFolderInvalidData": "One or more fields are invalid.", - "fileman.renameFolderSuccess": "Folder renamed successfully.", - "fileman.searchFolder": "Search folder...", - "fileman.svgFileType": "Scalable Vector Graphic", - "fileman.tarFileType": "TAR Archive", - "fileman.tgzFileType": "Gzipped TAR Archive", - "fileman.tifFileType": "TIFF Image", - "fileman.title": "File Manager", - "fileman.ttfFileType": "TrueType Font File", - "fileman.txtFileType": "Text Document", - "fileman.unknownFileType": "{type} file", - "fileman.uploadSuccess": "File(s) uploaded successfully.", - "fileman.viewOptions": "View Options", - "fileman.wavFileType": "WAV Audio File", - "fileman.wmaFileType": "WMA Audio File", - "fileman.wmvFileType": "WMV Video File", - "fileman.woff2FileType": "Web Open Font File", - "fileman.woffFileType": "Web Open Font File", - "fileman.xlstFileType": "Microsoft Excel Document", - "fileman.xmlFileType": "XML Document", - "fileman.xzFileType": "XZ Archive", - "fileman.zipFileType": "ZIP Archive", - "folderDeleteDialog.confirm": "Are you sure you want to delete folder {name} and all its content?", - "folderDeleteDialog.deleteSuccess": "Folder has been deleted successfully.", - "folderDeleteDialog.folderId": "Folder ID {id}", - "folderDeleteDialog.title": "Confirm Delete Folder", - "history.restore.confirmButton": "Restore", - "history.restore.confirmText": "Are you sure you want to restore this page content as it was on {date}? This version will be copied on top of the current history. As such, newer versions will still be preserved.", - "history.restore.confirmTitle": "Restore page version?", - "history.restore.success": "Page version restored succesfully!", - "navEdit.clearItems": "Clear All Items", - "navEdit.editMenuItems": "Edit Menu Items", - "navEdit.emptyMenuText": "Click the Add button to add your first menu item.", - "navEdit.header": "Header", - "navEdit.icon": "Icon", - "navEdit.iconHint": "Icon to display to the left of the menu item.", - "navEdit.label": "Label", - "navEdit.labelHint": "Text to display on the menu item.", - "navEdit.link": "Link", - "navEdit.nestItem": "Nest Item", - "navEdit.nestingWarn": "The previous menu item must be a normal link or another nested link. Invalid nested items will be shown in red.", - "navEdit.noSelection": "Select a menu item from the left to start editing.", - "navEdit.openInNewWindow": "Open in New Window", - "navEdit.openInNewWindowHint": "Whether the link should open in a new window / tab.", - "navEdit.saveModeSuccess": "Navigation mode set successfully.", - "navEdit.saveSuccess": "Menu items saved successfully.", - "navEdit.selectGroups": "Group(s):", - "navEdit.separator": "Separator", - "navEdit.target": "Target", - "navEdit.targetHint": "Target path or external link to point to.", - "navEdit.title": "Edit Navigation", - "navEdit.unnestItem": "Unnest Item", - "navEdit.visibility": "Visibility", - "navEdit.visibilityAll": "Everyone", - "navEdit.visibilityHint": "Whether to show the menu item to everyone or just selected groups.", - "navEdit.visibilityLimited": "Selected Groups", - "pageDeleteDialog.confirm": "Are you sure you want to delete the page {name}?", - "pageDeleteDialog.deleteSuccess": "Page deleted successfully.", - "pageDeleteDialog.pageId": "Page ID {id}", - "pageDeleteDialog.title": "Confirm Page Deletion", - "pageDuplicateDialog.title": "Duplicate and Save As...", - "pageRenameDialog.title": "Rename / Move to...", - "pageSaveDialog.displayModePath": "Browse Using Paths", - "pageSaveDialog.displayModeTitle": "Browse Using Titles", - "pageSaveDialog.title": "Save As...", - "profile.accessibility": "Accessibility", - "profile.activity": "Activity", - "profile.appearance": "Site Appearance", - "profile.appearanceDark": "Dark", - "profile.appearanceDefault": "Site Default", - "profile.appearanceHint": "Use the light or dark theme.", - "profile.appearanceLight": "Light", - "profile.auth": "Authentication", - "profile.authChangePassword": "Change Password", - "profile.authDisableTfa": "Turn Off 2FA", - "profile.authDisableTfaConfirm": "Are you sure you want to disable Two Factor Authentication?", - "profile.authDisableTfaFailed": "Failed to turn off 2FA.", - "profile.authDisableTfaSuccess": "2FA turned off successfully.", - "profile.authInfo": "Your account is associated with the following authentication methods:", - "profile.authLoadingFailed": "Failed to load authentication methods.", - "profile.authModifyTfa": "Modify 2FA", - "profile.authSetTfa": "Set 2FA", - "profile.authSetTfaLoading": "Setting up 2FA... Please wait", - "profile.avatar": "Avatar", - "profile.avatarClearFailed": "Failed to clear profile picture.", - "profile.avatarClearSuccess": "Profile picture cleared successfully.", - "profile.avatarUploadDisabled": "Your avatar is set by your organization and cannot be changed.", - "profile.avatarUploadFailed": "Failed to upload user profile picture.", - "profile.avatarUploadHint": "For best results, use a 180x180 image of type JPG or PNG.", - "profile.avatarUploadSuccess": "Profile picture uploaded successfully.", - "profile.avatarUploadTitle": "Upload your user profile picture.", - "profile.cvd": "Color Vision Deficiency", - "profile.cvdDeuteranopia": "Deuteranopia", - "profile.cvdHint": "Alter the color scheme of certain UI elements to account for certain color vision dificiencies.", - "profile.cvdNone": "None", - "profile.cvdProtanopia": "Protanopia", - "profile.cvdTritanopia": "Tritanopia", - "profile.darkMode": "Dark Mode", - "profile.darkModeHint": "Change the appareance of the site to a dark theme.", - "profile.dateFormat": "Date Format", - "profile.dateFormatHint": "Set your preferred format to display dates.", - "profile.displayName": "Display Name", - "profile.displayNameHint": "Your full name; shown when authoring content (e.g. pages, comments, etc.).", - "profile.editDisabledDescription": "Your wiki administrator has disabled profile editing.", - "profile.editDisabledTitle": "Profile info is managed by your organization.", - "profile.email": "Email Address", - "profile.emailHint": "The email address used for login.", - "profile.groups": "Groups", - "profile.groupsInfo": "You're currently part of the following groups:", - "profile.groupsLoadingFailed": "Failed to load groups.", - "profile.groupsNone": "You're not part of any group.", - "profile.jobTitle": "Job Title", - "profile.jobTitleHint": "Your position in your organization; shown on your profile page.", - "profile.localeDefault": "Locale Default", - "profile.location": "Location", - "profile.locationHint": "Your city and country; shown on your profile page.", - "profile.myInfo": "My Info", - "profile.notifications": "Notifications", - "profile.pages.emptyList": "No pages to display.", - "profile.pages.headerCreatedAt": "Created", - "profile.pages.headerPath": "Path", - "profile.pages.headerTitle": "Title", - "profile.pages.headerUpdatedAt": "Last Updated", - "profile.pages.refreshSuccess": "Page list has been refreshed.", - "profile.pages.subtitle": "List of pages I created or last modified", - "profile.pages.title": "Pages", - "profile.passkeys": "Passkeys", - "profile.passkeysAdd": "Add Passkey", - "profile.passkeysDeactivateConfirm": "Are you sure you want to deactivate this passkey?", - "profile.passkeysDeactivateFailed": "Failed to deactivate the passkey.", - "profile.passkeysDeactivateSuccess": "Passkey deactivated successfully. You may still need to remove the passkey from your device.", - "profile.passkeysIntro": "Passkeys are a replacement for passwords for a faster, easier and more secure login. It relies on your device existing biometrics (phone, computer, security key) to validate your identity.", - "profile.passkeysInvalidName": "Passkey name is missing or invalid.", - "profile.passkeysName": "Passkey Name", - "profile.passkeysNameHint": "Enter a name for your passkey:", - "profile.passkeysSetupFailed": "Failed to setup new passkey.", - "profile.passkeysSetupSuccess": "Passkey registered successfully.", - "profile.passkeysUnsupported": "Passkeys are not supported on your device.", - "profile.preferences": "Preferences", - "profile.pronouns": "Pronouns", - "profile.pronounsHint": "Let people know which pronouns should they use when referring to you.", - "profile.save.success": "Profile saved successfully.", - "profile.saveFailed": "Failed to save profile changes.", - "profile.saveSuccess": "Profile saved successfully.", - "profile.saving": "Saving profile...", - "profile.subtitle": "My personal info", - "profile.timeFormat": "Time Format", - "profile.timeFormat12h": "12 hour", - "profile.timeFormat24h": "24 hour", - "profile.timeFormatHint": "Set your preferred format to display time.", - "profile.timezone": "Timezone", - "profile.timezoneHint": "Set your timezone to display local time correctly.", - "profile.title": "Profile", - "profile.uploadNewAvatar": "Upload New Image", - "profile.viewPublicProfile": "View Public Profile", - "renderPageDialog.loading": "Rendering page...", - "renderPageDialog.success": "Page rerendered successfully.", - "search.editorAny": "Any editor", - "search.emptyQuery": "Enter a query in the search field above and press Enter.", - "search.filterEditor": "Editor", - "search.filterLocale": "Locale(s)", - "search.filterLocaleDisplay": "Any locale | {n} locale only | {count} locales selected", - "search.filterPath": "Path starting with...", - "search.filterPublishState": "Publish State", - "search.filterTags": "Tags", - "search.filters": "Filters", - "search.noResults": "No results found for {0} with the current filters.", - "search.publishStateAny": "Any publish state", - "search.publishStateDraft": "Draft", - "search.publishStatePublished": "Published", - "search.publishStateScheduled": "Scheduled", - "search.results": "Search Results", - "search.sortBy": "Sort By", - "search.sortByLastUpdated": "Last Updated", - "search.sortByRelevance": "Relevance", - "search.sortByTitle": "Title", - "search.totalResults": "No result | {0} result | {0} results", - "tags.clearSelection": "Clear Selection", - "tags.currentSelection": "Current Selection", - "tags.locale": "Locale", - "tags.localeAny": "Any", - "tags.noResults": "Couldn't find any page with the selected tags.", - "tags.noResultsWithFilter": "Couldn't find any page matching the current filtering options.", - "tags.orderBy": "Order By", - "tags.orderByField.ID": "ID", - "tags.orderByField.creationDate": "Creation Date", - "tags.orderByField.lastModified": "Last Modified", - "tags.orderByField.path": "Path", - "tags.orderByField.title": "Title", - "tags.pageLastUpdated": "Last Updated {date}", - "tags.retrievingResultsLoading": "Retrieving page results...", - "tags.searchWithinResultsPlaceholder": "Search within results...", - "tags.selectOneMoreTags": "Select one or more tags", - "tags.selectOneMoreTagsHint": "Select one or more tags on the left.", - "welcome.admin": "Administration Area", - "welcome.createHome": "Create the homepage", - "welcome.homeDefault.content": "Write some content here...", - "welcome.homeDefault.description": "Welcome to my wiki!", - "welcome.homeDefault.title": "Home", - "welcome.subtitle": "Let's get started...", - "welcome.title": "Welcome to Wiki.js!" -} diff --git a/server/locales/metadata.mjs b/server/locales/metadata.mjs deleted file mode 100644 index a3c8cc7c6..000000000 --- a/server/locales/metadata.mjs +++ /dev/null @@ -1,81 +0,0 @@ -const localazyMetadata = { - projectUrl: "https://localazy.com/p/wiki", - baseLocale: "en", - languages: [ - { - language: "de", - region: "", - script: "", - isRtl: false, - name: "German", - localizedName: "Deutsch", - pluralType: (n) => { return (n===1) ? "one" : "other"; } - }, - { - language: "en", - region: "", - script: "", - isRtl: false, - name: "English", - localizedName: "English", - pluralType: (n) => { return (n===1) ? "one" : "other"; } - }, - { - language: "fr", - region: "", - script: "", - isRtl: false, - name: "French", - localizedName: "Français", - pluralType: (n) => { return (n===0 || n===1) ? "one" : "other"; } - }, - { - language: "pt", - region: "BR", - script: "", - isRtl: false, - name: "Brazilian Portuguese", - localizedName: "Português (Brasil)", - pluralType: (n) => { return (n>=0 && n<=1) ? "one" : "other"; } - }, - { - language: "ru", - region: "", - script: "", - isRtl: false, - name: "Russian", - localizedName: "Русский", - pluralType: (n) => { return ((n%10===1) && (n%100!==11)) ? "one" : ((n%10>=2 && n%10<=4) && ((n%100<12 || n%100>14))) ? "few" : "many"; } - }, - { - language: "zh", - region: "", - script: "Hans", - isRtl: false, - name: "Simplified Chinese", - localizedName: "简体中文", - pluralType: (n) => { return "other"; } - } - ], - files: [ - { - cdnHash: "54b977214afbffe2ffeb07d0ccb03558e75e4408", - file: "file.json", - path: "", - library: "", - module: "", - buildType: "", - productFlavors: [], - cdnFiles: { - "de#": "https://delivery.localazy.com/_a7797965569058078203416ae5aa/_e0/54b977214afbffe2ffeb07d0ccb03558e75e4408/de/file.json", - "en#": "https://delivery.localazy.com/_a7797965569058078203416ae5aa/_e0/54b977214afbffe2ffeb07d0ccb03558e75e4408/en/file.json", - "fr#": "https://delivery.localazy.com/_a7797965569058078203416ae5aa/_e0/54b977214afbffe2ffeb07d0ccb03558e75e4408/fr/file.json", - "pt_BR#": "https://delivery.localazy.com/_a7797965569058078203416ae5aa/_e0/54b977214afbffe2ffeb07d0ccb03558e75e4408/pt-BR/file.json", - "ru#": "https://delivery.localazy.com/_a7797965569058078203416ae5aa/_e0/54b977214afbffe2ffeb07d0ccb03558e75e4408/ru/file.json", - "zh#Hans": "https://delivery.localazy.com/_a7797965569058078203416ae5aa/_e0/54b977214afbffe2ffeb07d0ccb03558e75e4408/zh-Hans/file.json" - } - } - ] -}; - -export default localazyMetadata; diff --git a/server/models/analytics.mjs b/server/models/analytics.mjs deleted file mode 100644 index 0e16563a2..000000000 --- a/server/models/analytics.mjs +++ /dev/null @@ -1,102 +0,0 @@ -import { Model } from 'objection' -import fs from 'node:fs/promises' -import path from 'node:path' -import { defaultTo, forOwn, isBoolean, replace, sortBy } from 'lodash-es' -import yaml from 'js-yaml' -import { parseModuleProps } from '../helpers/common.mjs' - -/** - * Analytics model - */ -export class Analytics extends Model { - static get tableName() { return 'analytics' } - - static get jsonSchema () { - return { - type: 'object', - required: ['module', 'isEnabled'], - - properties: { - id: { type: 'string' }, - module: { type: 'string' }, - isEnabled: { type: 'boolean', default: false } - } - } - } - - static get jsonAttributes() { - return ['config'] - } - - static async getProviders(isEnabled) { - const providers = await WIKI.db.analytics.query().where(isBoolean(isEnabled) ? { isEnabled } : {}) - return sortBy(providers, ['module']) - } - - static async refreshProvidersFromDisk() { - try { - // -> Fetch definitions from disk - const analyticsDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/analytics')) - WIKI.data.analytics = [] - for (const dir of analyticsDirs) { - const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/analytics', dir, 'definition.yml'), 'utf8') - const defParsed = yaml.load(def) - defParsed.key = dir - defParsed.props = parseModuleProps(defParsed.props) - WIKI.data.analytics.push(defParsed) - WIKI.logger.debug(`Loaded analytics module definition ${dir}: [ OK ]`) - } - - WIKI.logger.info(`Loaded ${WIKI.data.analytics.length} analytics module definitions: [ OK ]`) - } catch (err) { - WIKI.logger.error(`Failed to scan or load analytics providers: [ FAILED ]`) - WIKI.logger.error(err) - } - } - - static async getCode ({ cache = false } = {}) { - if (cache) { - const analyticsCached = await WIKI.cache.get('analytics') - if (analyticsCached) { - return analyticsCached - } - } - try { - const analyticsCode = { - head: '', - bodyStart: '', - bodyEnd: '' - } - const providers = await WIKI.db.analytics.getProviders(true) - - for (let provider of providers) { - const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/analytics', provider.key, 'code.yml'), 'utf8') - let code = yaml.safeLoad(def) - code.head = defaultTo(code.head, '') - code.bodyStart = defaultTo(code.bodyStart, '') - code.bodyEnd = defaultTo(code.bodyEnd, '') - - forOwn(provider.config, (value, key) => { - code.head = replace(code.head, new RegExp(`{{${key}}}`, 'g'), value) - code.bodyStart = replace(code.bodyStart, `{{${key}}}`, value) - code.bodyEnd = replace(code.bodyEnd, `{{${key}}}`, value) - }) - - analyticsCode.head += code.head - analyticsCode.bodyStart += code.bodyStart - analyticsCode.bodyEnd += code.bodyEnd - } - - await WIKI.cache.set('analytics', analyticsCode, 300) - - return analyticsCode - } catch (err) { - WIKI.logger.warn('Error while getting analytics code: ', err) - return { - head: '', - bodyStart: '', - bodyEnd: '' - } - } - } -} diff --git a/server/models/apiKeys.mjs b/server/models/apiKeys.mjs deleted file mode 100644 index 7893e8406..000000000 --- a/server/models/apiKeys.mjs +++ /dev/null @@ -1,75 +0,0 @@ -/* global WIKI */ - -import { Model } from 'objection' -import { DateTime } from 'luxon' -import ms from 'ms' -import jwt from 'jsonwebtoken' - -/** - * Users model - */ -export class ApiKey extends Model { - static get tableName() { return 'apiKeys' } - - static get jsonSchema () { - return { - type: 'object', - required: ['name', 'key'], - - properties: { - id: {type: 'string'}, - name: {type: 'string'}, - key: {type: 'string'}, - expiration: {type: 'string'}, - isRevoked: {type: 'boolean'}, - createdAt: {type: 'string'}, - validUntil: {type: 'string'} - } - } - } - - async $beforeUpdate(opt, context) { - await super.$beforeUpdate(opt, context) - - this.updatedAt = new Date().toISOString() - } - async $beforeInsert(context) { - await super.$beforeInsert(context) - - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } - - static async createNewKey ({ name, expiration, groups }) { - console.info(DateTime.utc().plus(ms(expiration)).toISO()) - - const entry = await WIKI.db.apiKeys.query().insert({ - name, - key: 'pending', - expiration: DateTime.utc().plus(ms(expiration)).toISO(), - isRevoked: true - }) - - console.info(entry) - - const key = jwt.sign({ - api: entry.id, - grp: groups - }, { - key: WIKI.config.auth.certs.private, - passphrase: WIKI.config.auth.secret - }, { - algorithm: 'RS256', - expiresIn: expiration, - audience: WIKI.config.auth.audience, - issuer: 'urn:wiki.js' - }) - - await WIKI.db.apiKeys.query().findById(entry.id).patch({ - key, - isRevoked: false - }) - - return key - } -} diff --git a/server/models/assets.mjs b/server/models/assets.mjs deleted file mode 100644 index 8b6174d40..000000000 --- a/server/models/assets.mjs +++ /dev/null @@ -1,252 +0,0 @@ -import { Model } from 'objection' -import path from 'node:path' -import fse from 'fs-extra' -import { startsWith } from 'lodash-es' -import { generateHash } from '../helpers/common.mjs' - -import { Tree } from './tree.mjs' -import { User } from './users.mjs' - -/** - * Users model - */ -export class Asset extends Model { - static get tableName () { return 'assets' } - - static get jsonSchema () { - return { - type: 'object', - - properties: { - id: { type: 'string' }, - filename: { type: 'string' }, - hash: { type: 'string' }, - ext: { type: 'string' }, - kind: { type: 'string' }, - mime: { type: 'string' }, - fileSize: { type: 'integer' }, - metadata: { type: 'object' }, - createdAt: { type: 'string' }, - updatedAt: { type: 'string' } - } - } - } - - static get relationMappings () { - return { - author: { - relation: Model.BelongsToOneRelation, - modelClass: User, - join: { - from: 'assets.authorId', - to: 'users.id' - } - }, - tree: { - relation: Model.HasOneRelation, - modelClass: Tree, - join: { - from: 'assets.id', - to: 'tree.id' - } - } - } - } - - async $beforeUpdate (opt, context) { - await super.$beforeUpdate(opt, context) - - this.updatedAt = new Date().toISOString() - } - - async $beforeInsert (context) { - await super.$beforeInsert(context) - - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } - - async getAssetPath () { - let hierarchy = [] - if (this.folderId) { - hierarchy = await WIKI.db.assetFolders.getHierarchy(this.folderId) - } - return (this.folderId) ? hierarchy.map(h => h.slug).join('/') + `/${this.filename}` : this.filename - } - - async deleteAssetCache () { - await fse.remove(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${this.hash}.dat`)) - } - - static async upload (opts) { - const fileInfo = path.parse(opts.originalname) - - // Check for existing asset - let asset = await WIKI.db.assets.query().where({ - // hash: fileHash, - folderId: opts.folderId - }).first() - - // Build Object - const assetRow = { - filename: opts.originalname, - ext: fileInfo.ext, - kind: startsWith(opts.mimetype, 'image/') ? 'image' : 'binary', - mime: opts.mimetype, - fileSize: opts.size, - folderId: opts.folderId - } - - // Sanitize SVG contents - if ( - WIKI.config.uploads.scanSVG && - ( - opts.mimetype.toLowerCase().startsWith('image/svg') || - fileInfo.ext.toLowerCase() === '.svg' - ) - ) { - const svgSanitizeJob = await WIKI.scheduler.registerJob({ - name: 'sanitize-svg', - immediate: true, - worker: true - }, opts.path) - await svgSanitizeJob.finished - } - - // Save asset data - try { - const fileBuffer = await fse.readFile(opts.path) - - if (asset) { - // Patch existing asset - if (opts.mode === 'upload') { - assetRow.authorId = opts.user.id - } - await WIKI.db.assets.query().patch(assetRow).findById(asset.id) - await WIKI.db.knex('assetData').where({ - id: asset.id - }).update({ - data: fileBuffer - }) - } else { - // Create asset entry - assetRow.authorId = opts.user.id - asset = await WIKI.db.assets.query().insert(assetRow) - await WIKI.db.knex('assetData').insert({ - id: asset.id, - data: fileBuffer - }) - } - - // Move temp upload to cache - // if (opts.mode === 'upload') { - // await fs.move(opts.path, path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${fileHash}.dat`), { overwrite: true }) - // } else { - // await fs.copy(opts.path, path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${fileHash}.dat`), { overwrite: true }) - // } - - // Add to Storage - if (!opts.skipStorage) { - await WIKI.db.storage.assetEvent({ - event: 'uploaded', - asset: { - ...asset, - path: await asset.getAssetPath(), - data: fileBuffer, - authorId: opts.user.id, - authorName: opts.user.name, - authorEmail: opts.user.email - } - }) - } - } catch (err) { - WIKI.logger.warn(err) - } - } - - static async getThumbnail ({ id, path, locale, siteId }) { - return WIKI.db.tree.query() - .select('tree.*', 'assets.preview', 'assets.previewState') - .innerJoin('assets', 'tree.id', 'assets.id') - .where(id - ? { 'tree.id': id } - : { - 'tree.hash': generateHash(path), - 'tree.locale': locale, - 'tree.siteId': siteId - }) - .first() - } - - static async getAsset ({ pathArgs, siteId }, res) { - try { - const fileInfo = path.parse(pathArgs.path.toLowerCase()) - const fileHash = generateHash(pathArgs.path) - const cachePath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${siteId}/${fileHash}.dat`) - - // Force unsafe extensions to download - if (WIKI.config.security.forceAssetDownload && !['.png', '.apng', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.svg'].includes(fileInfo.ext)) { - res.set('Content-disposition', 'attachment; filename=' + encodeURIComponent(fileInfo.base)) - } - - if (await WIKI.db.assets.getAssetFromCache({ cachePath, extName: fileInfo.ext }, res)) { - return - } - // if (await WIKI.db.assets.getAssetFromStorage(assetPath, res)) { - // return - // } - await WIKI.db.assets.getAssetFromDb({ pathArgs, fileHash, cachePath, siteId }, res) - } catch (err) { - if (err.code === 'ECONNABORTED' || err.code === 'EPIPE') { - return - } - WIKI.logger.error(err) - res.sendStatus(500) - } - } - - static async getAssetFromCache ({ cachePath, extName }, res) { - try { - await fse.access(cachePath, fse.constants.R_OK) - } catch (err) { - return false - } - res.type(extName) - await new Promise(resolve => res.sendFile(cachePath, { dotfiles: 'deny' }, resolve)) - return true - } - - static async getAssetFromStorage (assetPath, res) { - const localLocations = await WIKI.db.storage.getLocalLocations({ - asset: { - path: assetPath - } - }) - for (const location of localLocations.filter(location => Boolean(location.path))) { - const assetExists = await WIKI.db.assets.getAssetFromCache(assetPath, location.path, res) - if (assetExists) { - return true - } - } - return false - } - - static async getAssetFromDb ({ pathArgs, fileHash, cachePath, siteId }, res) { - const asset = await WIKI.db.knex('tree').where({ - siteId, - hash: fileHash - }).first() - if (asset) { - const assetData = await WIKI.db.knex('assets').where('id', asset.id).first() - res.type(assetData.fileExt) - res.send(assetData.data) - await fse.outputFile(cachePath, assetData.data) - } else { - res.sendStatus(404) - } - } - - static async flushTempUploads () { - return fse.emptyDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'uploads')) - } -} diff --git a/server/models/authentication.mjs b/server/models/authentication.mjs deleted file mode 100644 index f13d902ed..000000000 --- a/server/models/authentication.mjs +++ /dev/null @@ -1,61 +0,0 @@ -import { Model } from 'objection' -import fs from 'node:fs/promises' -import path from 'node:path' -import { get } from 'lodash-es' -import yaml from 'js-yaml' -import { parseModuleProps } from '../helpers/common.mjs' - -/** - * Authentication model - */ -export class Authentication extends Model { - static get tableName() { return 'authentication' } - - static get jsonSchema () { - return { - type: 'object', - required: ['module'], - - properties: { - id: { type: 'string' }, - module: { type: 'string' }, - isEnabled: { type: 'boolean' }, - selfRegistration: {type: 'boolean'} - } - } - } - - static get jsonAttributes() { - return ['config', 'domainWhitelist', 'autoEnrollGroups'] - } - - static async getStrategy(module) { - return WIKI.db.authentication.query().findOne({ module }) - } - - static async getStrategies({ enabledOnly = false } = {}) { - return WIKI.db.authentication.query().where(enabledOnly ? { isEnabled: true } : {}) - } - - static async refreshStrategiesFromDisk() { - try { - // -> Fetch definitions from disk - const authenticationDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/authentication')) - WIKI.data.authentication = [] - for (const dir of authenticationDirs) { - const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/authentication', dir, 'definition.yml'), 'utf8') - const defParsed = yaml.load(def) - if (!defParsed.isAvailable) { continue } - defParsed.key = dir - defParsed.props = parseModuleProps(defParsed.props) - WIKI.data.authentication.push(defParsed) - WIKI.logger.debug(`Loaded authentication module definition ${dir}: [ OK ]`) - } - - WIKI.logger.info(`Loaded ${WIKI.data.authentication.length} authentication module definitions: [ OK ]`) - } catch (err) { - WIKI.logger.error(`Failed to scan or load authentication providers: [ FAILED ]`) - WIKI.logger.error(err) - } - } -} diff --git a/server/models/blocks.mjs b/server/models/blocks.mjs deleted file mode 100644 index 1e51568ee..000000000 --- a/server/models/blocks.mjs +++ /dev/null @@ -1,28 +0,0 @@ -import { Model } from 'objection' - -/** - * Block model - */ -export class Block extends Model { - static get tableName () { return 'blocks' } - - static get jsonAttributes () { - return ['config'] - } - - static async addBlock (data) { - return WIKI.db.blocks.query().insertAndFetch({ - block: data.block, - name: data.name, - description: data.description, - icon: data.icon, - isEnabled: true, - isCustom: true, - config: {} - }) - } - - static async deleteBlock (id) { - return WIKI.db.blocks.query().deleteById(id) - } -} diff --git a/server/models/commentProviders.mjs b/server/models/commentProviders.mjs deleted file mode 100644 index e45d56243..000000000 --- a/server/models/commentProviders.mjs +++ /dev/null @@ -1,99 +0,0 @@ -import { Model } from 'objection' -import fs from 'node:fs/promises' -import path from 'node:path' -import { defaultTo, find, forOwn, isBoolean, replace, sortBy } from 'lodash-es' -import yaml from 'js-yaml' -import { parseModuleProps } from '../helpers/common.mjs' - -/** - * CommentProvider model - */ -export class CommentProvider extends Model { - static get tableName() { return 'commentProviders' } - static get idColumn() { return 'key' } - - static get jsonSchema () { - return { - type: 'object', - required: ['key', 'isEnabled'], - - properties: { - key: {type: 'string'}, - isEnabled: {type: 'boolean'} - } - } - } - - static get jsonAttributes() { - return ['config'] - } - - static async getProvider(key) { - return WIKI.db.commentProviders.query().findOne({ key }) - } - - static async getProviders(isEnabled) { - const providers = await WIKI.db.commentProviders.query().where(isBoolean(isEnabled) ? { isEnabled } : {}) - return sortBy(providers, ['module']) - } - - static async refreshProvidersFromDisk() { - try { - // -> Fetch definitions from disk - const commentsDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/comments')) - WIKI.data.commentProviders = [] - for (const dir of commentsDirs) { - const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/comments', dir, 'definition.yml'), 'utf8') - const defParsed = yaml.load(def) - defParsed.key = dir - defParsed.props = parseModuleProps(defParsed.props) - WIKI.data.commentProviders.push(defParsed) - WIKI.logger.debug(`Loaded comments provider module definition ${dir}: [ OK ]`) - } - - WIKI.logger.info(`Loaded ${WIKI.data.commentProviders.length} comments providers module definitions: [ OK ]`) - } catch (err) { - WIKI.logger.error(`Failed to scan or load comments providers: [ FAILED ]`) - WIKI.logger.error(err) - } - } - - static async initProvider() { - const commentProvider = await WIKI.db.commentProviders.query().findOne('isEnabled', true) - if (commentProvider) { - WIKI.data.commentProvider = { - ...find(WIKI.data.commentProviders, ['key', commentProvider.module]), - head: '', - bodyStart: '', - bodyEnd: '', - main: '' - } - - if (WIKI.data.commentProvider.codeTemplate) { - const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/comments', commentProvider.key, 'code.yml'), 'utf8') - let code = yaml.safeLoad(def) - code.head = defaultTo(code.head, '') - code.body = defaultTo(code.body, '') - code.main = defaultTo(code.main, '') - - forOwn(commentProvider.config, (value, key) => { - code.head = replace(code.head, new RegExp(`{{${key}}}`, 'g'), value) - code.body = replace(code.body, new RegExp(`{{${key}}}`, 'g'), value) - code.main = replace(code.main, new RegExp(`{{${key}}}`, 'g'), value) - }) - - WIKI.data.commentProvider.head = code.head - WIKI.data.commentProvider.body = code.body - WIKI.data.commentProvider.main = code.main - } else { - WIKI.data.commentProvider = { - ...WIKI.data.commentProvider, - ...(await import(`../modules/comments/${commentProvider.key}/comment.mjs`)), - config: commentProvider.config - } - await WIKI.data.commentProvider.init() - } - WIKI.data.commentProvider.config = commentProvider.config - } - } -} diff --git a/server/models/comments.mjs b/server/models/comments.mjs deleted file mode 100644 index aac0b617a..000000000 --- a/server/models/comments.mjs +++ /dev/null @@ -1,190 +0,0 @@ -import { Model } from 'objection' -import validate from 'validate.js' - -import { Page } from './pages.mjs' -import { User } from './users.mjs' - -/** - * Comments model - */ -export class Comment extends Model { - static get tableName() { return 'comments' } - - static get jsonSchema () { - return { - type: 'object', - required: [], - - properties: { - id: {type: 'integer'}, - content: {type: 'string'}, - render: {type: 'string'}, - name: {type: 'string'}, - email: {type: 'string'}, - ip: {type: 'string'}, - createdAt: {type: 'string'}, - updatedAt: {type: 'string'} - } - } - } - - static get relationMappings() { - return { - author: { - relation: Model.BelongsToOneRelation, - modelClass: User, - join: { - from: 'comments.authorId', - to: 'users.id' - } - }, - page: { - relation: Model.BelongsToOneRelation, - modelClass: Page, - join: { - from: 'comments.pageId', - to: 'pages.id' - } - } - } - } - - $beforeUpdate() { - this.updatedAt = new Date().toISOString() - } - $beforeInsert() { - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } - - /** - * Post New Comment - */ - static async postNewComment ({ pageId, replyTo, content, guestName, guestEmail, user, ip }) { - // -> Input validation - if (user.id === 2) { - const validation = validate({ - email: guestEmail.toLowerCase(), - name: guestName - }, { - email: { - email: true, - length: { - maximum: 255 - } - }, - name: { - presence: { - allowEmpty: false - }, - length: { - minimum: 2, - maximum: 255 - } - } - }, { format: 'flat' }) - - if (validation && validation.length > 0) { - throw new WIKI.Error.InputInvalid(validation[0]) - } - } - - content = content.trim() - if (content.length < 2) { - throw new WIKI.Error.CommentContentMissing() - } - - // -> Load Page - const page = await WIKI.db.pages.getPageFromDb(pageId) - if (page) { - if (!WIKI.auth.checkAccess(user, ['write:comments'], { - path: page.path, - locale: page.locale - })) { - throw new WIKI.Error.CommentPostForbidden() - } - } else { - throw new WIKI.Error.PageNotFound() - } - - // -> Process by comment provider - return WIKI.data.commentProvider.create({ - page, - replyTo, - content, - user: { - ...user, - ...(user.id === 2) ? { - name: guestName, - email: guestEmail - } : {}, - ip - } - }) - } - - /** - * Update an Existing Comment - */ - static async updateComment ({ id, content, user, ip }) { - // -> Load Page - const pageId = await WIKI.data.commentProvider.getPageIdFromCommentId(id) - if (!pageId) { - throw new WIKI.Error.CommentNotFound() - } - const page = await WIKI.db.pages.getPageFromDb(pageId) - if (page) { - if (!WIKI.auth.checkAccess(user, ['manage:comments'], { - path: page.path, - locale: page.locale - })) { - throw new WIKI.Error.CommentManageForbidden() - } - } else { - throw new WIKI.Error.PageNotFound() - } - - // -> Process by comment provider - return WIKI.data.commentProvider.update({ - id, - content, - page, - user: { - ...user, - ip - } - }) - } - - /** - * Delete an Existing Comment - */ - static async deleteComment ({ id, user, ip }) { - // -> Load Page - const pageId = await WIKI.data.commentProvider.getPageIdFromCommentId(id) - if (!pageId) { - throw new WIKI.Error.CommentNotFound() - } - const page = await WIKI.db.pages.getPageFromDb(pageId) - if (page) { - if (!WIKI.auth.checkAccess(user, ['manage:comments'], { - path: page.path, - locale: page.locale - })) { - throw new WIKI.Error.CommentManageForbidden() - } - } else { - throw new WIKI.Error.PageNotFound() - } - - // -> Process by comment provider - await WIKI.data.commentProvider.remove({ - id, - page, - user: { - ...user, - ip - } - }) - } -} diff --git a/server/models/groups.mjs b/server/models/groups.mjs deleted file mode 100644 index dd3c40b83..000000000 --- a/server/models/groups.mjs +++ /dev/null @@ -1,55 +0,0 @@ -import { Model } from 'objection' - -import { User } from './users.mjs' - -/** - * Groups model - */ -export class Group extends Model { - static get tableName() { return 'groups' } - - static get jsonSchema () { - return { - type: 'object', - required: ['name'], - - properties: { - id: {type: 'integer'}, - name: {type: 'string'}, - isSystem: {type: 'boolean'}, - redirectOnLogin: {type: 'string'}, - createdAt: {type: 'string'}, - updatedAt: {type: 'string'} - } - } - } - - static get jsonAttributes() { - return ['permissions', 'pageRules'] - } - - static get relationMappings() { - return { - users: { - relation: Model.ManyToManyRelation, - modelClass: User, - join: { - from: 'groups.id', - through: { - from: 'userGroups.groupId', - to: 'userGroups.userId' - }, - to: 'users.id' - } - } - } - } - - $beforeUpdate() { - this.updatedAt = new Date().toISOString() - } - $beforeInsert() { - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } -} diff --git a/server/models/hooks.mjs b/server/models/hooks.mjs deleted file mode 100644 index 785312a3e..000000000 --- a/server/models/hooks.mjs +++ /dev/null @@ -1,42 +0,0 @@ -import { Model } from 'objection' - -/** - * Hook model - */ -export class Hook extends Model { - static get tableName () { return 'hooks' } - - static get jsonAttributes () { - return ['events'] - } - - $beforeUpdate () { - this.updatedAt = new Date() - } - - static async createHook (data) { - return WIKI.db.hooks.query().insertAndFetch({ - name: data.name, - events: data.events, - url: data.url, - includeMetadata: data.includeMetadata, - includeContent: data.includeContent, - acceptUntrusted: data.acceptUntrusted, - authHeader: data.authHeader, - state: 'pending', - lastErrorMessage: null - }) - } - - static async updateHook (id, patch) { - return WIKI.db.hooks.query().findById(id).patch({ - ...patch, - state: 'pending', - lastErrorMessage: null - }) - } - - static async deleteHook (id) { - return WIKI.db.hooks.query().deleteById(id) - } -} diff --git a/server/models/index.mjs b/server/models/index.mjs deleted file mode 100644 index 910b984e6..000000000 --- a/server/models/index.mjs +++ /dev/null @@ -1,47 +0,0 @@ -import { Analytics } from './analytics.mjs' -import { ApiKey } from './apiKeys.mjs' -import { Asset } from './assets.mjs' -import { Authentication } from './authentication.mjs' -import { Block } from './blocks.mjs' -import { CommentProvider } from './commentProviders.mjs' -import { Comment } from './comments.mjs' -import { Group } from './groups.mjs' -import { Hook } from './hooks.mjs' -import { Locale } from './locales.mjs' -import { Navigation } from './navigation.mjs' -import { PageHistory } from './pageHistory.mjs' -import { PageLink } from './pageLinks.mjs' -import { Page } from './pages.mjs' -import { Renderer } from './renderers.mjs' -import { Setting } from './settings.mjs' -import { Site } from './sites.mjs' -import { Storage } from './storage.mjs' -import { Tag } from './tags.mjs' -import { Tree } from './tree.mjs' -import { UserKey } from './userKeys.mjs' -import { User } from './users.mjs' - -export default { - analytics: Analytics, - apiKeys: ApiKey, - assets: Asset, - authentication: Authentication, - blocks: Block, - commentProviders: CommentProvider, - comments: Comment, - groups: Group, - hooks: Hook, - locales: Locale, - navigation: Navigation, - pageHistory: PageHistory, - pageLinks: PageLink, - pages: Page, - renderers: Renderer, - settings: Setting, - sites: Site, - storage: Storage, - tags: Tag, - tree: Tree, - userKeys: UserKey, - users: User -} diff --git a/server/models/locales.mjs b/server/models/locales.mjs deleted file mode 100644 index 7efaedb71..000000000 --- a/server/models/locales.mjs +++ /dev/null @@ -1,146 +0,0 @@ -import { Model } from 'objection' -import { find } from 'lodash-es' -import { stat, readFile } from 'node:fs/promises' -import path from 'node:path' -import { DateTime } from 'luxon' - -/** - * Locales model - */ -export class Locale extends Model { - static get tableName() { return 'locales' } - static get idColumn() { return 'code' } - - static get jsonSchema () { - return { - type: 'object', - required: ['code', 'name'], - - properties: { - code: {type: 'string'}, - isRTL: {type: 'boolean', default: false}, - name: {type: 'string'}, - nativeName: {type: 'string'}, - createdAt: {type: 'string'}, - updatedAt: {type: 'string'}, - completeness: {type: 'integer'} - } - } - } - - static get jsonAttributes() { - return ['strings'] - } - - $beforeUpdate() { - this.updatedAt = new Date().toISOString() - } - $beforeInsert() { - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } - - static async refreshFromDisk ({ force = false } = {}) { - try { - const localesMeta = (await import(`../locales/metadata.mjs`)).default - WIKI.logger.info(`Found ${localesMeta.languages.length} locales: [ OK ]`) - - const dbLocales = await WIKI.db.locales.query().select('code', 'updatedAt') - - let localFilesSkipped = 0 - for (const lang of localesMeta.languages) { - // -> Build filename - const langFilenameParts = [lang.language] - if (lang.region) { - langFilenameParts.push(lang.region) - } - if (lang.script) { - langFilenameParts.push(lang.script) - } - const langFilename = langFilenameParts.join('-') - - // -> Get DB version - const dbLang = find(dbLocales, ['code', langFilename]) - - // -> Get File version - const flPath = path.join(WIKI.SERVERPATH, `locales/${langFilename}.json`) - try { - const flStat = await stat(flPath) - const flUpdatedAt = DateTime.fromJSDate(flStat.mtime) - - // -> Load strings - if (!dbLang || DateTime.fromJSDate(dbLang.updatedAt) < flUpdatedAt || force) { - WIKI.logger.debug(`Loading locale ${langFilename} into DB...`) - const flStrings = JSON.parse(await readFile(flPath, 'utf8')) - await WIKI.db.locales.query().insert({ - code: langFilename, - name: lang.name, - nativeName: lang.localizedName, - language: lang.language, - region: lang.region, - script: lang.script, - isRTL: lang.isRtl, - strings: flStrings - }).onConflict('code').merge(['strings', 'updatedAt']) - } else { - WIKI.logger.debug(`Locale ${langFilename} is newer in the DB. Skipping disk version. [ OK ]`) - } - } catch (err) { - localFilesSkipped++ - WIKI.logger.debug(`Locale ${langFilename} not found on disk. Missing strings file. [ SKIPPED ]`) - } - } - if (localFilesSkipped > 0) { - WIKI.logger.info(`${localFilesSkipped} locales were defined in the metadata file but not found on disk. [ SKIPPED ]`) - } - } catch (err) { - WIKI.logger.warn(`Failed to load locales from disk: [ FAILED ]`) - WIKI.logger.warn(err) - return false - } - } - - static async getLocales ({ cache = true } = {}) { - if (!WIKI.cache.has('locales') || !cache) { - const locales = await WIKI.db.locales.query().select('code', 'isRTL', 'language', 'name', 'nativeName', 'createdAt', 'updatedAt', 'completeness') - WIKI.cache.set('locales', locales) - for (const locale of locales) { - WIKI.cache.set(`locale:${locale.code}`, locale) - } - } - return WIKI.cache.get('locales') - } - - static async getStrings (locale) { - const { strings } = await WIKI.db.locales.query().findOne('code', locale).column('strings') - return strings - } - - static async reloadCache () { - await WIKI.db.locales.getLocales({ cache: false }) - } - - static async getNavLocales({ cache = false } = {}) { - return [] - // if (!WIKI.config.lang.namespacing) { - // return [] - // } - - // if (cache) { - // const navLocalesCached = await WIKI.cache.get('nav:locales') - // if (navLocalesCached) { - // return navLocalesCached - // } - // } - // const navLocales = await WIKI.db.locales.query().select('code', 'nativeName AS name').whereIn('code', WIKI.config.lang.namespaces).orderBy('code') - // if (navLocales) { - // if (cache) { - // await WIKI.cache.set('nav:locales', navLocales, 300) - // } - // return navLocales - // } else { - // WIKI.logger.warn('Site Locales for navigation are missing or corrupted.') - // return [] - // } - } -} diff --git a/server/models/navigation.mjs b/server/models/navigation.mjs deleted file mode 100644 index 1b723147c..000000000 --- a/server/models/navigation.mjs +++ /dev/null @@ -1,79 +0,0 @@ -import { Model } from 'objection' -import { has, intersection } from 'lodash-es' - -/** - * Navigation model - */ -export class Navigation extends Model { - static get tableName() { return 'navigation' } - - static get jsonSchema () { - return { - type: 'object', - - properties: { - name: {type: 'string'}, - items: {type: 'array', items: {type: 'object'}} - } - } - } - - static async getNav ({ id, cache = false, userGroups = [] }) { - const result = await WIKI.db.navigation.query().findById(id).select('items') - if (!result) { return [] } - return result.items.filter(item => { - return !item.visibilityGroups?.length || intersection(item.visibilityGroups, userGroups).length > 0 - }).map(item => { - if (!item.children || item.children?.length < 1) { return item } - return { - ...item, - children: item.children.filter(child => { - return !child.visibilityGroups?.length || intersection(child.visibilityGroups, userGroups).length > 0 - }) - } - }) - } - - static async getTree({ cache = false, locale = 'en', groups = [], bypassAuth = false } = {}) { - if (cache) { - const navTreeCached = await WIKI.cache.get(`nav:sidebar:${locale}`) - if (navTreeCached) { - return bypassAuth ? navTreeCached : WIKI.db.navigation.getAuthorizedItems(navTreeCached, groups) - } - } - const navTree = await WIKI.db.navigation.query().findOne('key', `site`) - if (navTree) { - // Check for pre-2.3 format - if (has(navTree.config[0], 'kind')) { - navTree.config = [{ - locale: 'en', - items: navTree.config.map(item => ({ - ...item, - visibilityMode: 'all', - visibilityGroups: [] - })) - }] - } - - for (const tree of navTree.config) { - if (cache) { - await WIKI.cache.set(`nav:sidebar:${tree.locale}`, tree.items, 300) - } - } - if (bypassAuth) { - return locale === 'all' ? navTree.config : WIKI.cache.get(`nav:sidebar:${locale}`) - } else { - return locale === 'all' ? WIKI.db.navigation.getAuthorizedItems(navTree.config, groups) : WIKI.db.navigation.getAuthorizedItems(WIKI.cache.get(`nav:sidebar:${locale}`), groups) - } - } else { - WIKI.logger.warn('Site Navigation is missing or corrupted.') - return [] - } - } - - static getAuthorizedItems(tree = [], groups = []) { - return tree.filter(leaf => { - return leaf.visibilityMode === 'all' || intersection(leaf.visibilityGroups, groups).length > 0 - }) - } -} diff --git a/server/models/pageHistory.mjs b/server/models/pageHistory.mjs deleted file mode 100644 index c07006d6b..000000000 --- a/server/models/pageHistory.mjs +++ /dev/null @@ -1,238 +0,0 @@ -import { Model } from 'objection' -import { get, reduce, reverse } from 'lodash-es' -import { DateTime, Duration } from 'luxon' - -import { Locale } from './locales.mjs' -import { Page } from './pages.mjs' -import { User } from './users.mjs' -import { Tag } from './tags.mjs' - -/** - * Page History model - */ -export class PageHistory extends Model { - static get tableName() { return 'pageHistory' } - - static get jsonSchema () { - return { - type: 'object', - required: ['path', 'title'], - - properties: { - id: {type: 'integer'}, - path: {type: 'string'}, - hash: {type: 'string'}, - title: {type: 'string'}, - description: {type: 'string'}, - publishState: {type: 'string'}, - publishStartDate: {type: 'string'}, - publishEndDate: {type: 'string'}, - content: {type: 'string'}, - contentType: {type: 'string'}, - - createdAt: {type: 'string'} - } - } - } - - static get relationMappings() { - return { - tags: { - relation: Model.ManyToManyRelation, - modelClass: Tag, - join: { - from: 'pageHistory.id', - through: { - from: 'pageHistoryTags.pageId', - to: 'pageHistoryTags.tagId' - }, - to: 'tags.id' - } - }, - page: { - relation: Model.BelongsToOneRelation, - modelClass: Page, - join: { - from: 'pageHistory.pageId', - to: 'pages.id' - } - }, - author: { - relation: Model.BelongsToOneRelation, - modelClass: User, - join: { - from: 'pageHistory.authorId', - to: 'users.id' - } - } - } - } - - $beforeInsert() { - this.createdAt = new Date().toISOString() - } - - /** - * Create Page Version - */ - static async addVersion(opts) { - await WIKI.db.pageHistory.query().insert({ - action: opts.historyData?.action ?? 'updated', - affectedFields: JSON.stringify(opts.historyData?.affectedFields ?? []), - alias: opts.alias, - config: JSON.stringify(opts.config ?? {}), - authorId: opts.authorId, - content: opts.content, - contentType: opts.contentType, - description: opts.description, - editor: opts.editor, - hash: opts.hash, - icon: opts.icon, - locale: opts.locale, - pageId: opts.id, - path: opts.path, - publishEndDate: opts.publishEndDate?.toISO(), - publishStartDate: opts.publishStartDate?.toISO(), - publishState: opts.publishState, - reason: opts.historyData?.reason, - relations: JSON.stringify(opts.relations ?? []), - render: opts.render, - scripts: JSON.stringify(opts.scripts ?? {}), - siteId: opts.siteId, - title: opts.title, - toc: JSON.stringify(opts.toc ?? []), - versionDate: opts.versionDate - }) - } - - /** - * Get Page Version - */ - static async getVersion({ pageId, versionId }) { - const version = await WIKI.db.pageHistory.query() - .column([ - 'pageHistory.path', - 'pageHistory.title', - 'pageHistory.description', - 'pageHistory.isPublished', - 'pageHistory.publishStartDate', - 'pageHistory.publishEndDate', - 'pageHistory.content', - 'pageHistory.contentType', - 'pageHistory.createdAt', - 'pageHistory.action', - 'pageHistory.authorId', - 'pageHistory.pageId', - 'pageHistory.versionDate', - { - versionId: 'pageHistory.id', - editor: 'pageHistory.editorKey', - locale: 'pageHistory.locale', - authorName: 'author.name' - } - ]) - .joinRelated('author') - .where({ - 'pageHistory.id': versionId, - 'pageHistory.pageId': pageId - }).first() - if (version) { - return { - ...version, - updatedAt: version.createdAt || null, - tags: [] - } - } else { - return null - } - } - - /** - * Get History Trail of a Page - */ - static async getHistory({ pageId, offsetPage = 0, offsetSize = 100 }) { - const history = await WIKI.db.pageHistory.query() - .column([ - 'pageHistory.id', - 'pageHistory.path', - 'pageHistory.authorId', - 'pageHistory.action', - 'pageHistory.versionDate', - { - authorName: 'author.name' - } - ]) - .joinRelated('author') - .where({ - 'pageHistory.pageId': pageId - }) - .orderBy('pageHistory.versionDate', 'desc') - .page(offsetPage, offsetSize) - - let prevPh = null - const upperLimit = (offsetPage + 1) * offsetSize - - if (history.total >= upperLimit) { - prevPh = await WIKI.db.pageHistory.query() - .column([ - 'pageHistory.id', - 'pageHistory.path', - 'pageHistory.authorId', - 'pageHistory.action', - 'pageHistory.versionDate', - { - authorName: 'author.name' - } - ]) - .joinRelated('author') - .where({ - 'pageHistory.pageId': pageId - }) - .orderBy('pageHistory.versionDate', 'desc') - .offset((offsetPage + 1) * offsetSize) - .limit(1) - .first() - } - - return { - trail: reduce(reverse(history.results), (res, ph) => { - let actionType = 'edit' - let valueBefore = null - let valueAfter = null - - if (!prevPh && history.total < upperLimit) { - actionType = 'initial' - } else if (get(prevPh, 'path', '') !== ph.path) { - actionType = 'move' - valueBefore = get(prevPh, 'path', '') - valueAfter = ph.path - } - - res.unshift({ - versionId: ph.id, - authorId: ph.authorId, - authorName: ph.authorName, - actionType, - valueBefore, - valueAfter, - versionDate: ph.versionDate - }) - - prevPh = ph - return res - }, []), - total: history.total - } - } - - /** - * Purge history older than X - * - * @param {String} olderThan ISO 8601 Duration - */ - static async purge (olderThan) { - const dur = Duration.fromISO(olderThan) - const olderThanISO = DateTime.utc().minus(dur) - await WIKI.db.pageHistory.query().where('versionDate', '<', olderThanISO.toISO()).del() - } -} diff --git a/server/models/pageLinks.mjs b/server/models/pageLinks.mjs deleted file mode 100644 index 55d5fe3d6..000000000 --- a/server/models/pageLinks.mjs +++ /dev/null @@ -1,36 +0,0 @@ -import { Model } from 'objection' - -import { Page } from './pages.mjs' - -/** - * Users model - */ -export class PageLink extends Model { - static get tableName() { return 'pageLinks' } - - static get jsonSchema () { - return { - type: 'object', - required: ['path', 'locale'], - - properties: { - id: {type: 'integer'}, - path: {type: 'string'}, - locale: {type: 'string'} - } - } - } - - static get relationMappings() { - return { - page: { - relation: Model.BelongsToOneRelation, - modelClass: Page, - join: { - from: 'pageLinks.pageId', - to: 'pages.id' - } - } - } - } -} diff --git a/server/models/pages.mjs b/server/models/pages.mjs deleted file mode 100644 index e0fc8ec1c..000000000 --- a/server/models/pages.mjs +++ /dev/null @@ -1,1371 +0,0 @@ -import { Model } from 'objection' -import { cloneDeep, find, get, has, initial, isEmpty, isString, last, pick } from 'lodash-es' -import { Type as JSBinType } from 'js-binary' -import { getDictNameFromLocale } from '../helpers/common.mjs' -import { generateHash, getFileExtension, injectPageMetadata } from '../helpers/page.mjs' -import path from 'node:path' -import fse from 'fs-extra' -import yaml from 'js-yaml' -import striptags from 'striptags' -import emojiRegex from 'emoji-regex' -import he from 'he' -import CleanCSS from 'clean-css' -import TurndownService from 'turndown' -import { gfm as turndownPluginGfm } from '@joplin/turndown-plugin-gfm' -import * as cheerio from 'cheerio' -import matter from 'gray-matter' - -import { PageLink } from './pageLinks.mjs' -import { User } from './users.mjs' - -const pageRegex = /^[a-zA-Z0-9-_/]*$/ -const aliasRegex = /^[a-zA-Z0-9-_]*$/ - -const frontmatterRegex = { - html: /^()?(?:\n|\r)*([\w\W]*)*/ -} - -/** - * Pages model - */ -export class Page extends Model { - static get tableName () { return 'pages' } - - static get jsonSchema () { - return { - type: 'object', - required: ['path', 'title'], - - properties: { - id: { type: 'string' }, - path: { type: 'string' }, - hash: { type: 'string' }, - title: { type: 'string' }, - description: { type: 'string' }, - publishState: { type: 'string' }, - publishStartDate: { type: 'string' }, - publishEndDate: { type: 'string' }, - content: { type: 'string' }, - contentType: { type: 'string' }, - render: { type: 'string' }, - siteId: { type: 'string' }, - createdAt: { type: 'string' }, - updatedAt: { type: 'string' } - } - } - } - - static get jsonAttributes () { - return ['config', 'historyData', 'relations', 'scripts', 'toc'] - } - - static get relationMappings () { - return { - // tags: { - // relation: Model.ManyToManyRelation, - // modelClass: Tag, - // join: { - // from: 'pages.id', - // through: { - // from: 'pageTags.pageId', - // to: 'pageTags.tagId' - // }, - // to: 'tags.id' - // } - // }, - links: { - relation: Model.HasManyRelation, - modelClass: PageLink, - join: { - from: 'pages.id', - to: 'pageLinks.pageId' - } - }, - author: { - relation: Model.BelongsToOneRelation, - modelClass: User, - join: { - from: 'pages.authorId', - to: 'users.id' - } - }, - creator: { - relation: Model.BelongsToOneRelation, - modelClass: User, - join: { - from: 'pages.creatorId', - to: 'users.id' - } - } - } - } - - $beforeUpdate () { - this.updatedAt = new Date().toISOString() - } - - $beforeInsert () { - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } - - /** - * Solving the violates foreign key constraint using cascade strategy - * using static hooks - * @see https://vincit.github.io/objection.js/api/types/#type-statichookarguments - */ - static async beforeDelete ({ asFindQuery }) { - const page = await asFindQuery().select('id') - await WIKI.db.comments.query().delete().where('pageId', page[0].id) - } - - /** - * Cache Schema - */ - static get cacheSchema () { - return new JSBinType({ - id: 'string', - authorId: 'string', - authorName: 'string', - createdAt: 'string', - creatorId: 'string', - creatorName: 'string', - description: 'string', - editor: 'string', - publishState: 'string', - publishEndDate: 'string', - publishStartDate: 'string', - render: 'string', - siteId: 'string', - tags: [ - { - tag: 'string' - } - ], - extra: { - js: 'string', - css: 'string' - }, - title: 'string', - toc: 'string', - updatedAt: 'string' - }) - } - - /** - * Inject page metadata into contents - * - * @returns {string} Page Contents with Injected Metadata - */ - injectMetadata () { - return injectPageMetadata(this) - } - - /** - * Get the page's file extension based on content type - * - * @returns {string} File Extension - */ - getFileExtension () { - return getFileExtension(this.contentType) - } - - /** - * Parse injected page metadata from raw content - * - * @param {String} raw Raw file contents - * @param {String} contentType Content Type - * @returns {Object} Parsed Page Metadata with Raw Content - */ - static parseMetadata (raw, contentType) { - try { - switch (contentType) { - case 'markdown': { - const result = matter(raw) - if (!result?.isEmpty) { - return { - content: result.content, - ...result.data - } - } - break - } - case 'html': { - const result = frontmatterRegex.html.exec(raw) - if (result[2]) { - return { - ...yaml.safeLoad(result[2]), - content: result[3] - } - } - break - } - } - } catch (err) { - WIKI.logger.warn('Failed to parse page metadata. Invalid syntax.') - } - return { - content: raw - } - } - - /** - * Create a New Page - * - * @param {Object} opts Page Properties - * @returns {Promise} Promise of the Page Model Instance - */ - static async createPage (opts) { - // -> Validate site - if (!WIKI.sites[opts.siteId]) { - throw new Error('ERR_INVALID_SITE') - } - - // -> Remove trailing slash - if (opts.path.endsWith('/')) { - opts.path = opts.path.slice(0, -1) - } - - // -> Remove starting slash - if (opts.path.startsWith('/')) { - opts.path = opts.path.slice(1) - } - - // -> Validate path - if (!pageRegex.test(opts.path)) { - throw new Error('ERR_INVALID_PATH') - } - - opts.path = opts.path.toLowerCase() - // const dotPath = opts.path.replaceAll('/', '.').replaceAll('-', '_') - - // -> Check for page access - if (!WIKI.auth.checkAccess(opts.user, ['write:pages'], { - locale: opts.locale, - path: opts.path - })) { - throw new Error('ERR_FORBIDDEN') - } - - // -> Check for duplicate - const dupCheck = await WIKI.db.pages.query().findOne({ - siteId: opts.siteId, - locale: opts.locale, - path: opts.path - }).select('id') - if (dupCheck) { - throw new Error('ERR_PAGE_DUPLICATE_PATH') - } - - // -> Check for alias - if (opts.alias) { - if (!aliasRegex.test(opts.alias)) { - throw new Error('ERR_PAGE_INVALID_ALIAS') - } - const dupAliasCheck = await WIKI.db.pages.query().findOne({ - siteId: opts.siteId, - alias: opts.alias - }).select('id') - if (dupAliasCheck) { - throw new Error('ERR_PAGE_DUPLICATE_ALIAS') - } - } - - // -> Check for empty content - if (!opts.content || opts.content.trim().length < 1) { - throw new WIKI.Error.PageEmptyContent() - } - - // -> Format CSS Scripts - let scriptCss = '' - if (WIKI.auth.checkAccess(opts.user, ['write:styles'], { - locale: opts.locale, - path: opts.path - })) { - if (!isEmpty(opts.scriptCss)) { - scriptCss = new CleanCSS({ inline: false }).minify(opts.scriptCss).styles - } else { - scriptCss = '' - } - } - - // -> Format JS Scripts - let scriptJsLoad = '' - let scriptJsUnload = '' - if (WIKI.auth.checkAccess(opts.user, ['write:scripts'], { - locale: opts.locale, - path: opts.path - })) { - scriptJsLoad = opts.scriptJsLoad || '' - scriptJsUnload = opts.scriptJsUnload || '' - } - - // -> Get Tags - let tags = [] - if (opts.tags && opts.tags.length > 0) { - tags = await WIKI.db.tags.processNewTags(opts.tags, opts.siteId) - } - - // -> Create page - const page = await WIKI.db.pages.query().insert({ - alias: opts.alias, - authorId: opts.user.id, - content: opts.content, - creatorId: opts.user.id, - config: { - allowComments: opts.allowComments ?? true, - allowContributions: opts.allowContributions ?? true, - allowRatings: opts.allowRatings ?? true, - showSidebar: opts.showSidebar ?? true, - showTags: opts.showTags ?? true, - showToc: opts.showToc ?? true, - tocDepth: opts.tocDepth ?? WIKI.sites[opts.siteId].config?.defaults.tocDepth - }, - contentType: WIKI.data.editors[opts.editor]?.contentType ?? 'text', - description: opts.description, - editor: opts.editor, - hash: generateHash({ path: opts.path, locale: opts.locale }), - icon: opts.icon, - isBrowsable: opts.isBrowsable ?? true, - isSearchable: opts.isSearchable ?? true, - locale: opts.locale, - ownerId: opts.user.id, - path: opts.path, - publishState: opts.publishState, - publishEndDate: opts.publishEndDate?.toISO(), - publishStartDate: opts.publishStartDate?.toISO(), - relations: opts.relations ?? [], - siteId: opts.siteId, - tags, - title: opts.title, - toc: '[]', - scripts: JSON.stringify({ - jsLoad: scriptJsLoad, - jsUnload: scriptJsUnload, - css: scriptCss - }) - }).returning('*') - - // -> Render page to HTML - await WIKI.db.pages.renderPage(page) - - // -> Add to tree - const pathParts = page.path.split('/') - await WIKI.db.tree.addPage({ - id: page.id, - parentPath: initial(pathParts).join('/'), - fileName: last(pathParts), - locale: page.locale, - title: page.title, - tags, - meta: { - authorId: page.authorId, - contentType: page.contentType, - creatorId: page.creatorId, - description: page.description, - isBrowsable: page.isBrowsable, - ownerId: page.ownerId, - publishState: page.publishState, - publishEndDate: page.publishEndDate, - publishStartDate: page.publishStartDate - }, - siteId: page.siteId - }) - - // -> Update search vector - WIKI.db.pages.updatePageSearchVector({ id: page.id }) - - // // -> Add to Storage - // if (!opts.skipStorage) { - // await WIKI.db.storage.pageEvent({ - // event: 'created', - // page - // }) - // } - - // // -> Reconnect Links - // await WIKI.db.pages.reconnectLinks({ - // locale: page.locale, - // path: page.path, - // mode: 'create' - // }) - - // -> Get latest updatedAt - page.updatedAt = await WIKI.db.pages.query().findById(page.id).select('updatedAt').then(r => r.updatedAt) - - return page - } - - /** - * Update an Existing Page - * - * @param {Object} opts Page Properties - * @returns {Promise} Promise of the Page Model Instance - */ - static async updatePage (opts) { - // -> Fetch original page - const ogPage = await WIKI.db.pages.query().findById(opts.id) - if (!ogPage) { - throw new Error('ERR_PAGE_NOT_FOUND') - } - - // -> Check for page access - if (!WIKI.auth.checkAccess(opts.user, ['write:pages'], { - locale: ogPage.locale, - path: ogPage.path - })) { - throw new Error('ERR_PAGE_UPDATE_FORBIDDEN') - } - - const patch = {} - const historyData = { - action: 'updated', - reason: opts.reasonForChange, - affectedFields: [] - } - let shouldUpdateSearch = false - - // -> Create version snapshot - await WIKI.db.pageHistory.addVersion(ogPage) - - // -> Basic fields - if ('title' in opts.patch) { - patch.title = opts.patch.title.trim() - historyData.affectedFields.push('title') - shouldUpdateSearch = true - - if (patch.title.length < 1) { - throw new Error('ERR_PAGE_TITLE_MISSING') - } - } - - if ('description' in opts.patch) { - patch.description = opts.patch.description.trim() - historyData.affectedFields.push('description') - shouldUpdateSearch = true - } - - if ('icon' in opts.patch) { - patch.icon = opts.patch.icon.trim() - historyData.affectedFields.push('icon') - } - - if ('alias' in opts.patch) { - patch.alias = opts.patch.alias.trim() - historyData.affectedFields.push('alias') - - if (patch.alias.length > 255) { - throw new Error('ERR_PAGE_ALIAS_TOO_LONG') - } else if (!aliasRegex.test(patch.alias)) { - throw new Error('ERR_PAGE_INVALID_ALIAS') - } else if (patch.alias.length > 0) { - const dupAliasCheck = await WIKI.db.pages.query().where({ - siteId: ogPage.siteId, - alias: patch.alias - }).andWhereNot('id', ogPage.id).select('id').first() - if (dupAliasCheck) { - throw new Error('ERR_PAGE_DUPLICATE_ALIAS') - } - } - } - - if ('content' in opts.patch && opts.patch.content) { - patch.content = opts.patch.content - historyData.affectedFields.push('content') - shouldUpdateSearch = true - } - - // -> Publish State - if (opts.patch.publishState) { - patch.publishState = opts.patch.publishState - historyData.affectedFields.push('publishState') - - if (patch.publishState === 'scheduled' && (!opts.patch.publishStartDate || !opts.patch.publishEndDate)) { - throw new Error('ERR_PAGE_MISSING_SCHEDULED_DATES') - } - } - if (opts.patch.publishStartDate) { - patch.publishStartDate = opts.patch.publishStartDate - historyData.affectedFields.push('publishStartDate') - } - if (opts.patch.publishEndDate) { - patch.publishEndDate = opts.patch.publishEndDate - historyData.affectedFields.push('publishEndDate') - } - - // -> Browsable / Searchable Flags - if ('isBrowsable' in opts.patch) { - patch.isBrowsable = opts.patch.isBrowsable - historyData.affectedFields.push('isBrowsable') - } - if ('isSearchable' in opts.patch) { - patch.isSearchable = opts.patch.isSearchable - historyData.affectedFields.push('isSearchable') - } - - // -> Page Config - if ('allowComments' in opts.patch) { - patch.config = { - ...patch.config ?? ogPage.config ?? {}, - allowComments: opts.patch.allowComments - } - historyData.affectedFields.push('allowComments') - } - if ('allowContributions' in opts.patch) { - patch.config = { - ...patch.config ?? ogPage.config ?? {}, - allowContributions: opts.patch.allowContributions - } - historyData.affectedFields.push('allowContributions') - } - if ('allowRatings' in opts.patch) { - patch.config = { - ...patch.config ?? ogPage.config ?? {}, - allowRatings: opts.patch.allowRatings - } - historyData.affectedFields.push('allowRatings') - } - if ('showSidebar' in opts.patch) { - patch.config = { - ...patch.config ?? ogPage.config ?? {}, - showSidebar: opts.patch.showSidebar - } - historyData.affectedFields.push('showSidebar') - } - if ('showTags' in opts.patch) { - patch.config = { - ...patch.config ?? ogPage.config ?? {}, - showTags: opts.patch.showTags - } - historyData.affectedFields.push('showTags') - } - if ('showToc' in opts.patch) { - patch.config = { - ...patch.config ?? ogPage.config ?? {}, - showToc: opts.patch.showToc - } - historyData.affectedFields.push('showToc') - } - if ('tocDepth' in opts.patch) { - patch.config = { - ...patch.config ?? ogPage.config ?? {}, - tocDepth: opts.patch.tocDepth - } - historyData.affectedFields.push('tocDepth') - - if (patch.config.tocDepth?.min < 1 || patch.config.tocDepth?.min > 6) { - throw new Error('ERR_PAGE_INVALID_TOC_DEPTH') - } - if (patch.config.tocDepth?.max < 1 || patch.config.tocDepth?.max > 6) { - throw new Error('ERR_PAGE_INVALID_TOC_DEPTH') - } - } - - // -> Relations - if ('relations' in opts.patch) { - patch.relations = opts.patch.relations.map(r => { - if (r.label.length < 1) { - throw new Error('ERR_PAGE_RELATION_LABEL_MISSING') - } else if (r.label.length > 255) { - throw new Error('ERR_PAGE_RELATION_LABEL_TOOLONG') - } else if (r.icon.length > 255) { - throw new Error('ERR_PAGE_RELATION_ICON_INVALID') - } else if (r.target.length > 1024) { - throw new Error('ERR_PAGE_RELATION_TARGET_INVALID') - } - return r - }) - historyData.affectedFields.push('relations') - } - - // -> Format CSS Scripts - if (opts.patch.scriptCss) { - if (WIKI.auth.checkAccess(opts.user, ['write:styles'], { - locale: ogPage.locale, - path: ogPage.path - })) { - patch.scripts = { - ...patch.scripts ?? ogPage.scripts ?? {}, - css: !isEmpty(opts.patch.scriptCss) ? new CleanCSS({ inline: false }).minify(opts.patch.scriptCss).styles : '' - } - historyData.affectedFields.push('scripts.css') - } - } - - // -> Format JS Scripts - if (opts.patch.scriptJsLoad) { - if (WIKI.auth.checkAccess(opts.user, ['write:scripts'], { - locale: ogPage.locale, - path: ogPage.path - })) { - patch.scripts = { - ...patch.scripts ?? ogPage.scripts ?? {}, - jsLoad: opts.patch.scriptJsLoad ?? '' - } - historyData.affectedFields.push('scripts.jsLoad') - } - } - if (opts.patch.scriptJsUnload) { - if (WIKI.auth.checkAccess(opts.user, ['write:scripts'], { - locale: ogPage.locale, - path: ogPage.path - })) { - patch.scripts = { - ...patch.scripts ?? ogPage.scripts ?? {}, - jsUnload: opts.patch.scriptJsUnload ?? '' - } - historyData.affectedFields.push('scripts.jsUnload') - } - } - - // -> Tags - if ('tags' in opts.patch) { - patch.tags = await WIKI.db.tags.processNewTags(opts.patch.tags, ogPage.siteId) - historyData.affectedFields.push('tags') - } - - // -> Update page - await WIKI.db.pages.query().patch({ - ...patch, - authorId: opts.user.id, - historyData - }).where('id', ogPage.id) - const page = await WIKI.db.pages.getPageFromDb(ogPage.id) - - // -> Render page to HTML - if (opts.patch.content) { - await WIKI.db.pages.renderPage(page) - } - WIKI.events.outbound.emit('deletePageFromCache', page.hash) - - // -> Update tree - await WIKI.db.knex('tree').where('id', page.id).update({ - title: page.title, - tags: page.tags, - meta: { - authorId: page.authorId, - contentType: page.contentType, - creatorId: page.creatorId, - description: page.description, - isBrowsable: page.isBrowsable, - ownerId: page.ownerId, - publishState: page.publishState, - publishEndDate: page.publishEndDate, - publishStartDate: page.publishStartDate - }, - updatedAt: page.updatedAt - }) - - // -> Update search vector - if (shouldUpdateSearch) { - WIKI.db.pages.updatePageSearchVector({ id: page.id }) - } - - // -> Update on Storage - // if (!opts.skipStorage) { - // await WIKI.db.storage.pageEvent({ - // event: 'updated', - // page - // }) - // } - - // -> Get latest updatedAt - page.updatedAt = await WIKI.db.pages.query().findById(page.id).select('updatedAt').then(r => r.updatedAt) - - return page - } - - /** - * Update a page text search vector value - * - * @param {Object} opts - Options - * @param {string} [opts.id] - Page ID to update (fetch from DB) - * @param {Object} [opts.page] - Page object to update (use directly) - */ - static async updatePageSearchVector ({ id, page }) { - if (!page) { - if (!id) { - throw new Error('Must provide either the page ID or the page object.') - } - page = await WIKI.db.pages.query().findById(id).select('id', 'locale', 'render', 'password') - } - // -> Exclude password-protected content from being indexed - const safeContent = page.password ? '' : WIKI.db.pages.cleanHTML(page.render) - const dictName = getDictNameFromLocale(page.locale) - return WIKI.db.knex('pages').where('id', page.id).update({ - searchContent: safeContent, - ts: WIKI.db.knex.raw(` - setweight(to_tsvector('${dictName}', coalesce(title,'')), 'A') || - setweight(to_tsvector('${dictName}', coalesce(description,'')), 'B') || - setweight(to_tsvector('${dictName}', coalesce(?,'')), 'C')`, [safeContent]) - }) - } - - /** - * Refresh Autocomplete Index - */ - static async refreshAutocompleteIndex () { - await WIKI.db.knex('autocomplete').truncate() - await WIKI.db.knex.raw(` - INSERT INTO "autocomplete" (word) - SELECT word FROM ts_stat( - 'SELECT to_tsvector(''simple'', "title") || to_tsvector(''simple'', "description") || to_tsvector(''simple'', "searchContent") FROM "pages" WHERE "isSearchableComputed" IS TRUE' - ) - `) - } - - /** - * Convert an Existing Page - * - * @param {Object} opts Page Properties - * @returns {Promise} Promise of the Page Model Instance - */ - static async convertPage (opts) { - // -> Fetch original page - const ogPage = await WIKI.db.pages.query().findById(opts.id) - if (!ogPage) { - throw new Error('Invalid Page Id') - } - - if (ogPage.editor === opts.editor) { - throw new Error('Page is already using this editor. Nothing to convert.') - } - - // -> Check for page access - if (!WIKI.auth.checkAccess(opts.user, ['write:pages'], { - locale: ogPage.locale, - path: ogPage.path - })) { - throw new WIKI.Error.PageUpdateForbidden() - } - - // -> Check content type - const sourceContentType = ogPage.contentType - const targetContentType = get(find(WIKI.data.editors, ['key', opts.editor]), 'contentType', 'text') - const shouldConvert = sourceContentType !== targetContentType - let convertedContent = null - - // -> Convert content - if (shouldConvert) { - // -> Markdown => HTML - if (sourceContentType === 'markdown' && targetContentType === 'html') { - if (!ogPage.render) { - throw new Error('Aborted conversion because rendered page content is empty!') - } - convertedContent = ogPage.render - - const $ = cheerio.load(convertedContent, { - decodeEntities: true - }) - - if ($.root().children().length > 0) { - // Remove header anchors - $('.toc-anchor').remove() - - // Attempt to convert tabsets - $('tabset').each((tabI, tabElm) => { - const tabHeaders = [] - // -> Extract templates - $(tabElm).children('template').each((tmplI, tmplElm) => { - if ($(tmplElm).attr('v-slot:tabs') === '') { - $(tabElm).before('
    ' + $(tmplElm).html() + '
') - } else { - $(tabElm).after('
' + $(tmplElm).html() + '
') - } - }) - // -> Parse tab headers - $(tabElm).prev('.tabset-headers').children((i, elm) => { - tabHeaders.push($(elm).html()) - }) - $(tabElm).prev('.tabset-headers').remove() - // -> Inject tab headers - $(tabElm).next('.markdown-tabset').children((i, elm) => { - if (tabHeaders.length > i) { - $(elm).prepend(`

${tabHeaders[i]}

`) - } - }) - $(tabElm).next('.markdown-tabset').prepend('

Tabset

') - $(tabElm).remove() - }) - - convertedContent = $.html('body').replace('', '').replace('', '').replace(/&#x([0-9a-f]{1,6});/ig, (entity, code) => { - code = parseInt(code, 16) - - // Don't unescape ASCII characters, assuming they're encoded for a good reason - if (code < 0x80) return entity - - return String.fromCodePoint(code) - }) - } - - // -> HTML => Markdown - } else if (sourceContentType === 'html' && targetContentType === 'markdown') { - const td = new TurndownService({ - bulletListMarker: '-', - codeBlockStyle: 'fenced', - emDelimiter: '*', - fence: '```', - headingStyle: 'atx', - hr: '---', - linkStyle: 'inlined', - preformattedCode: true, - strongDelimiter: '**' - }) - - td.use(turndownPluginGfm) - - td.keep(['kbd']) - - td.addRule('subscript', { - filter: ['sub'], - replacement: c => `~${c}~` - }) - - td.addRule('superscript', { - filter: ['sup'], - replacement: c => `^${c}^` - }) - - td.addRule('underline', { - filter: ['u'], - replacement: c => `_${c}_` - }) - - td.addRule('taskList', { - filter: (n, o) => { - return n.nodeName === 'INPUT' && n.getAttribute('type') === 'checkbox' - }, - replacement: (c, n) => { - return n.getAttribute('checked') ? '[x] ' : '[ ] ' - } - }) - - td.addRule('removeTocAnchors', { - filter: (n, o) => { - return n.nodeName === 'A' && n.classList.contains('toc-anchor') - }, - replacement: c => '' - }) - - convertedContent = td.turndown(ogPage.content) - // -> Unsupported - } else { - throw new Error('Unsupported source / destination content types combination.') - } - } - - // -> Create version snapshot - if (shouldConvert) { - await WIKI.db.pageHistory.addVersion({ - ...ogPage, - action: 'updated', - versionDate: ogPage.updatedAt - }) - } - - // -> Update page - await WIKI.db.pages.query().patch({ - contentType: targetContentType, - editor: opts.editor, - ...(convertedContent ? { content: convertedContent } : {}) - }).where('id', ogPage.id) - const page = await WIKI.db.pages.getPageFromDb(ogPage.id) - - await WIKI.db.pages.deletePageFromCache(page.hash) - WIKI.events.outbound.emit('deletePageFromCache', page.hash) - - // -> Update on Storage - await WIKI.db.storage.pageEvent({ - event: 'updated', - page - }) - } - - /** - * Move a Page - * - * @param {Object} opts Page Properties - * @returns {Promise} Promise with no value - */ - static async movePage (opts) { - if (!has(opts, 'id')) { - throw new Error('Missing page ID') - } - const page = await WIKI.db.pages.query().findById(opts.id) - if (!page) { - throw new WIKI.Error.PageNotFound() - } - - // -> Validate path - if (opts.destinationPath.includes('.') || opts.destinationPath.includes(' ') || opts.destinationPath.includes('\\') || opts.destinationPath.includes('//')) { - throw new WIKI.Error.PageIllegalPath() - } - - // -> Remove trailing slash - if (opts.destinationPath.endsWith('/')) { - opts.destinationPath = opts.destinationPath.slice(0, -1) - } - - // -> Remove starting slash - if (opts.destinationPath.startsWith('/')) { - opts.destinationPath = opts.destinationPath.slice(1) - } - - // -> Check for source page access - if (!WIKI.auth.checkAccess(opts.user, ['manage:pages'], { - locale: page.locale, - path: page.path - })) { - throw new WIKI.Error.PageMoveForbidden() - } - // -> Check for destination page access - if (!WIKI.auth.checkAccess(opts.user, ['write:pages'], { - locale: opts.destinationLocale, - path: opts.destinationPath - })) { - throw new WIKI.Error.PageMoveForbidden() - } - - // -> Check for existing page at destination path - const destPage = await WIKI.db.pages.query().findOne({ - path: opts.destinationPath, - locale: opts.destinationLocale - }) - if (destPage) { - throw new WIKI.Error.PagePathCollision() - } - - // -> Create version snapshot - await WIKI.db.pageHistory.addVersion({ - ...page, - action: 'moved', - versionDate: page.updatedAt - }) - - // -> Update page object - const updatedPage = cloneDeep(page) - updatedPage.path = opts.destinationPath - updatedPage.locale = opts.destinationLocale - updatedPage.title = opts.title ?? page.title - updatedPage.hash = generateHash({ path: opts.destinationPath, locale: opts.destinationLocale }) - updatedPage.authorId = opts.user.id - - // -> Move page - await WIKI.db.pages.query().patch({ - path: updatedPage.path, - locale: updatedPage.locale, - title: updatedPage.title, - hash: updatedPage.hash, - authorId: updatedPage.authorId - }).findById(page.id) - await WIKI.db.pages.deletePageFromCache(page.hash) - WIKI.events.outbound.emit('deletePageFromCache', page.hash) - - // -> Replace tree node - const pathParts = updatedPage.path.split('/') - await WIKI.db.knex('tree').where('id', page.id).del() - await WIKI.db.tree.addPage({ - id: page.id, - parentPath: initial(pathParts).join('/'), - fileName: last(pathParts), - locale: updatedPage.locale, - title: updatedPage.title, - tags: updatedPage.tags, - meta: { - authorId: updatedPage.authorId, - contentType: updatedPage.contentType, - creatorId: updatedPage.creatorId, - description: updatedPage.description, - isBrowsable: updatedPage.isBrowsable, - ownerId: updatedPage.ownerId, - publishState: updatedPage.publishState, - publishEndDate: updatedPage.publishEndDate, - publishStartDate: updatedPage.publishStartDate - }, - siteId: updatedPage.siteId - }) - - // -> Rename in Search Index - WIKI.db.pages.updatePageSearchVector({ id: page.id }) - - // -> Rename in Storage - if (!opts.skipStorage) { - // await WIKI.db.storage.pageEvent({ - // event: 'renamed', - // page: { - // ...page, - // destinationPath: updatedPage.path, - // destinationLocale: updatedPage.locale, - // destinationHash: updatedPage.hash, - // moveAuthorId: opts.user.id, - // moveAuthorName: opts.user.name, - // moveAuthorEmail: opts.user.email - // } - // }) - } - - // // -> Reconnect Links : Changing old links to the new path - // await WIKI.db.pages.reconnectLinks({ - // sourceLocale: page.locale, - // sourcePath: page.path, - // locale: opts.destinationLocale, - // path: opts.destinationPath, - // mode: 'move' - // }) - - // // -> Reconnect Links : Validate invalid links to the new path - // await WIKI.db.pages.reconnectLinks({ - // locale: opts.destinationLocale, - // path: opts.destinationPath, - // mode: 'create' - // }) - } - - /** - * Delete an Existing Page - * - * @param {Object} opts Page Properties - * @returns {Promise} Promise with no value - */ - static async deletePage (opts) { - const page = await WIKI.db.pages.getPageFromDb(has(opts, 'id') ? opts.id : opts) - if (!page) { - throw new WIKI.Error.PageNotFound() - } - - // -> Check for page access - if (!WIKI.auth.checkAccess(opts.user, ['delete:pages'], { - locale: page.locale, - path: page.path - })) { - throw new WIKI.Error.PageDeleteForbidden() - } - - // -> Create version snapshot - await WIKI.db.pageHistory.addVersion({ - ...page, - action: 'deleted', - versionDate: page.updatedAt - }) - - // -> Delete page - await WIKI.db.pages.query().delete().where('id', page.id) - await WIKI.db.knex('tree').where('id', page.id).del() - await WIKI.db.pages.deletePageFromCache(page.hash) - WIKI.events.outbound.emit('deletePageFromCache', page.hash) - - // -> Delete from Storage - if (!opts.skipStorage) { - // await WIKI.db.storage.pageEvent({ - // event: 'deleted', - // page - // }) - } - - // -> Reconnect Links - await WIKI.db.pages.reconnectLinks({ - locale: page.locale, - path: page.path, - mode: 'delete' - }) - } - - /** - * Reconnect links to new/move/deleted page - * - * @param {Object} opts - Page parameters - * @param {string} opts.path - Page Path - * @param {string} opts.locale - Page Locale Code - * @param {string} [opts.sourcePath] - Previous Page Path (move only) - * @param {string} [opts.sourceLocale] - Previous Page Locale Code (move only) - * @param {string} opts.mode - Page Update mode (create, move, delete) - * @returns {Promise} Promise with no value - */ - static async reconnectLinks (opts) { - return - // TODO: fix this - const pageHref = `/${opts.locale}/${opts.path}` - const replaceArgs = { - from: '', - to: '' - } - switch (opts.mode) { - case 'create': - replaceArgs.from = `` - replaceArgs.to = `` - break - case 'move': - const prevPageHref = `/${opts.sourceLocale}/${opts.sourcePath}` - replaceArgs.from = `` - replaceArgs.to = `` - break - case 'delete': - replaceArgs.from = `` - replaceArgs.to = `` - break - default: - return false - } - - let affectedHashes = [] - // -> Perform replace and return affected page hashes (POSTGRES only) - if (WIKI.config.db.type === 'postgres') { - const qryHashes = await WIKI.db.pages.query() - .returning('hash') - .patch({ - render: WIKI.db.knex.raw('REPLACE(??, ?, ?)', ['render', replaceArgs.from, replaceArgs.to]) - }) - .whereIn('pages.id', function () { - this.select('pageLinks.pageId').from('pageLinks').where({ - 'pageLinks.path': opts.path, - 'pageLinks.locale': opts.locale - }) - }) - affectedHashes = qryHashes.map(h => h.hash) - } else { - // -> Perform replace, then query affected page hashes (MYSQL, MARIADB, MSSQL, SQLITE only) - await WIKI.db.pages.query() - .patch({ - render: WIKI.db.knex.raw('REPLACE(??, ?, ?)', ['render', replaceArgs.from, replaceArgs.to]) - }) - .whereIn('pages.id', function () { - this.select('pageLinks.pageId').from('pageLinks').where({ - 'pageLinks.path': opts.path, - 'pageLinks.locale': opts.locale - }) - }) - const qryHashes = await WIKI.db.pages.query() - .column('hash') - .whereIn('pages.id', function () { - this.select('pageLinks.pageId').from('pageLinks').where({ - 'pageLinks.path': opts.path, - 'pageLinks.locale': opts.locale - }) - }) - affectedHashes = qryHashes.map(h => h.hash) - } - for (const hash of affectedHashes) { - await WIKI.db.pages.deletePageFromCache(hash) - WIKI.events.outbound.emit('deletePageFromCache', hash) - } - } - - /** - * Trigger the rendering of a page - * - * @param {Object} page Page Model Instance - * @returns {Promise} Promise with no value - */ - static async renderPage (page) { - const renderJob = await WIKI.scheduler.addJob({ - task: 'render-page', - payload: { - id: page.id - }, - maxRetries: 0, - promise: true - }) - return renderJob.promise - } - - /** - * Fetch an Existing Page from Cache if possible, from DB otherwise and save render to Cache - * - * @param {Object} opts Page Properties - * @returns {Promise} Promise of the Page Model Instance - */ - static async getPage (opts) { - return WIKI.db.pages.getPageFromDb(opts) - - // -> Get from cache first - let page = await WIKI.db.pages.getPageFromCache(opts) - if (!page) { - // -> Get from DB - page = await WIKI.db.pages.getPageFromDb(opts) - if (page) { - if (page.render) { - // -> Save render to cache - await WIKI.db.pages.savePageToCache(page) - } else { - // -> No render? Possible duplicate issue - /* TODO: Detect duplicate and delete */ - throw new Error('Error while fetching page. No rendered version of this page exists. Try to edit the page and save it again.') - } - } - } - return page - } - - /** - * Fetch an Existing Page from the Database - * - * @param {Object} opts Page Properties - * @returns {Promise} Promise of the Page Model Instance - */ - static async getPageFromDb (opts) { - const queryModeID = typeof opts === 'string' - try { - return WIKI.db.pages.query() - .column([ - 'pages.*', - { - authorName: 'author.name', - authorEmail: 'author.email', - creatorName: 'creator.name', - creatorEmail: 'creator.email' - }, - 'tree.navigationId', - 'tree.navigationMode' - ]) - .joinRelated('author') - .joinRelated('creator') - .leftJoin('tree', 'pages.id', 'tree.id') - .where(queryModeID - ? { - 'pages.id': opts - } - : { - 'pages.siteId': opts.siteId, - 'pages.path': opts.path, - 'pages.locale': opts.locale - }) - // .andWhere(builder => { - // if (queryModeID) return - // builder.where({ - // 'pages.isPublished': true - // }).orWhere({ - // 'pages.isPublished': false, - // 'pages.authorId': opts.userId - // }) - // }) - .first() - } catch (err) { - WIKI.logger.warn(err) - throw err - } - } - - /** - * Save a Page Model Instance to Cache - * - * @param {Object} page Page Model Instance - * @returns {Promise} Promise with no value - */ - static async savePageToCache (page) { - const cachePath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${page.hash}.bin`) - await fse.outputFile(cachePath, WIKI.db.pages.cacheSchema.encode({ - id: page.id, - authorId: page.authorId, - authorName: page.authorName, - createdAt: page.createdAt.toISOString(), - creatorId: page.creatorId, - creatorName: page.creatorName, - description: page.description, - editor: page.editor, - extra: { - css: get(page, 'extra.css', ''), - js: get(page, 'extra.js', '') - }, - publishState: page.publishState ?? '', - publishEndDate: page.publishEndDate ?? '', - publishStartDate: page.publishStartDate ?? '', - render: page.render, - siteId: page.siteId, - tags: page.tags.map(t => pick(t, ['tag'])), - title: page.title, - toc: isString(page.toc) ? page.toc : JSON.stringify(page.toc), - updatedAt: page.updatedAt.toISOString() - })) - } - - /** - * Fetch an Existing Page from Cache - * - * @param {Object} opts Page Properties - * @returns {Promise} Promise of the Page Model Instance - */ - static async getPageFromCache (opts) { - const pageHash = generateHash({ path: opts.path, locale: opts.locale }) - const cachePath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${pageHash}.bin`) - - try { - const pageBuffer = await fse.readFile(cachePath) - const page = WIKI.db.pages.cacheSchema.decode(pageBuffer) - return { - ...page, - path: opts.path, - locale: opts.locale - } - } catch (err) { - if (err.code === 'ENOENT') { - return false - } - WIKI.logger.error(err) - throw err - } - } - - /** - * Delete an Existing Page from Cache - * - * @param {String} page Page Unique Hash - * @returns {Promise} Promise with no value - */ - static async deletePageFromCache (hash) { - return fse.remove(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${hash}.bin`)) - } - - /** - * Flush the contents of the Cache - */ - static async flushCache () { - return fse.emptyDir(path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'cache')) - } - - /** - * Migrate all pages from a source locale to the target locale - * - * @param {Object} opts Migration properties - * @param {string} opts.sourceLocale Source Locale Code - * @param {string} opts.targetLocale Target Locale Code - * @returns {Promise} Promise with no value - */ - static async migrateToLocale ({ sourceLocale, targetLocale }) { - return WIKI.db.pages.query() - .patch({ - locale: targetLocale - }) - .where({ - locale: sourceLocale - }) - .whereNotExists(function () { - this.select('id').from('pages AS pagesm').where('pagesm.locale', targetLocale).andWhereRaw('pagesm.path = pages.path') - }) - } - - /** - * Clean raw HTML from content for use in search engines - * - * @param {string} rawHTML Raw HTML - * @returns {string} Cleaned Content Text - */ - static cleanHTML (rawHTML = '') { - const data = striptags(rawHTML || '', [], ' ') - .replace(emojiRegex(), '') - return he.decode(data) - .replace(/(\r\n|\n|\r)/gm, ' ') - .replace(/\s\s+/g, ' ') - } - - /** - * Subscribe to HA propagation events - */ - static subscribeToEvents () { - WIKI.events.inbound.on('deletePageFromCache', hash => { - WIKI.db.pages.deletePageFromCache(hash) - }) - WIKI.events.inbound.on('flushCache', () => { - WIKI.db.pages.flushCache() - }) - } -} diff --git a/server/models/renderers.mjs b/server/models/renderers.mjs deleted file mode 100644 index 58401ed09..000000000 --- a/server/models/renderers.mjs +++ /dev/null @@ -1,174 +0,0 @@ -import { Model } from 'objection' -import path from 'node:path' -import fs from 'fs/promises' -import { clone, filter, find, get, has, reverse, some, transform, union } from 'lodash-es' -import yaml from 'js-yaml' -import { DepGraph } from 'dependency-graph' -import { parseModuleProps } from '../helpers/common.mjs' - -/** - * Renderer model - */ -export class Renderer extends Model { - static get tableName() { return 'renderers' } - - static get jsonSchema () { - return { - type: 'object', - required: ['module', 'isEnabled'], - - properties: { - id: {type: 'string'}, - module: {type: 'string'}, - isEnabled: {type: 'boolean'} - } - } - } - - static get jsonAttributes() { - return ['config'] - } - - static async getRenderers() { - return WIKI.db.renderers.query() - } - - static async fetchDefinitions() { - try { - // -> Fetch definitions from disk - const renderersDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/rendering')) - WIKI.data.renderers = [] - for (const dir of renderersDirs) { - const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/rendering', dir, 'definition.yml'), 'utf8') - const defParsed = yaml.load(def) - defParsed.key = dir - defParsed.props = parseModuleProps(defParsed.props) - WIKI.data.renderers.push(defParsed) - WIKI.logger.debug(`Loaded renderers module definition ${dir}: [ OK ]`) - } - - WIKI.logger.info(`Loaded ${WIKI.data.renderers.length} renderers module definitions: [ OK ]`) - } catch (err) { - WIKI.logger.error(`Failed to scan or load renderers providers: [ FAILED ]`) - WIKI.logger.error(err) - } - } - - static async refreshRenderersFromDisk() { - try { - const dbRenderers = await WIKI.db.renderers.query() - - // -> Fetch definitions from disk - await WIKI.db.renderers.fetchDefinitions() - - // -> Insert new Renderers - const newRenderers = [] - let updatedRenderers = 0 - for (const renderer of WIKI.data.renderers) { - if (!some(dbRenderers, ['module', renderer.key])) { - newRenderers.push({ - module: renderer.key, - isEnabled: renderer.enabledDefault ?? true, - config: transform(renderer.props, (result, value, key) => { - result[key] = value.default - return result - }, {}) - }) - } else { - const rendererConfig = get(find(dbRenderers, ['module', renderer.key]), 'config', {}) - await WIKI.db.renderers.query().patch({ - config: transform(renderer.props, (result, value, key) => { - if (!has(result, key)) { - result[key] = value.default - } - return result - }, rendererConfig) - }).where('module', renderer.key) - updatedRenderers++ - } - } - if (newRenderers.length > 0) { - await WIKI.db.renderers.query().insert(newRenderers) - WIKI.logger.info(`Loaded ${newRenderers.length} new renderers: [ OK ]`) - } - - if (updatedRenderers > 0) { - WIKI.logger.info(`Updated ${updatedRenderers} existing renderers: [ OK ]`) - } - - // -> Delete removed Renderers - for (const renderer of dbRenderers) { - if (!some(WIKI.data.renderers, ['key', renderer.module])) { - await WIKI.db.renderers.query().where('module', renderer.module).del() - WIKI.logger.info(`Removed renderer ${renderer.module} because it is no longer present in the modules folder: [ OK ]`) - } - } - } catch (err) { - WIKI.logger.error('Failed to import renderers: [ FAILED ]') - WIKI.logger.error(err) - } - } - - static async getRenderingPipeline(contentType) { - const renderersDb = await WIKI.db.renderers.query().where('isEnabled', true) - if (renderersDb && renderersDb.length > 0) { - const renderers = renderersDb.map(rdr => { - const renderer = find(WIKI.data.renderers, ['key', rdr.module]) - return { - ...renderer, - config: rdr.config - } - }) - - // Build tree - const rawCores = filter(renderers, renderer => !has(renderer, 'dependsOn')).map(core => { - core.children = filter(renderers, ['dependsOn', core.key]) - return core - }) - - // Build dependency graph - const graph = new DepGraph({ circular: true }) - rawCores.map(core => { graph.addNode(core.key) }) - rawCores.map(core => { - rawCores.map(coreTarget => { - if (core.key !== coreTarget.key) { - if (core.output === coreTarget.input) { - graph.addDependency(core.key, coreTarget.key) - } - } - }) - }) - - // Filter unused cores - let activeCoreKeys = filter(rawCores, ['input', contentType]).map(core => core.key) - clone(activeCoreKeys).map(coreKey => { - activeCoreKeys = union(activeCoreKeys, graph.dependenciesOf(coreKey)) - }) - const activeCores = filter(rawCores, core => activeCoreKeys.includes(core.key)) - - // Rebuild dependency graph with active cores - const graphActive = new DepGraph({ circular: true }) - activeCores.map(core => { graphActive.addNode(core.key) }) - activeCores.map(core => { - activeCores.map(coreTarget => { - if (core.key !== coreTarget.key) { - if (core.output === coreTarget.input) { - graphActive.addDependency(core.key, coreTarget.key) - } - } - }) - }) - - // Reorder cores in reverse dependency order - let orderedCores = [] - reverse(graphActive.overallOrder()).map(coreKey => { - orderedCores.push(find(rawCores, ['key', coreKey])) - }) - - return orderedCores - } else { - WIKI.logger.error(`Rendering pipeline is empty!`) - return false - } - } -} diff --git a/server/models/settings.mjs b/server/models/settings.mjs deleted file mode 100644 index 36b0bdb25..000000000 --- a/server/models/settings.mjs +++ /dev/null @@ -1,37 +0,0 @@ -import { Model } from 'objection' -import { has, reduce, set } from 'lodash-es' - -/** - * Settings model - */ -export class Setting extends Model { - static get tableName() { return 'settings' } - static get idColumn() { return 'key' } - - static get jsonSchema () { - return { - type: 'object', - required: ['key'], - - properties: { - key: {type: 'string'} - } - } - } - - static get jsonAttributes() { - return ['value'] - } - - static async getConfig() { - const settings = await WIKI.db.settings.query() - if (settings.length > 0) { - return reduce(settings, (res, val, key) => { - set(res, val.key, (has(val.value, 'v')) ? val.value.v : val.value) - return res - }, {}) - } else { - return false - } - } -} diff --git a/server/models/sites.mjs b/server/models/sites.mjs deleted file mode 100644 index 97bf6d084..000000000 --- a/server/models/sites.mjs +++ /dev/null @@ -1,188 +0,0 @@ -import { Model } from 'objection' -import { defaultsDeep, keyBy } from 'lodash-es' -import { v4 as uuid } from 'uuid' - -/** - * Site model - */ -export class Site extends Model { - static get tableName () { return 'sites' } - - static get jsonSchema () { - return { - type: 'object', - required: ['hostname'], - - properties: { - id: { type: 'string' }, - hostname: { type: 'string' }, - isEnabled: { type: 'boolean', default: false } - } - } - } - - static get jsonAttributes () { - return ['config'] - } - - static async getSiteByHostname ({ hostname, forceReload = false }) { - if (forceReload) { - await WIKI.db.sites.reloadCache() - } - const siteId = WIKI.sitesMappings[hostname] || WIKI.sitesMappings['*'] - if (siteId) { - return WIKI.sites[siteId] - } - return null - } - - static async reloadCache () { - WIKI.logger.info('Reloading site configurations...') - const sites = await WIKI.db.sites.query().orderBy('id') - WIKI.sites = keyBy(sites, 'id') - WIKI.sitesMappings = {} - for (const site of sites) { - WIKI.sitesMappings[site.hostname] = site.id - } - WIKI.logger.info(`Loaded ${sites.length} site configurations [ OK ]`) - } - - static async createSite (hostname, config) { - const newSite = await WIKI.db.sites.query().insertAndFetch({ - hostname, - isEnabled: true, - config: defaultsDeep(config, { - title: 'My Wiki Site', - description: '', - company: '', - contentLicense: '', - footerExtra: '', - pageExtensions: ['md', 'html', 'txt'], - pageCasing: true, - discoverable: false, - defaults: { - tocDepth: { - min: 1, - max: 2 - } - }, - features: { - browse: true, - ratings: false, - ratingsMode: 'off', - comments: false, - contributions: false, - profile: true, - search: true - }, - logoUrl: '', - logoText: true, - sitemap: true, - robots: { - index: true, - follow: true - }, - locales: { - primary: 'en', - active: ['en'] - }, - assets: { - logo: false, - logoExt: 'svg', - favicon: false, - faviconExt: 'svg', - loginBg: false - }, - theme: { - dark: false, - codeBlocksTheme: 'github-dark', - colorPrimary: '#1976D2', - colorSecondary: '#02C39A', - colorAccent: '#FF9800', - colorHeader: '#000000', - colorSidebar: '#1976D2', - injectCSS: '', - injectHead: '', - injectBody: '', - contentWidth: 'full', - sidebarPosition: 'left', - tocPosition: 'right', - showSharingMenu: true, - showPrintBtn: true, - baseFont: 'roboto', - contentFont: 'roboto' - }, - editors: { - asciidoc: { - isActive: true, - config: {} - }, - markdown: { - isActive: true, - config: { - allowHTML: true, - kroki: false, - krokiServerUrl: 'https://kroki.io', - latexEngine: 'katex', - lineBreaks: true, - linkify: true, - multimdTable: true, - plantuml: false, - plantumlServerUrl: 'https://www.plantuml.com/plantuml/', - quotes: 'english', - tabWidth: 2, - typographer: false, - underline: true - } - }, - wysiwyg: { - isActive: true, - config: {} - } - }, - uploads: { - conflictBehavior: 'overwrite', - normalizeFilename: true - } - }) - }) - - WIKI.logger.debug(`Creating new root navigation for site ${newSite.id}`) - - await WIKI.db.navigation.query().insert({ - id: newSite.id, - siteId: newSite.id, - items: [] - }) - - WIKI.logger.debug(`Creating new DB storage for site ${newSite.id}`) - - await WIKI.db.storage.query().insert({ - module: 'db', - siteId: newSite.id, - isEnabled: true, - contentTypes: { - activeTypes: ['pages', 'images', 'documents', 'others', 'large'], - largeThreshold: '5MB' - }, - assetDelivery: { - streaming: true, - directAccess: false - }, - state: { - current: 'ok' - } - }) - - return newSite - } - - static async updateSite (id, patch) { - return WIKI.db.sites.query().findById(id).patch(patch) - } - - static async deleteSite (id) { - await WIKI.db.storage.query().delete().where('siteId', id) - return WIKI.db.sites.query().deleteById(id) - } -} diff --git a/server/models/storage.mjs b/server/models/storage.mjs deleted file mode 100644 index c1e0c442d..000000000 --- a/server/models/storage.mjs +++ /dev/null @@ -1,212 +0,0 @@ -import { Model } from 'objection' -import path from 'node:path' -import fs from 'node:fs/promises' -import { capitalize, find, has, hasIn, remove, uniq } from 'lodash-es' -import yaml from 'js-yaml' - -/** - * Storage model - */ -export class Storage extends Model { - static get tableName() { return 'storage' } - static get idColumn() { return 'id' } - - static get jsonSchema () { - return { - type: 'object', - required: ['module', 'isEnabled', 'siteId'], - - properties: { - module: {type: 'string'}, - isEnabled: {type: 'boolean'} - } - } - } - - static get jsonAttributes() { - return ['contentTypes', 'assetDelivery', 'versioning', 'schedule', 'config', 'state'] - } - - static async getTargets ({ siteId, enabledOnly = false } = {}) { - return WIKI.db.storage.query().where(builder => { - if (siteId) { - builder.where('siteId', siteId) - } - if (enabledOnly) { - builder.where('isEnabled', true) - } - }) - } - - static async refreshTargetsFromDisk () { - let trx - try { - // -> Fetch definitions from disk - const storageDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/storage')) - WIKI.storage.defs = [] - for (const dir of storageDirs) { - const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/storage', dir, 'definition.yml'), 'utf8') - const defParsed = yaml.load(def) - defParsed.key = dir - defParsed.isLoaded = false - WIKI.storage.defs.push(defParsed) - WIKI.logger.debug(`Loaded storage module definition ${dir}: [ OK ]`) - } - WIKI.logger.info(`Loaded ${WIKI.storage.defs.length} storage module definitions: [ OK ]`) - } catch (err) { - WIKI.logger.error('Failed to scan or load new storage providers: [ FAILED ]') - WIKI.logger.error(err) - if (trx) { - trx.rollback() - } - } - } - - /** - * Ensure a storage module is loaded - */ - static async ensureModule (moduleName) { - if (!has(WIKI.storage.modules, moduleName)) { - try { - WIKI.storage.modules[moduleName] = (await import(`../modules/storage/${moduleName}/storage.mjs`)).default - WIKI.logger.debug(`Activated storage module ${moduleName}: [ OK ]`) - return true - } catch (err) { - WIKI.logger.warn(`Failed to load storage module ${moduleName}: [ FAILED ]`) - WIKI.logger.warn(err) - return false - } - } else { - return true - } - } - - /** - * Initialize active storage targets - */ - static async initTargets () { - const dbTargets = await WIKI.db.storage.query().where('isEnabled', true) - const activeModules = uniq(dbTargets.map(t => t.module)) - try { - // -> Stop and delete existing jobs - // const prevjobs = remove(WIKI.scheduler.jobs, job => job.name === 'sync-storage') - // if (prevjobs.length > 0) { - // prevjobs.forEach(job => job.stop()) - // } - - // -> Load active modules - for (const md of activeModules) { - this.ensureModule(md) - } - - // -> Initialize targets - // for (const target of this.targets) { - // const targetDef = find(WIKI.data.storage, ['key', target.key]) - // target.fn = require(`../modules/storage/${target.key}/storage`) - // target.fn.config = target.config - // target.fn.mode = target.mode - // try { - // await target.fn.init() - - // // -> Save succeeded init state - // await WIKI.db.storage.query().patch({ - // state: { - // status: 'operational', - // message: '', - // lastAttempt: new Date().toISOString() - // } - // }).where('key', target.key) - - // // -> Set recurring sync job - // if (targetDef.schedule && target.syncInterval !== 'P0D') { - // WIKI.scheduler.registerJob({ - // name: 'sync-storage', - // immediate: false, - // schedule: target.syncInterval, - // repeat: true - // }, target.key) - // } - - // // -> Set internal recurring sync job - // if (targetDef.internalSchedule && targetDef.internalSchedule !== 'P0D') { - // WIKI.scheduler.registerJob({ - // name: 'sync-storage', - // immediate: false, - // schedule: target.internalSchedule, - // repeat: true - // }, target.key) - // } - // } catch (err) { - // // -> Save initialization error - // await WIKI.db.storage.query().patch({ - // state: { - // status: 'error', - // message: err.message, - // lastAttempt: new Date().toISOString() - // } - // }).where('key', target.key) - // } - // } - } catch (err) { - WIKI.logger.warn(err) - throw err - } - } - - static async pageEvent({ event, page }) { - try { - for (let target of this.targets) { - await target.fn[event](page) - } - } catch (err) { - WIKI.logger.warn(err) - throw err - } - } - - static async assetEvent({ event, asset }) { - try { - for (let target of this.targets) { - await target.fn[`asset${capitalize(event)}`](asset) - } - } catch (err) { - WIKI.logger.warn(err) - throw err - } - } - - static async getLocalLocations({ asset }) { - const locations = [] - const promises = this.targets.map(async (target) => { - try { - const path = await target.fn.getLocalLocation(asset) - locations.push({ - path, - key: target.key - }) - } catch (err) { - WIKI.logger.warn(err) - } - }) - await Promise.all(promises) - return locations - } - - static async executeAction(targetKey, handler) { - try { - const target = find(this.targets, ['key', targetKey]) - if (target) { - if (hasIn(target.fn, handler)) { - await target.fn[handler]() - } else { - throw new Error('Invalid Handler for Storage Target') - } - } else { - throw new Error('Invalid or Inactive Storage Target') - } - } catch (err) { - WIKI.logger.warn(err) - throw err - } - } -} diff --git a/server/models/tags.mjs b/server/models/tags.mjs deleted file mode 100644 index 089adfacf..000000000 --- a/server/models/tags.mjs +++ /dev/null @@ -1,59 +0,0 @@ -import { Model } from 'objection' -import { difference, some, uniq } from 'lodash-es' - -const allowedCharsRgx = /^[a-z0-9-\u3400-\u4DBF\u4E00-\u9FFF]+$/ - -/** - * Tags model - */ -export class Tag extends Model { - static get tableName() { return 'tags' } - - static get jsonSchema () { - return { - type: 'object', - required: ['tag'], - - properties: { - id: {type: 'string'}, - tag: {type: 'string'}, - - createdAt: {type: 'string'}, - updatedAt: {type: 'string'} - } - } - } - - $beforeUpdate() { - this.updatedAt = new Date().toISOString() - } - $beforeInsert() { - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } - - static async processNewTags (tags, siteId) { - // Validate tags - - const normalizedTags = uniq(tags.map(t => t.trim().toLowerCase().replaceAll('#', '')).filter(t => t)) - - for (const tag of normalizedTags) { - if (!allowedCharsRgx.test(tag)) { - throw new Error(`Tag #${tag} has invalid characters. Must consists of letters (no diacritics), numbers, CJK logograms and dashes only.`) - } - } - - // Fetch existing tags - - const existingTags = await WIKI.db.knex('tags').column('tag').where('siteId', siteId).pluck('tag') - - // Create missing tags - - const newTags = difference(normalizedTags, existingTags).map(t => ({ tag: t, usageCount: 1, siteId })) - if (newTags.length > 0) { - await WIKI.db.tags.query().insert(newTags) - } - - return normalizedTags - } -} diff --git a/server/models/tree.mjs b/server/models/tree.mjs deleted file mode 100644 index 8d107fd5c..000000000 --- a/server/models/tree.mjs +++ /dev/null @@ -1,461 +0,0 @@ -import { Model } from 'objection' -import { differenceWith, dropRight, last, nth } from 'lodash-es' -import { - decodeTreePath, - encodeTreePath, - generateHash -} from '../helpers/common.mjs' - -import { Site } from './sites.mjs' - -const rePathName = /^[a-z0-9-]+$/ -const reTitle = /^[^<>"]+$/ - -/** - * Tree model - */ -export class Tree extends Model { - static get tableName () { return 'tree' } - - static get jsonSchema () { - return { - type: 'object', - required: ['fileName'], - - properties: { - id: { type: 'string' }, - folderPath: { type: 'string' }, - fileName: { type: 'string' }, - type: { type: 'string' }, - title: { type: 'string' }, - createdAt: { type: 'string' }, - updatedAt: { type: 'string' } - } - } - } - - static get jsonAttributes () { - return ['meta'] - } - - static get relationMappings () { - return { - site: { - relation: Model.BelongsToOneRelation, - modelClass: Site, - join: { - from: 'tree.siteId', - to: 'sites.id' - } - } - } - } - - $beforeUpdate () { - this.updatedAt = new Date().toISOString() - } - - $beforeInsert () { - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } - - /** - * Get a Folder - * - * @param {Object} args - Fetch Properties - * @param {string} [args.id] - UUID of the folder - * @param {string} [args.path] - Path of the folder - * @param {string} [args.locale] - Locale code of the folder (when using path) - * @param {string} [args.siteId] - UUID of the site in which the folder is (when using path) - * @param {boolean} [args.createIfMissing] - Create the folder and its ancestor if it's missing (when using path) - */ - static async getFolder ({ id, path, locale, siteId, createIfMissing = false }) { - // Get by ID - if (id) { - const parent = await WIKI.db.knex('tree').where('id', id).first() - if (!parent) { - throw new Error('ERR_INVALID_FOLDER') - } - return parent - } else { - // Get by path - const parentPath = encodeTreePath(path) - const parentPathParts = parentPath.split('.') - const parentFilter = { - folderPath: dropRight(parentPathParts).join('.'), - fileName: last(parentPathParts) - } - const parent = await WIKI.db.knex('tree').where({ - ...parentFilter, - type: 'folder', - locale, - siteId - }).first() - if (parent) { - return parent - } else if (createIfMissing) { - return WIKI.db.tree.createFolder({ - parentPath: parentFilter.folderPath, - pathName: parentFilter.fileName, - title: parentFilter.fileName, - locale, - siteId - }) - } else { - throw new Error('ERR_INVALID_FOLDER') - } - } - } - - /** - * Add Page Entry - * - * @param {Object} args - New Page Properties - * @param {string} [args.parentId] - UUID of the parent folder - * @param {string} [args.parentPath] - Path of the parent folder - * @param {string} args.pathName - Path name of the page to add - * @param {string} args.title - Title of the page to add - * @param {string} args.locale - Locale code of the page to add - * @param {string} args.siteId - UUID of the site in which the page will be added - * @param {string[]} [args.tags] - Tags of the assets - * @param {Object} [args.meta] - Extra metadata - */ - static async addPage ({ id, parentId, parentPath, fileName, title, locale, siteId, tags = [], meta = {} }) { - const folder = (parentId || parentPath) - ? await WIKI.db.tree.getFolder({ - id: parentId, - path: parentPath, - locale, - siteId, - createIfMissing: true - }) - : { - folderPath: '', - fileName: '' - } - const folderPath = folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName - const fullPath = folderPath ? `${folderPath}/${fileName}` : fileName - - WIKI.logger.debug(`Adding page ${fullPath} to tree...`) - - const pageEntry = await WIKI.db.knex('tree').insert({ - id, - folderPath, - fileName, - type: 'page', - title, - hash: generateHash(fullPath), - locale, - siteId, - tags, - meta, - navigationId: siteId - }).returning('*') - - return pageEntry[0] - } - - /** - * Add Asset Entry - * - * @param {Object} args - New Asset Properties - * @param {string} [args.parentId] - UUID of the parent folder - * @param {string} [args.parentPath] - Path of the parent folder - * @param {string} args.pathName - Path name of the asset to add - * @param {string} args.title - Title of the asset to add - * @param {string} args.locale - Locale code of the asset to add - * @param {string} args.siteId - UUID of the site in which the asset will be added - * @param {string[]} [args.tags] - Tags of the assets - * @param {Object} [args.meta] - Extra metadata - */ - static async addAsset ({ id, parentId, parentPath, fileName, title, locale, siteId, tags = [], meta = {} }) { - const folder = (parentId || parentPath) - ? await WIKI.db.tree.getFolder({ - id: parentId, - path: parentPath, - locale, - siteId, - createIfMissing: true - }) - : { - folderPath: '', - fileName: '' - } - const folderPath = folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName - const fullPath = folderPath ? `${folderPath}/${fileName}` : fileName - - WIKI.logger.debug(`Adding asset ${fullPath} to tree...`) - - const assetEntry = await WIKI.db.knex('tree').insert({ - id, - folderPath, - fileName, - type: 'asset', - title, - hash: generateHash(fullPath), - locale, - siteId, - tags, - meta - }).returning('*') - - return assetEntry[0] - } - - /** - * Create New Folder - * - * @param {Object} args - New Folder Properties - * @param {string} [args.parentId] - UUID of the parent folder - * @param {string} [args.parentPath] - Path of the parent folder - * @param {string} args.pathName - Path name of the folder to create - * @param {string} args.title - Title of the folder to create - * @param {string} args.locale - Locale code of the folder to create - * @param {string} args.siteId - UUID of the site in which the folder will be created - */ - static async createFolder ({ parentId, parentPath, pathName, title, locale, siteId }) { - // Validate path name - if (!rePathName.test(pathName)) { - throw new Error('ERR_INVALID_PATH') - } - - // Validate title - if (!reTitle.test(title)) { - throw new Error('ERR_FOLDER_TITLE_INVALID') - } - - parentPath = encodeTreePath(parentPath) - WIKI.logger.debug(`Creating new folder ${pathName}...`) - const parentPathParts = parentPath.split('.') - const parentFilter = { - folderPath: dropRight(parentPathParts).join('.'), - fileName: last(parentPathParts) - } - - // Get parent path - let parent = null - if (parentId) { - parent = await WIKI.db.knex('tree').where('id', parentId).first() - if (!parent) { - throw new Error('ERR_FOLDER_PARENT_INVALID') - } - parentPath = parent.folderPath ? `${parent.folderPath}.${parent.fileName}` : parent.fileName - } else if (parentPath) { - parent = await WIKI.db.knex('tree').where(parentFilter).first() - } else { - parentPath = '' - } - - // Check for collision - const existingFolder = await WIKI.db.knex('tree').select('id').where({ - siteId, - locale, - folderPath: parentPath, - fileName: pathName, - type: 'folder' - }).first() - if (existingFolder) { - throw new Error('ERR_FOLDER_DUPLICATE') - } - - // Ensure all ancestors exist - if (parentPath) { - const expectedAncestors = [] - const existingAncestors = await WIKI.db.knex('tree').select('folderPath', 'fileName').where(builder => { - const parentPathParts = parentPath.split('.') - for (let i = 1; i <= parentPathParts.length; i++) { - const ancestor = { - folderPath: dropRight(parentPathParts, i).join('.'), - fileName: nth(parentPathParts, i * -1) - } - expectedAncestors.push(ancestor) - builder.orWhere({ - ...ancestor, - type: 'folder' - }) - } - }) - for (const ancestor of differenceWith(expectedAncestors, existingAncestors, (expAnc, exsAnc) => expAnc.folderPath === exsAnc.folderPath && expAnc.fileName === exsAnc.fileName)) { - WIKI.logger.debug(`Creating missing parent folder ${ancestor.fileName} at path /${ancestor.folderPath}...`) - const newAncestorFullPath = ancestor.folderPath ? `${decodeTreePath(ancestor.folderPath)}/${ancestor.fileName}` : ancestor.fileName - const newAncestor = await WIKI.db.knex('tree').insert({ - ...ancestor, - type: 'folder', - title: ancestor.fileName, - hash: generateHash(newAncestorFullPath), - locale, - siteId, - meta: { - children: 1 - } - }).returning('*') - - // Parent didn't exist until now, assign it - if (!parent && ancestor.folderPath === parentFilter.folderPath && ancestor.fileName === parentFilter.fileName) { - parent = newAncestor[0] - } - } - } - - // Create folder - const fullPath = parentPath ? `${decodeTreePath(parentPath)}/${pathName}` : pathName - const folder = await WIKI.db.knex('tree').insert({ - folderPath: parentPath, - fileName: pathName, - type: 'folder', - title, - hash: generateHash(fullPath), - locale, - siteId, - meta: { - children: 0 - } - }).returning('*') - - // Update parent ancestor count - if (parent) { - await WIKI.db.knex('tree').where('id', parent.id).update({ - meta: { - ...(parent.meta ?? {}), - children: (parent.meta?.children || 0) + 1 - } - }) - } - - WIKI.logger.debug(`Created folder ${folder[0].id} successfully.`) - - return folder[0] - } - - /** - * Rename a folder - * - * @param {Object} args - Rename Folder Properties - * @param {string} args.folderId - UUID of the folder to rename - * @param {string} args.pathName - New path name of the folder - * @param {string} args.title - New title of the folder - */ - static async renameFolder ({ folderId, pathName, title }) { - // Get folder - const folder = await WIKI.db.knex('tree').where('id', folderId).first() - if (!folder) { - throw new Error('ERR_INVALID_FOLDER') - } - - // Validate path name - if (!rePathName.test(pathName)) { - throw new Error('ERR_INVALID_PATH') - } - - // Validate title - if (!reTitle.test(title)) { - throw new Error('ERR_FOLDER_TITLE_INVALID') - } - - WIKI.logger.debug(`Renaming folder ${folder.id} path to ${pathName}...`) - - if (pathName !== folder.fileName) { - // Check for collision - const existingFolder = await WIKI.db.knex('tree') - .whereNot('id', folder.id) - .andWhere({ - siteId: folder.siteId, - folderPath: folder.folderPath, - fileName: pathName, - type: 'folder' - }).first() - if (existingFolder) { - throw new Error('ERR_FOLDER_DUPLICATE') - } - - // Build new paths - const oldFolderPath = folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName - const newFolderPath = folder.folderPath ? `${folder.folderPath}.${pathName}` : pathName - - // Update children nodes - WIKI.logger.debug(`Updating parent path of children nodes from ${oldFolderPath} to ${newFolderPath} ...`) - await WIKI.db.knex('tree').where('siteId', folder.siteId).andWhere('folderPath', oldFolderPath).update({ - folderPath: newFolderPath - }) - await WIKI.db.knex('tree').where('siteId', folder.siteId).andWhere('folderPath', '<@', oldFolderPath).update({ - folderPath: WIKI.db.knex.raw(`'${newFolderPath}' || subpath(tree."folderPath", nlevel('${newFolderPath}'))`) - }) - - // Rename the folder itself - const fullPath = folder.folderPath ? `${folder.folderPath}/${pathName}` : pathName - await WIKI.db.knex('tree').where('id', folder.id).update({ - fileName: pathName, - title, - hash: generateHash(fullPath) - }) - } else { - // Update the folder title only - await WIKI.db.knex('tree').where('id', folder.id).update({ - title - }) - } - - WIKI.logger.debug(`Renamed folder ${folder.id} successfully.`) - } - - /** - * Delete a folder - * - * @param {String} folderId Folder ID - */ - static async deleteFolder (folderId) { - // Get folder - const folder = await WIKI.db.knex('tree').where('id', folderId).first() - if (!folder) { - throw new Error('ERR_INVALID_FOLDER') - } - const folderPath = folder.folderPath ? `${folder.folderPath}.${folder.fileName}` : folder.fileName - WIKI.logger.debug(`Deleting folder ${folder.id} at path ${folderPath}...`) - - // Delete all children - const deletedNodes = await WIKI.db.knex('tree').where('folderPath', '<@', folderPath).del().returning(['id', 'type']) - - // Delete folders - const deletedFolders = deletedNodes.filter(n => n.type === 'folder').map(n => n.id) - if (deletedFolders.length > 0) { - WIKI.logger.debug(`Deleted ${deletedFolders.length} children folders.`) - } - - // Delete pages - const deletedPages = deletedNodes.filter(n => n.type === 'page').map(n => n.id) - if (deletedPages.length > 0) { - WIKI.logger.debug(`Deleting ${deletedPages.length} children pages...`) - - // TODO: Delete page - } - - // Delete assets - const deletedAssets = deletedNodes.filter(n => n.type === 'asset').map(n => n.id) - if (deletedAssets.length > 0) { - WIKI.logger.debug(`Deleting ${deletedPages.length} children assets...`) - - // TODO: Delete asset - } - - // Delete the folder itself - await WIKI.db.knex('tree').where('id', folder.id).del() - - // Update parent children count - if (folder.folderPath) { - const parentPathParts = folder.folderPath.split('.') - const parent = await WIKI.db.knex('tree').where({ - folderPath: dropRight(parentPathParts).join('.'), - fileName: last(parentPathParts) - }).first() - await WIKI.db.knex('tree').where('id', parent.id).update({ - meta: { - ...(parent.meta ?? {}), - children: (parent.meta?.children || 1) - 1 - } - }) - } - - WIKI.logger.debug(`Deleted folder ${folder.id} successfully.`) - } -} diff --git a/server/models/userKeys.mjs b/server/models/userKeys.mjs deleted file mode 100644 index 262e482f0..000000000 --- a/server/models/userKeys.mjs +++ /dev/null @@ -1,83 +0,0 @@ -/* global WIKI */ - -import { Model } from 'objection' -import { DateTime } from 'luxon' -import { nanoid } from 'nanoid' - -import { User } from './users.mjs' - -/** - * Users model - */ -export class UserKey extends Model { - static get tableName() { return 'userKeys' } - - static get jsonSchema () { - return { - type: 'object', - required: ['kind', 'token', 'validUntil'], - - properties: { - id: {type: 'string'}, - kind: {type: 'string'}, - token: {type: 'string'}, - createdAt: {type: 'string'}, - validUntil: {type: 'string'} - } - } - } - - static get relationMappings() { - return { - user: { - relation: Model.BelongsToOneRelation, - modelClass: User, - join: { - from: 'userKeys.userId', - to: 'users.id' - } - } - } - } - - async $beforeInsert(context) { - await super.$beforeInsert(context) - - this.createdAt = DateTime.utc().toISO() - } - - static async generateToken ({ userId, kind, meta }, context) { - WIKI.logger.debug(`Generating ${kind} token for user ${userId}...`) - const token = await nanoid() - await WIKI.db.userKeys.query().insert({ - kind, - token, - meta, - validUntil: DateTime.utc().plus({ days: 1 }).toISO(), - userId - }) - return token - } - - static async validateToken ({ kind, token, skipDelete }, context) { - const res = await WIKI.db.userKeys.query().findOne({ kind, token }).withGraphJoined('user') - if (res) { - if (skipDelete !== true) { - await WIKI.db.userKeys.query().deleteById(res.id) - } - if (DateTime.utc() > DateTime.fromISO(res.validUntil)) { - throw new Error('ERR_EXPIRED_VALIDATION_TOKEN') - } - return { - ...res.meta, - user: res.user - } - } else { - throw new Error('ERR_INVALID_VALIDATION_TOKEN') - } - } - - static async destroyToken ({ token }) { - return WIKI.db.userKeys.query().findOne({ token }).delete() - } -} diff --git a/server/models/users.mjs b/server/models/users.mjs deleted file mode 100644 index f405290f7..000000000 --- a/server/models/users.mjs +++ /dev/null @@ -1,903 +0,0 @@ -/* global WIKI */ - -import { difference, find, first, flatten, flattenDeep, get, has, isArray, isEmpty, isNil, isString, last, set, toString, truncate, uniq } from 'lodash-es' -import tfa from 'node-2fa' -import jwt from 'jsonwebtoken' -import { Model } from 'objection' -import validate from 'validate.js' -import qr from 'qr-image' -import bcrypt from 'bcryptjs' - -import { Group } from './groups.mjs' - -/** - * Users model - */ -export class User extends Model { - static get tableName() { return 'users' } - - static get jsonSchema () { - return { - type: 'object', - required: ['email'], - - properties: { - id: {type: 'string'}, - email: {type: 'string'}, - name: {type: 'string', minLength: 1, maxLength: 255}, - pictureUrl: {type: 'string'}, - isSystem: {type: 'boolean'}, - isActive: {type: 'boolean'}, - isVerified: {type: 'boolean'}, - createdAt: {type: 'string'}, - updatedAt: {type: 'string'} - } - } - } - - static get jsonAttributes() { - return ['auth', 'meta', 'prefs'] - } - - static get relationMappings() { - return { - groups: { - relation: Model.ManyToManyRelation, - modelClass: Group, - join: { - from: 'users.id', - through: { - from: 'userGroups.userId', - to: 'userGroups.groupId' - }, - to: 'groups.id' - } - } - } - } - - async $beforeUpdate(opt, context) { - await super.$beforeUpdate(opt, context) - - this.updatedAt = new Date().toISOString() - } - async $beforeInsert(context) { - await super.$beforeInsert(context) - - this.createdAt = new Date().toISOString() - this.updatedAt = new Date().toISOString() - } - - // ------------------------------------------------ - // Instance Methods - // ------------------------------------------------ - - async generateTFA(strategyId, siteId) { - WIKI.logger.debug(`Generating new TFA secret for user ${this.id}...`) - const site = WIKI.sites[siteId] ?? WIKI.sites[0] ?? { config: { title: 'Wiki' } } - const tfaInfo = tfa.generateSecret({ - name: site.config.title, - account: this.email - }) - this.auth[strategyId].tfaSecret = tfaInfo.secret - this.auth[strategyId].tfaIsActive = false - await this.$query().patch({ - auth: this.auth - }) - const safeTitle = site.config.title.replace(/[\s-.,=!@#$%?&*()+[\]{}/\\;<>]/g, '') - return qr.imageSync(`otpauth://totp/${safeTitle}:${this.email}?secret=${tfaInfo.secret}`, { type: 'svg' }) - } - - async enableTFA(strategyId) { - this.auth[strategyId].tfaIsActive = true - return this.$query().patch({ - auth: this.auth - }) - } - - async disableTFA(strategyId) { - this.auth[strategyId].tfaIsActive = false - return this.$query().patch({ - tfaIsActive: false, - tfaSecret: '' - }) - } - - verifyTFA(strategyId, code) { - return tfa.verifyToken(this.auth[strategyId].tfaSecret, code)?.delta === 0 - } - - getPermissions () { - return uniq(flatten(this.groups.map(g => g.permissions))) - } - - getGroups() { - return uniq(this.groups.map(g => g.id)) - } - - // ------------------------------------------------ - // Model Methods - // ------------------------------------------------ - - static async getById(id) { - return WIKI.db.users.query().findById(id).withGraphFetched('groups').modifyGraph('groups', builder => { - builder.select('groups.id', 'permissions') - }) - } - - static async processProfile({ profile, providerKey }) { - const provider = get(WIKI.auth.strategies, providerKey, {}) - provider.info = find(WIKI.data.authentication, ['key', provider.stategyKey]) - - // Find existing user - let user = await WIKI.db.users.query().findOne({ - providerId: toString(profile.id), - providerKey - }) - - // Parse email - let primaryEmail = '' - if (isArray(profile.emails)) { - const e = find(profile.emails, ['primary', true]) - primaryEmail = (e) ? e.value : first(profile.emails).value - } else if (isArray(profile.email)) { - primaryEmail = first(flattenDeep([profile.email])) - } else if (isString(profile.email) && profile.email.length > 5) { - primaryEmail = profile.email - } else if (isString(profile.mail) && profile.mail.length > 5) { - primaryEmail = profile.mail - } else if (profile.user && profile.user.email && profile.user.email.length > 5) { - primaryEmail = profile.user.email - } else { - throw new Error('Missing or invalid email address from profile.') - } - primaryEmail = primaryEmail.toLowerCase() - - // Find pending social user - if (!user) { - user = await WIKI.db.users.query().findOne({ - email: primaryEmail, - providerId: null, - providerKey - }) - if (user) { - user = await user.$query().patchAndFetch({ - providerId: toString(profile.id) - }) - } - } - - // Parse display name - let displayName = '' - if (isString(profile.displayName) && profile.displayName.length > 0) { - displayName = profile.displayName - } else if (isString(profile.name) && profile.name.length > 0) { - displayName = profile.name - } else { - displayName = primaryEmail.split('@')[0] - } - - // Parse picture URL / Data - let pictureUrl = '' - if (profile.picture && Buffer.isBuffer(profile.picture)) { - pictureUrl = 'internal' - } else { - pictureUrl = truncate(get(profile, 'picture', get(user, 'pictureUrl', null)), { - length: 255, - omission: '' - }) - } - - // Update existing user - if (user) { - if (!user.isActive) { - throw new WIKI.Error.AuthAccountBanned() - } - if (user.isSystem) { - throw new Error('This is a system reserved account and cannot be used.') - } - - user = await user.$query().patchAndFetch({ - email: primaryEmail, - name: displayName, - pictureUrl: pictureUrl - }) - - if (pictureUrl === 'internal') { - await WIKI.db.users.updateUserAvatarData(user.id, profile.picture) - } - - return user - } - - // Self-registration - if (provider.selfRegistration) { - // Check if email domain is whitelisted - if (get(provider, 'domainWhitelist', []).length > 0) { - const emailDomain = last(primaryEmail.split('@')) - if (!provider.domainWhitelist.includes(emailDomain)) { - throw new WIKI.Error.AuthRegistrationDomainUnauthorized() - } - } - - // Create account - user = await WIKI.db.users.query().insertAndFetch({ - providerKey: providerKey, - providerId: toString(profile.id), - email: primaryEmail, - name: displayName, - pictureUrl: pictureUrl, - locale: WIKI.config.lang.code, - defaultEditor: 'markdown', - tfaIsActive: false, - isSystem: false, - isActive: true, - isVerified: true - }) - - // Assign to group(s) - if (provider.autoEnrollGroups.length > 0) { - await user.$relatedQuery('groups').relate(provider.autoEnrollGroups) - } - - if (pictureUrl === 'internal') { - await WIKI.db.users.updateUserAvatarData(user.id, profile.picture) - } - - return user - } - - throw new Error('You are not authorized to login.') - } - - /** - * Login a user - */ - static async login ({ strategyId, siteId, username, password }, context) { - if (has(WIKI.auth.strategies, strategyId)) { - const selStrategy = WIKI.auth.strategies[strategyId] - if (!selStrategy.isEnabled) { - throw new WIKI.Error.AuthProviderInvalid() - } - - const strInfo = find(WIKI.data.authentication, ['key', selStrategy.module]) - - // Inject form user/pass - if (strInfo.useForm) { - set(context.req, 'body.email', username) - set(context.req, 'body.password', password) - set(context.req.params, 'strategy', strategyId) - } - - // Authenticate - return new Promise((resolve, reject) => { - WIKI.auth.passport.authenticate(selStrategy.id, { - session: !strInfo.useForm, - scope: strInfo.scopes ? strInfo.scopes : null - }, async (err, user, info) => { - if (err) { return reject(err) } - if (!user) { return reject(new WIKI.Error.AuthLoginFailed()) } - - try { - const resp = await WIKI.db.users.afterLoginChecks(user, selStrategy.id, context, { - siteId, - skipTFA: !strInfo.useForm, - skipChangePwd: !strInfo.useForm - }) - resolve(resp) - } catch (err) { - reject(err) - } - })(context.req, context.res, () => {}) - }) - } else { - throw new WIKI.Error.AuthProviderInvalid() - } - } - - /** - * Perform post-login checks - */ - static async afterLoginChecks (user, strategyId, context, { siteId, skipTFA, skipChangePwd } = { skipTFA: false, skipChangePwd: false, siteId: null }) { - const str = WIKI.auth.strategies[strategyId] - if (!str) { - throw new Error('ERR_INVALID_STRATEGY') - } - - // Get redirect target - user.groups = await user.$relatedQuery('groups').select('groups.id', 'permissions', 'redirectOnLogin') - let redirect = '/' - if (user.groups && user.groups.length > 0) { - for (const grp of user.groups) { - if (!isEmpty(grp.redirectOnLogin) && grp.redirectOnLogin !== '/') { - redirect = grp.redirectOnLogin - break - } - } - } - - // Get auth strategy flags - const authStr = user.auth[strategyId] || {} - - // Is 2FA required? - if (!skipTFA) { - if (authStr.tfaIsActive && authStr.tfaSecret) { - try { - const tfaToken = await WIKI.db.userKeys.generateToken({ - kind: 'tfa', - userId: user.id, - meta: { - strategyId - } - }) - return { - nextAction: 'provideTfa', - continuationToken: tfaToken, - redirect - } - } catch (errc) { - WIKI.logger.warn(errc) - throw new WIKI.Error.AuthGenericError() - } - } else if (str.config?.enforceTfa || authStr.tfaRequired) { - try { - const tfaQRImage = await user.generateTFA(strategyId, siteId) - const tfaToken = await WIKI.db.userKeys.generateToken({ - kind: 'tfaSetup', - userId: user.id, - meta: { - strategyId - } - }) - return { - nextAction: 'setupTfa', - continuationToken: tfaToken, - tfaQRImage, - redirect - } - } catch (errc) { - WIKI.logger.warn(errc) - throw new WIKI.Error.AuthGenericError() - } - } - } - - // Must Change Password? - if (!skipChangePwd && authStr.mustChangePwd) { - try { - const pwdChangeToken = await WIKI.db.userKeys.generateToken({ - kind: 'changePwd', - userId: user.id, - meta: { - strategyId - } - }) - - return { - nextAction: 'changePassword', - continuationToken: pwdChangeToken, - redirect - } - } catch (errc) { - WIKI.logger.warn(errc) - throw new WIKI.Error.AuthGenericError() - } - } - - return new Promise((resolve, reject) => { - context.req.login(user, { session: false }, async errc => { - if (errc) { return reject(errc) } - const jwtToken = await WIKI.db.users.refreshToken(user, strategyId) - resolve({ - nextAction: 'redirect', - jwt: jwtToken.token, - redirect - }) - }) - }) - } - - /** - * Generate a new token for a user - */ - static async refreshToken (user) { - if (isString(user)) { - user = await WIKI.db.users.query().findById(user).withGraphFetched('groups').modifyGraph('groups', builder => { - builder.select('groups.id', 'permissions') - }) - if (!user) { - WIKI.logger.warn(`Failed to refresh token for user ${user}: Not found.`) - throw new WIKI.Error.AuthGenericError() - } - if (!user.isActive) { - WIKI.logger.warn(`Failed to refresh token for user ${user}: Inactive.`) - throw new WIKI.Error.AuthAccountBanned() - } - } else if (isNil(user.groups)) { - user.groups = await user.$relatedQuery('groups').select('groups.id', 'permissions') - } - - // Update Last Login Date - // -> Bypass Objection.js to avoid updating the updatedAt field - await WIKI.db.knex('users').where('id', user.id).update({ lastLoginAt: new Date().toISOString() }) - - return { - token: jwt.sign({ - id: user.id, - email: user.email, - groups: user.getGroups() - }, { - key: WIKI.config.auth.certs.private, - passphrase: WIKI.config.auth.secret - }, { - algorithm: 'RS256', - expiresIn: WIKI.config.auth.tokenExpiration, - audience: WIKI.config.auth.audience, - issuer: 'urn:wiki.js' - }), - user - } - } - - /** - * Verify a TFA login - */ - static async loginTFA ({ strategyId, siteId, securityCode, continuationToken, setup }, context) { - if (securityCode.length === 6 && continuationToken.length > 1) { - const { user, strategyId: expectedStrategyId } = await WIKI.db.userKeys.validateToken({ - kind: setup ? 'tfaSetup' : 'tfa', - token: continuationToken, - skipDelete: setup - }) - - if (strategyId !== expectedStrategyId) { - throw new Error('ERR_INVALID_STRATEGY') - } - - if (user) { - if (user.verifyTFA(strategyId, securityCode)) { - if (setup) { - await user.enableTFA(strategyId) - } - return WIKI.db.users.afterLoginChecks(user, strategyId, context, { siteId, skipTFA: true }) - } else { - throw new Error('ERR_TFA_INCORRECT_TOKEN') - } - } - } - throw new Error('ERR_TFA_INVALID_REQUEST') - } - - /** - * Change Password from a Mandatory Password Change after Login - */ - static async loginChangePassword ({ strategyId, siteId, continuationToken, newPassword }, context) { - if (!newPassword || newPassword.length < 8) { - throw new Error('ERR_PASSWORD_TOO_SHORT') - } - const { user, strategyId: expectedStrategyId } = await WIKI.db.userKeys.validateToken({ - kind: 'changePwd', - token: continuationToken - }) - - if (strategyId !== expectedStrategyId) { - throw new Error('ERR_INVALID_STRATEGY') - } - - if (user) { - user.auth[strategyId].password = await bcrypt.hash(newPassword, 12) - user.auth[strategyId].mustChangePwd = false - await user.$query().patch({ - auth: user.auth - }) - - return WIKI.db.users.afterLoginChecks(user, strategyId, context, { siteId, skipChangePwd: true, skipTFA: true }) - } else { - throw new Error('ERR_INVALID_USER') - } - } - - /** - * Change Password from Profile - */ - static async changePassword ({ strategyId, siteId, currentPassword, newPassword }, context) { - const userId = context.req.user?.id - if (!userId) { - throw new Error('ERR_NOT_AUTHENTICATED') - } - - const user = await WIKI.db.users.query().findById(userId) - if (!user) { - throw new Error('ERR_INVALID_USER') - } - - if (!newPassword || newPassword.length < 8) { - throw new Error('ERR_PASSWORD_TOO_SHORT') - } - - if (!user.auth[strategyId]?.password) { - throw new Error('ERR_INVALID_STRATEGY') - } - - if (await bcrypt.compare(currentPassword, user.auth[strategyId].password) !== true) { - throw new Error('ERR_INCORRECT_CURRENT_PASSWORD') - } - - user.auth[strategyId].password = await bcrypt.hash(newPassword, 12) - user.auth[strategyId].mustChangePwd = false - - await user.$query().patch({ - auth: user.auth - }) - - return true - } - - /** - * Send a password reset request - */ - static async loginForgotPassword ({ email }, context) { - const usr = await WIKI.db.users.query().where({ - email, - providerKey: 'local' - }).first() - if (!usr) { - WIKI.logger.debug(`Password reset attempt on nonexistant local account ${email}: [DISCARDED]`) - return - } - const resetToken = await WIKI.db.userKeys.generateToken({ - userId: usr.id, - kind: 'resetPwd' - }) - - await WIKI.mail.send({ - template: 'accountResetPwd', - to: email, - subject: `Password Reset Request`, - data: { - preheadertext: `A password reset was requested for ${WIKI.config.title}`, - title: `A password reset was requested for ${WIKI.config.title}`, - content: `Click the button below to reset your password. If you didn't request this password reset, simply discard this email.`, - buttonLink: `${WIKI.config.host}/login-reset/${resetToken}`, - buttonText: 'Reset Password' - }, - text: `A password reset was requested for wiki ${WIKI.config.title}. Open the following link to proceed: ${WIKI.config.host}/login-reset/${resetToken}` - }) - } - - /** - * Create a new user - * - * @param {Object} param0 User Fields - */ - static async createNewUser ({ email, password, name, groups, userInitiated = false, mustChangePassword = false, sendWelcomeEmail = false, sendWelcomeEmailFromSiteId }) { - const localAuth = await WIKI.db.authentication.getStrategy('local') - - // Check if self-registration is enabled - if (userInitiated && !localAuth.registration) { - throw new Error('ERR_REGISTRATION_DISABLED') - } - - // Input sanitization - email = email.toLowerCase().trim() - - // Input validation - const validation = validate({ - email, - password, - name - }, { - email: { - email: true, - length: { - maximum: 255 - } - }, - password: { - presence: { - allowEmpty: false - }, - length: { - minimum: 6 - } - }, - name: { - presence: { - allowEmpty: false - }, - length: { - minimum: 2, - maximum: 255 - } - } - }, { format: 'flat' }) - - if (validation && validation.length > 0) { - throw new Error(`ERR_INVALID_INPUT: ${validation[0]}`) - } - - // Check if email address is allowed - if (userInitiated && localAuth.allowedEmailRegex) { - const emailCheckRgx = new RegExp(localAuth.allowedEmailRegex, 'i') - if (!emailCheckRgx.test(email)) { - throw new Error('ERR_EMAIL_ADDRESS_NOT_ALLOWED') - } - } - - // Check if email already exists - const usr = await WIKI.db.users.query().findOne({ email }) - if (usr) { - throw new Error('ERR_DUPLICATE_ACCOUNT_EMAIL') - } - - // Check if site ID is provided when send welcome email is enabled - if (sendWelcomeEmail && !sendWelcomeEmailFromSiteId) { - throw new Error('ERR_INVALID_SITE') - } - - WIKI.logger.debug(`Creating new user account for ${email}...`) - - // Create the account - const newUsr = await WIKI.db.users.query().insert({ - email, - name, - auth: { - [localAuth.id]: { - password: await bcrypt.hash(password, 12), - mustChangePwd: mustChangePassword, - restrictLogin: false, - tfaRequired: false, - tfaSecret: '' - } - }, - hasAvatar: false, - isSystem: false, - isActive: true, - isVerified: true, - meta: { - jobTitle: '', - location: '', - pronouns: '' - }, - prefs: { - cvd: 'none', - timezone: WIKI.config.userDefaults.timezone || 'America/New_York', - appearance: 'site', - dateFormat: WIKI.config.userDefaults.dateFormat || 'YYYY-MM-DD', - timeFormat: WIKI.config.userDefaults.timeFormat || '12h' - } - }).returning('*') - - // Assign to group(s) - const groupsToEnroll = [WIKI.data.systemIds.usersGroupId] - if (groups?.length > 0) { - groupsToEnroll.push(...groups) - } - if (userInitiated && localAuth.autoEnrollGroups?.length > 0) { - groupsToEnroll.push(...localAuth.autoEnrollGroups) - } - await newUsr.$relatedQuery('groups').relate(uniq(groupsToEnroll)) - - // Verification Email - if (userInitiated && localAuth.config?.emailValidation) { - // Create verification token - const verificationToken = await WIKI.db.userKeys.generateToken({ - kind: 'verify', - userId: newUsr.id - }) - - // TODO: Handle multilingual text - // Send verification email - await WIKI.mail.send({ - template: 'UserVerify', - to: email, - subject: 'Verify your account', - data: { - preheadertext: 'Verify your account in order to gain access to the wiki.', - title: 'Verify your account', - content: 'Click the button below in order to verify your account and gain access to the wiki.', - buttonLink: `${WIKI.config.mail.defaultBaseURL}/verify/${verificationToken}`, - buttonText: 'Verify' - }, - text: `You must open the following link in your browser to verify your account and gain access to the wiki: ${WIKI.config.mail.defaultBaseURL}/verify/${verificationToken}` - }) - } else if (sendWelcomeEmail) { - // TODO: Handle multilingual text - const site = WIKI.sites[sendWelcomeEmailFromSiteId] - if (site) { - const siteUrl = site.hostname === '*' ? WIKI.config.mail.defaultBaseURL : `https://${site.hostname}` - // Send welcome email - await WIKI.mail.send({ - template: 'UserWelcome', - to: email, - subject: `Welcome to the wiki ${site.config.title}`, - data: { - siteTitle: site.config.title, - preview: `You've been invited to the wiki ${site.config.title}`, - title: `You've been invited to the wiki ${site.config.title}`, - content: `Click the button below to access the wiki.`, - email, - password, - buttonLink: `${siteUrl}/login`, - buttonText: 'Login', - logo: `${siteUrl}/_site/logo` - }, - text: `You've been invited to the wiki ${site.config.title}: ${siteUrl}/login` - }) - } else { - WIKI.logger.warn('An invalid site ID was provided when creating user. No welcome email was sent.') - throw new Error('ERR_INVALID_SITE') - } - } - - WIKI.logger.debug(`Created new user account for ${email} successfully.`) - - return newUsr - } - - /** - * Update an existing user - * - * @param {Object} param0 User ID and fields to update - */ - static async updateUser (id, { email, name, groups, auth, isVerified, isActive, meta, prefs }) { - const usr = await WIKI.db.users.query().findById(id) - if (usr) { - let usrData = {} - if (!isEmpty(email) && email !== usr.email) { - const dupUsr = await WIKI.db.users.query().select('id').where({ email }).first() - if (dupUsr) { - throw new Error('ERR_DUPLICATE_ACCOUNT_EMAIL') - } - usrData.email = email.toLowerCase() - } - if (!isEmpty(name) && name !== usr.name) { - usrData.name = name.trim() - } - if (isArray(groups)) { - const usrGroupsRaw = await usr.$relatedQuery('groups') - const usrGroups = usrGroupsRaw.map(g => g.id) - // Relate added groups - const addUsrGroups = difference(groups, usrGroups) - for (const grp of addUsrGroups) { - await usr.$relatedQuery('groups').relate(grp) - } - // Unrelate removed groups - const remUsrGroups = difference(usrGroups, groups) - for (const grp of remUsrGroups) { - await usr.$relatedQuery('groups').unrelate().where('groupId', grp) - } - } - if (!isNil(auth?.tfaRequired)) { - usr.auth[WIKI.data.systemIds.localAuthId].tfaRequired = auth.tfaRequired - usrData.auth = usr.auth - } - if (!isNil(auth?.mustChangePwd)) { - usr.auth[WIKI.data.systemIds.localAuthId].mustChangePwd = auth.mustChangePwd - usrData.auth = usr.auth - } - if (!isNil(auth?.restrictLogin)) { - usr.auth[WIKI.data.systemIds.localAuthId].restrictLogin = auth.restrictLogin - usrData.auth = usr.auth - } - if (!isNil(isVerified)) { - usrData.isVerified = isVerified - } - if (!isNil(isActive)) { - usrData.isVerified = isActive - } - if (!isEmpty(meta)) { - usrData.meta = meta - } - if (!isEmpty(prefs)) { - usrData.prefs = prefs - } - await WIKI.db.users.query().patch(usrData).findById(id) - } else { - throw new WIKI.Error.UserNotFound() - } - } - - /** - * Delete a User - * - * @param {*} id User ID - */ - static async deleteUser (id, replaceId) { - const usr = await WIKI.db.users.query().findById(id) - if (usr) { - await WIKI.db.assets.query().patch({ authorId: replaceId }).where('authorId', id) - await WIKI.db.comments.query().patch({ authorId: replaceId }).where('authorId', id) - await WIKI.db.pageHistory.query().patch({ authorId: replaceId }).where('authorId', id) - await WIKI.db.pages.query().patch({ authorId: replaceId }).where('authorId', id) - await WIKI.db.pages.query().patch({ creatorId: replaceId }).where('creatorId', id) - - await WIKI.db.userKeys.query().delete().where('userId', id) - await WIKI.db.users.query().deleteById(id) - } else { - throw new WIKI.Error.UserNotFound() - } - } - - /** - * Logout the current user - */ - static async logout (context) { - if (!context.req.user || context.req.user.id === WIKI.config.auth.guestUserId) { - return '/' - } - if (context.req.user.strategyId && has(WIKI.auth.strategies, context.req.user.strategyId)) { - const selStrategy = WIKI.auth.strategies[context.req.user.strategyId] - if (!selStrategy.isEnabled) { - throw new WIKI.Error.AuthProviderInvalid() - } - const provider = find(WIKI.data.authentication, ['key', selStrategy.module]) - if (provider.logout) { - return provider.logout(provider.config) - } - } - return '/' - } - - static async getGuestUser () { - const user = await WIKI.db.users.query().findById(WIKI.config.auth.guestUserId).withGraphJoined('groups').modifyGraph('groups', builder => { - builder.select('groups.id', 'permissions') - }) - if (!user) { - WIKI.logger.error('CRITICAL ERROR: Guest user is missing!') - process.exit(1) - } - user.permissions = user.getPermissions() - return user - } - - static async getRootUser () { - let user = await WIKI.db.users.query().findById(WIKI.config.auth.rootAdminUserId) - if (!user) { - WIKI.logger.error('CRITICAL ERROR: Root Administrator user is missing!') - process.exit(1) - } - user.permissions = ['manage:system'] - return user - } - - /** - * Add / Update User Avatar Data - */ - static async updateUserAvatarData (userId, data) { - try { - WIKI.logger.debug(`Updating user ${userId} avatar data...`) - if (data.length > 1024 * 1024) { - throw new Error('Avatar image filesize is too large. 1MB max.') - } - const existing = await WIKI.db.knex('userAvatars').select('id').where('id', userId).first() - if (existing) { - await WIKI.db.knex('userAvatars').where({ - id: userId - }).update({ - data - }) - } else { - await WIKI.db.knex('userAvatars').insert({ - id: userId, - data - }) - } - } catch (err) { - WIKI.logger.warn(`Failed to process binary thumbnail data for user ${userId}: ${err.message}`) - } - } - - static async getUserAvatarData (userId) { - try { - const usrData = await WIKI.db.knex('userAvatars').where('id', userId).first() - if (usrData) { - return usrData.data - } else { - return null - } - } catch (err) { - WIKI.logger.warn(`Failed to process binary thumbnail data for user ${userId}`) - } - } -} diff --git a/server/modules/analytics/azureinsights/code.yml b/server/modules/analytics/azureinsights/code.yml deleted file mode 100644 index 82a3c441f..000000000 --- a/server/modules/analytics/azureinsights/code.yml +++ /dev/null @@ -1,10 +0,0 @@ -head: | - diff --git a/server/modules/analytics/azureinsights/definition.yml b/server/modules/analytics/azureinsights/definition.yml deleted file mode 100644 index ffa89e036..000000000 --- a/server/modules/analytics/azureinsights/definition.yml +++ /dev/null @@ -1,13 +0,0 @@ -key: azureinsights -title: Azure Application Insights -description: Application Insights is an extensible Application Performance Management (APM) service for web developers on multiple platforms. -author: requarks.io -logo: https://static.requarks.io/logo/azure.svg -website: https://azure.microsoft.com/en-us/services/monitor/ -isAvailable: true -props: - instrumentationKey: - type: String - title: Instrumentation Key - hint: Found in the Azure Portal in your Application Insights resource panel - order: 1 diff --git a/server/modules/analytics/baidutongji/code.yml b/server/modules/analytics/baidutongji/code.yml deleted file mode 100644 index 5ad69f3b0..000000000 --- a/server/modules/analytics/baidutongji/code.yml +++ /dev/null @@ -1,11 +0,0 @@ -head: | - - diff --git a/server/modules/analytics/baidutongji/definition.yml b/server/modules/analytics/baidutongji/definition.yml deleted file mode 100644 index f64370ae1..000000000 --- a/server/modules/analytics/baidutongji/definition.yml +++ /dev/null @@ -1,13 +0,0 @@ -key: baidutongji -title: Baidu Tongji -description: Baidu Tongji is a web analytics service offered by Baidu that tracks and reports website traffic. -author: lawrenceching -logo: https://static.requarks.io/logo/baidu.svg -website: https://tongji.baidu.com -isAvailable: true -props: - propertyTrackingId: - type: String - title: Property Tracking ID - hint: Unique Property ID (found at the end of the tracking URL, e.g. https://hm.baidu.com/hm.js?XXXXXXXXXXXX) - order: 1 diff --git a/server/modules/analytics/countly/code.yml b/server/modules/analytics/countly/code.yml deleted file mode 100644 index e675ad004..000000000 --- a/server/modules/analytics/countly/code.yml +++ /dev/null @@ -1,27 +0,0 @@ -head: | - diff --git a/server/modules/analytics/countly/definition.yml b/server/modules/analytics/countly/definition.yml deleted file mode 100644 index dd8a4f7f5..000000000 --- a/server/modules/analytics/countly/definition.yml +++ /dev/null @@ -1,18 +0,0 @@ -key: countly -title: Countly -description: Countly is the best analytics platform to understand and enhance customer journeys in web, desktop and mobile applications. -author: requarks.io -logo: https://static.requarks.io/logo/countly.svg -website: https://count.ly/ -isAvailable: true -props: - appKey: - type: String - title: App Key - hint: The App Key found under Management > Applications - order: 1 - serverUrl: - type: String - title: Server URL - hint: The Count.ly server to report to. e.g. https://us-example.count.ly - order: 2 diff --git a/server/modules/analytics/elasticapm/code.yml b/server/modules/analytics/elasticapm/code.yml deleted file mode 100644 index fb25300a3..000000000 --- a/server/modules/analytics/elasticapm/code.yml +++ /dev/null @@ -1,12 +0,0 @@ -head: | - - diff --git a/server/modules/analytics/elasticapm/definition.yml b/server/modules/analytics/elasticapm/definition.yml deleted file mode 100644 index 0bd0bf742..000000000 --- a/server/modules/analytics/elasticapm/definition.yml +++ /dev/null @@ -1,26 +0,0 @@ -key: elasticapm -title: Elasticsearch APM RUM -description: Real User Monitoring captures user interaction with clients such as web browsers. -author: requarks.io -logo: https://static.requarks.io/logo/elasticsearch-apm.svg -website: https://www.elastic.co/solutions/apm -isAvailable: true -props: - serverUrl: - type: String - title: APM Server URL - hint: The full URL to your APM server, including the port - default: http://apm.example.com:8200 - order: 1 - serviceName: - type: String - title: Service Name - hint: The name of the client reported to APM - default: wiki-js - order: 2 - environment: - type: String - title: Environment - hint: e.g. production/development/test - default: '' - order: 3 diff --git a/server/modules/analytics/fathom/code.yml b/server/modules/analytics/fathom/code.yml deleted file mode 100644 index 6ac14c85b..000000000 --- a/server/modules/analytics/fathom/code.yml +++ /dev/null @@ -1,16 +0,0 @@ -head: | - - - diff --git a/server/modules/analytics/fathom/definition.yml b/server/modules/analytics/fathom/definition.yml deleted file mode 100644 index ffa095e22..000000000 --- a/server/modules/analytics/fathom/definition.yml +++ /dev/null @@ -1,18 +0,0 @@ -key: fathom -title: Fathom -description: Fathom Analytics provides simple, useful website stats without tracking or storing personal data of your users. -author: requarks.io -logo: https://static.requarks.io/logo/fathom.svg -website: https://usefathom.com/ -isAvailable: true -props: - host: - type: String - title: Fathom Server Host - hint: The hostname / ip adress where Fathom is installed, without the trailing slash. e.g. https://fathom.example.com - order: 1 - siteId: - type: String - title: Site ID - hint: The alphanumeric identifier of your site - order: 2 diff --git a/server/modules/analytics/fullstory/code.yml b/server/modules/analytics/fullstory/code.yml deleted file mode 100644 index cbfbade4d..000000000 --- a/server/modules/analytics/fullstory/code.yml +++ /dev/null @@ -1,18 +0,0 @@ -head: | - diff --git a/server/modules/analytics/fullstory/definition.yml b/server/modules/analytics/fullstory/definition.yml deleted file mode 100644 index e950c1575..000000000 --- a/server/modules/analytics/fullstory/definition.yml +++ /dev/null @@ -1,13 +0,0 @@ -key: fullstory -title: FullStory -description: FullStory is your digital experience analytics platform for on-the-fly funnels, pixel-perfect replay, custom events, heat maps, advanced search, Dev Tools, and more. -author: requarks.io -logo: https://static.requarks.io/logo/fullstory.svg -website: https://www.fullstory.com -isAvailable: true -props: - org: - type: String - title: Organization ID - hint: A 5 alphanumeric identifier, e.g. XXXXX - order: 1 diff --git a/server/modules/analytics/google/code.yml b/server/modules/analytics/google/code.yml deleted file mode 100644 index 9d6210566..000000000 --- a/server/modules/analytics/google/code.yml +++ /dev/null @@ -1,10 +0,0 @@ -head: | - - - diff --git a/server/modules/analytics/google/definition.yml b/server/modules/analytics/google/definition.yml deleted file mode 100644 index 5a6b30b00..000000000 --- a/server/modules/analytics/google/definition.yml +++ /dev/null @@ -1,13 +0,0 @@ -key: google -title: Google Analytics -description: Google Analytics is a web analytics service offered by Google that tracks and reports website traffic. -author: requarks.io -logo: https://static.requarks.io/logo/google-analytics.svg -website: https://analytics.google.com/ -isAvailable: true -props: - propertyTrackingId: - type: String - title: Property Tracking ID - hint: UA-XXXXXXX-X - order: 1 diff --git a/server/modules/analytics/gtm/code.yml b/server/modules/analytics/gtm/code.yml deleted file mode 100644 index b6d2737e8..000000000 --- a/server/modules/analytics/gtm/code.yml +++ /dev/null @@ -1,13 +0,0 @@ -head: | - - - -bodyStart: | - - - diff --git a/server/modules/analytics/gtm/definition.yml b/server/modules/analytics/gtm/definition.yml deleted file mode 100644 index 3500532b6..000000000 --- a/server/modules/analytics/gtm/definition.yml +++ /dev/null @@ -1,13 +0,0 @@ -key: gtm -title: Google Tag Manager -description: Google Tag Manager is a tag management system created by Google to manage JavaScript and HTML tags used for tracking and analytics on websites. -author: requarks.io -logo: https://static.requarks.io/logo/google-tag-manager.svg -website: https://tagmanager.google.com -isAvailable: true -props: - containerTrackingId: - type: String - title: Container Tracking ID - hint: GTM-XXXXXXX - order: 1 diff --git a/server/modules/analytics/hotjar/code.yml b/server/modules/analytics/hotjar/code.yml deleted file mode 100644 index b83868103..000000000 --- a/server/modules/analytics/hotjar/code.yml +++ /dev/null @@ -1,12 +0,0 @@ -head: | - - diff --git a/server/modules/analytics/hotjar/definition.yml b/server/modules/analytics/hotjar/definition.yml deleted file mode 100644 index ef966bd24..000000000 --- a/server/modules/analytics/hotjar/definition.yml +++ /dev/null @@ -1,13 +0,0 @@ -key: hotjar -title: Hotjar -description: Hotjar is the fast & visual way to understand your users, providing everything your team needs to uncover insights and make the right changes to your site. -author: requarks.io -logo: https://static.requarks.io/logo/hotjar.svg -website: https://www.hotjar.com -isAvailable: true -props: - siteId: - type: String - title: Site ID - hint: A numeric identifier of your site - order: 1 diff --git a/server/modules/analytics/matomo/code.yml b/server/modules/analytics/matomo/code.yml deleted file mode 100644 index a650e9d67..000000000 --- a/server/modules/analytics/matomo/code.yml +++ /dev/null @@ -1,17 +0,0 @@ -head: | - - - - diff --git a/server/modules/analytics/matomo/definition.yml b/server/modules/analytics/matomo/definition.yml deleted file mode 100644 index cf00da83e..000000000 --- a/server/modules/analytics/matomo/definition.yml +++ /dev/null @@ -1,20 +0,0 @@ -key: matomo -title: Matomo -description: Take back control with Matomo Analytics – a powerful web analytics platform that gives you and your business 100% data ownership and user privacy protection. -author: requarks.io -logo: https://static.requarks.io/logo/matomo.svg -website: https://matomo.org/ -isAvailable: true -props: - siteId: - type: String - title: Site ID - hint: The number index representing your site ID - default: 1 - order: 1 - serverHost: - type: String - title: Server Host - hint: Including https:// and optionally the port. Without trailing slash. (e.g. https://example.matomo.cloud) - default: https://example.matomo.cloud - order: 2 diff --git a/server/modules/analytics/newrelic/code.yml b/server/modules/analytics/newrelic/code.yml deleted file mode 100644 index 06c5bb7e2..000000000 --- a/server/modules/analytics/newrelic/code.yml +++ /dev/null @@ -1,5 +0,0 @@ -head: | - diff --git a/server/modules/analytics/newrelic/definition.yml b/server/modules/analytics/newrelic/definition.yml deleted file mode 100644 index 01e92235b..000000000 --- a/server/modules/analytics/newrelic/definition.yml +++ /dev/null @@ -1,30 +0,0 @@ -key: newrelic -title: New Relic Browser -description: New Relic Browser provides deep visibility and insight into how your users are interacting with your application or website. -author: requarks.io -logo: https://static.requarks.io/logo/newrelic.svg -website: https://newrelic.com/products/browser-monitoring -isAvailable: true -props: - licenseKey: - type: String - title: License Key - hint: Found at the very end of the code snippet provided by New Relic Browser - order: 1 - appId: - type: String - title: Application ID - hint: Found at the very end of the code snippet provided by New Relic Browser - order: 2 - beacon: - type: String - title: Beacon - default: bam.nr-data.net - hint: Found at the very end of the code snippet provided by New Relic Browser. Differs for US and EU servers. - order: 3 - errorBeacon: - type: String - title: Error Beacon - default: bam.nr-data.net - hint: Found at the very end of the code snippet provided by New Relic Browser. Differs for US and EU servers. - order: 4 diff --git a/server/modules/analytics/plausible/code.yml b/server/modules/analytics/plausible/code.yml deleted file mode 100644 index d2fba2bb8..000000000 --- a/server/modules/analytics/plausible/code.yml +++ /dev/null @@ -1,2 +0,0 @@ -head: | - diff --git a/server/modules/analytics/plausible/definition.yml b/server/modules/analytics/plausible/definition.yml deleted file mode 100644 index eb86a6d81..000000000 --- a/server/modules/analytics/plausible/definition.yml +++ /dev/null @@ -1,19 +0,0 @@ -key: plausible -title: Plausible Analytics -description: Simple, open-source, lightweight and privacy-friendly web analytics alternative to Google Analytics. -author: requarks.io -logo: https://cdn.js.wiki/images/3rdparty/plausible.svg -website: https://plausible.io -isAvailable: true -props: - domain: - type: String - title: Domain - hint: The value of the data-domain property - order: 1 - plausibleJsSrc: - type: String - default: https://plausible.io/js/plausible.js - title: Plausible JS Script source - hint: The URL of Plausbile Script (only needed when using a self hosted installation) - order: 2 diff --git a/server/modules/analytics/statcounter/code.yml b/server/modules/analytics/statcounter/code.yml deleted file mode 100644 index 51bd69969..000000000 --- a/server/modules/analytics/statcounter/code.yml +++ /dev/null @@ -1,12 +0,0 @@ -head: | - - - - - diff --git a/server/modules/analytics/statcounter/definition.yml b/server/modules/analytics/statcounter/definition.yml deleted file mode 100644 index 9747f0c87..000000000 --- a/server/modules/analytics/statcounter/definition.yml +++ /dev/null @@ -1,18 +0,0 @@ -key: statcounter -title: StatCounter -description: See how Statcounter's easy-to-use features give you everything you need to understand your visitors and increase your website traffic. -author: requarks.io -logo: https://static.requarks.io/logo/statcountr.svg -website: https://statcounter.com/ -isAvailable: true -props: - projectId: - type: String - title: Project ID - hint: Unique Project ID, found in the code snippet provided by StatCounter - order: 1 - securityToken: - type: String - title: Security Token - hint: Security token, found in the code snippet provided by StatCounter - order: 2 diff --git a/server/modules/analytics/yandex/code.yml b/server/modules/analytics/yandex/code.yml deleted file mode 100644 index 9f6ae1fcd..000000000 --- a/server/modules/analytics/yandex/code.yml +++ /dev/null @@ -1,16 +0,0 @@ -head: | - - - - diff --git a/server/modules/analytics/yandex/definition.yml b/server/modules/analytics/yandex/definition.yml deleted file mode 100644 index e0e264452..000000000 --- a/server/modules/analytics/yandex/definition.yml +++ /dev/null @@ -1,13 +0,0 @@ -key: yandex -title: Yandex Metrica -description: From traffic trends to mouse movements – get a comprehensive understanding of your online audience and drive business growth. -author: requarks.io -logo: https://static.requarks.io/logo/yandex.svg -website: https://metrica.yandex.com -isAvailable: true -props: - tagNumber: - type: String - title: Tag Number - hint: When creating the tag, select "CMS and website builders" and copy the provided Tag Number - order: 1 diff --git a/server/modules/authentication/auth0/authentication.js b/server/modules/authentication/auth0/authentication.js deleted file mode 100644 index 9f40c24a0..000000000 --- a/server/modules/authentication/auth0/authentication.js +++ /dev/null @@ -1,31 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Auth0 Account -// ------------------------------------ - -const Auth0Strategy = require('passport-auth0').Strategy - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new Auth0Strategy({ - domain: conf.domain, - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - passReqToCallback: true - }, async (req, accessToken, refreshToken, extraParams, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - } - )) - } -} diff --git a/server/modules/authentication/auth0/definition.yml b/server/modules/authentication/auth0/definition.yml deleted file mode 100644 index d228dd44d..000000000 --- a/server/modules/authentication/auth0/definition.yml +++ /dev/null @@ -1,37 +0,0 @@ -key: auth0 -title: Auth0 -description: Auth0 provides universal identity platform for web, mobile, IoT, and internal applications. -author: requarks.io -logo: https://static.requarks.io/logo/auth0.svg -icon: /_assets/icons/ultraviolet-auth0.svg -color: deep-orange -website: https://auth0.com/ -isAvailable: true -useForm: false -scopes: - - openid - - profile - - email -props: - domain: - type: String - title: Domain - hint: Your Auth0 domain (e.g. something.auth0.com) - order: 1 - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 2 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 3 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Auth0. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/cas/authentication.js b/server/modules/authentication/cas/authentication.js deleted file mode 100644 index eedf255c5..000000000 --- a/server/modules/authentication/cas/authentication.js +++ /dev/null @@ -1,29 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// CAS Account -// ------------------------------------ - -const CASStrategy = require('passport-cas').Strategy - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new CASStrategy({ - ssoBaseURL: conf.ssoBaseURL, - serverBaseURL: conf.serverBaseURL, - passReqToCallback: true - }, async (req, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - ) - } -} diff --git a/server/modules/authentication/cas/definition.yml b/server/modules/authentication/cas/definition.yml deleted file mode 100644 index 35b423d7f..000000000 --- a/server/modules/authentication/cas/definition.yml +++ /dev/null @@ -1,12 +0,0 @@ -key: cas -title: CAS -description: The Central Authentication Service (CAS) is a single sign-on protocol for the web. -author: requarks.io -logo: https://static.requarks.io/logo/cas.svg -icon: /_assets/icons/ultraviolet-cas.svg -color: green darken-2 -website: https://apereo.github.io/cas/ -useForm: false -props: - ssoBaseURL: String - serverBaseURL: String diff --git a/server/modules/authentication/discord/authentication.js b/server/modules/authentication/discord/authentication.js deleted file mode 100644 index 0e9364788..000000000 --- a/server/modules/authentication/discord/authentication.js +++ /dev/null @@ -1,40 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Discord Account -// ------------------------------------ - -const DiscordStrategy = require('passport-discord').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new DiscordStrategy({ - clientID: conf.clientId, - clientSecret: conf.clientSecret, - authorizationURL: 'https://discord.com/api/oauth2/authorize?prompt=none', - callbackURL: conf.callbackURL, - scope: 'identify email guilds', - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - if (conf.guildId && !_.some(profile.guilds, { id: conf.guildId })) { - throw new WIKI.Error.AuthLoginFailed() - } - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - displayName: profile.username, - picture: `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.png` - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - } - )) - } -} diff --git a/server/modules/authentication/discord/definition.yml b/server/modules/authentication/discord/definition.yml deleted file mode 100644 index 7c186dfdf..000000000 --- a/server/modules/authentication/discord/definition.yml +++ /dev/null @@ -1,33 +0,0 @@ -key: discord -title: Discord -description: Discord is a proprietary freeware VoIP application designed for gaming communities, that specializes in text, video and audio communication between users in a chat channel. -author: requarks.io -logo: https://static.requarks.io/logo/discord.svg -icon: /_assets/icons/ultraviolet-discord.svg -color: indigo lighten-2 -website: https://discord.com/ -isAvailable: true -useForm: false -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 - guildId: - type: String - title: Server ID - hint: Optional - Your unique server identifier, such that only members are authorized - order: 3 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Discord. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/dropbox/authentication.js b/server/modules/authentication/dropbox/authentication.js deleted file mode 100644 index 55c9ca981..000000000 --- a/server/modules/authentication/dropbox/authentication.js +++ /dev/null @@ -1,35 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Dropbox Account -// ------------------------------------ - -const DropboxStrategy = require('passport-dropbox-oauth2').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new DropboxStrategy({ - apiVersion: '2', - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - picture: _.get(profile, '_json.profile_photo_url', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - ) - } -} diff --git a/server/modules/authentication/dropbox/definition.yml b/server/modules/authentication/dropbox/definition.yml deleted file mode 100644 index bdb14a969..000000000 --- a/server/modules/authentication/dropbox/definition.yml +++ /dev/null @@ -1,28 +0,0 @@ -key: dropbox -title: Dropbox -description: Dropbox is a file hosting service that offers cloud storage, file synchronization, personal cloud, and client software. -author: requarks.io -logo: https://static.requarks.io/logo/dropbox.svg -icon: /_assets/icons/ultraviolet-dropbox.svg -color: blue darken-2 -website: https://dropbox.com -isAvailable: true -useForm: false -props: - clientId: - type: String - title: App Key - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: App Secret - hint: Application Client Secret - sensitive: true - order: 2 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Dropbox. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/facebook/authentication.js b/server/modules/authentication/facebook/authentication.js deleted file mode 100644 index 67657443b..000000000 --- a/server/modules/authentication/facebook/authentication.js +++ /dev/null @@ -1,36 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Facebook Account -// ------------------------------------ - -const FacebookStrategy = require('passport-facebook').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new FacebookStrategy({ - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - profileFields: ['id', 'displayName', 'email', 'photos'], - authType: 'reauthenticate', - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - picture: _.get(profile, 'photos[0].value', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - } - )) - } -} diff --git a/server/modules/authentication/facebook/definition.yml b/server/modules/authentication/facebook/definition.yml deleted file mode 100644 index 493d53db3..000000000 --- a/server/modules/authentication/facebook/definition.yml +++ /dev/null @@ -1,30 +0,0 @@ -key: facebook -title: Facebook -description: Facebook is an online social media and social networking service company. -author: requarks.io -logo: https://static.requarks.io/logo/facebook.svg -icon: /_assets/icons/ultraviolet-facebook.svg -color: indigo -website: https://facebook.com/ -isAvailable: true -useForm: false -scopes: - - email -props: - clientId: - type: String - title: App ID - hint: Application ID - order: 1 - clientSecret: - type: String - title: App Secret - hint: Application Secret - sensitive: true - order: 2 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Facebook. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/github/authentication.js b/server/modules/authentication/github/authentication.js deleted file mode 100644 index d960556bb..000000000 --- a/server/modules/authentication/github/authentication.js +++ /dev/null @@ -1,44 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// GitHub Account -// ------------------------------------ - -const GitHubStrategy = require('passport-github2').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - let githubConfig = { - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - scope: ['user:email'], - passReqToCallback: true - } - - if (conf.useEnterprise) { - githubConfig.authorizationURL = `https://${conf.enterpriseDomain}/login/oauth/authorize` - githubConfig.tokenURL = `https://${conf.enterpriseDomain}/login/oauth/access_token` - githubConfig.userProfileURL = conf.enterpriseUserEndpoint - githubConfig.userEmailURL = `${conf.enterpriseUserEndpoint}/emails` - } - - passport.use(conf.key, - new GitHubStrategy(githubConfig, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - picture: _.get(profile, 'photos[0].value', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - } - )) - } -} diff --git a/server/modules/authentication/github/definition.yml b/server/modules/authentication/github/definition.yml deleted file mode 100644 index 417bea9da..000000000 --- a/server/modules/authentication/github/definition.yml +++ /dev/null @@ -1,51 +0,0 @@ -key: github -title: GitHub -description: GitHub Inc. is a web-based hosting service for version control using Git. -author: requarks.io -logo: https://static.requarks.io/logo/github.svg -icon: /_assets/icons/ultraviolet-github.svg -color: grey darken-3 -website: https://github.com -isAvailable: true -useForm: false -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 - useEnterprise: - type: Boolean - title: Use GitHub Enterprise - hint: Enable if you're using the self-hosted GitHub Enterprise version - default: false - order: 3 - enterpriseDomain: - type: String - title: GitHub Enterprise Domain - hint: GitHub Enterprise Only - Domain of your installation (e.g. github.company.com). Leave blank otherwise. - default: '' - order: 4 - if: - - { key: 'useEnterprise', eq: true } - enterpriseUserEndpoint: - type: String - title: GitHub Enterprise User Endpoint - hint: GitHub Enterprise Only - Endpoint to fetch user details (e.g. https://api.github.com/user). Leave blank otherwise. - default: 'https://api.github.com/user' - order: 5 - if: - - { key: 'useEnterprise', eq: true } -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on GitHub. - icon: back - value: '{host}/login/{id}/callback' - diff --git a/server/modules/authentication/gitlab/authentication.js b/server/modules/authentication/gitlab/authentication.js deleted file mode 100644 index 992ae9178..000000000 --- a/server/modules/authentication/gitlab/authentication.js +++ /dev/null @@ -1,36 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// GitLab Account -// ------------------------------------ - -const GitLabStrategy = require('passport-gitlab2').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new GitLabStrategy({ - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - baseURL: conf.baseUrl, - scope: ['read_user'], - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - picture: _.get(profile, 'avatarUrl', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - } - )) - } -} diff --git a/server/modules/authentication/gitlab/definition.yml b/server/modules/authentication/gitlab/definition.yml deleted file mode 100644 index c5de2deab..000000000 --- a/server/modules/authentication/gitlab/definition.yml +++ /dev/null @@ -1,34 +0,0 @@ -key: gitlab -title: GitLab -description: GitLab is a web-based DevOps lifecycle tool that provides a Git-repository manager providing wiki, issue-tracking and CI/CD pipeline features. -author: requarks.io -logo: https://static.requarks.io/logo/gitlab.svg -icon: /_assets/icons/ultraviolet-gitlab.svg -color: deep-orange -website: https://gitlab.com -isAvailable: true -useForm: false -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 - baseUrl: - type: String - title: Base URL - hint: For self-managed GitLab instances, define the base URL (e.g. https://gitlab.example.com). Leave default for GitLab.com SaaS (https://gitlab.com). - default: https://gitlab.com - order: 3 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on GitLab. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/google/authentication.js b/server/modules/authentication/google/authentication.js deleted file mode 100644 index e64ccec21..000000000 --- a/server/modules/authentication/google/authentication.js +++ /dev/null @@ -1,48 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Google ID Account -// ------------------------------------ - -const GoogleStrategy = require('passport-google-oauth20').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - const strategy = new GoogleStrategy({ - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - if (conf.hostedDomain && conf.hostedDomain != profile._json.hd) { - throw new Error('Google authentication should have been performed with domain ' + conf.hostedDomain) - } - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - picture: _.get(profile, 'photos[0].value', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - - if (conf.hostedDomain) { - strategy.authorizationParams = function(options) { - return { - hd: conf.hostedDomain - } - } - } - - passport.use(conf.key, strategy) - }, - logout (conf) { - return '/' - } -} diff --git a/server/modules/authentication/google/definition.yml b/server/modules/authentication/google/definition.yml deleted file mode 100644 index 488d42d89..000000000 --- a/server/modules/authentication/google/definition.yml +++ /dev/null @@ -1,37 +0,0 @@ -key: google -title: Google -description: Google specializes in Internet-related services and products, which include online advertising technologies, search engine, cloud computing, software, and hardware. -author: requarks.io -logo: https://static.requarks.io/logo/google.svg -icon: /_assets/icons/ultraviolet-google.svg -color: red darken-1 -website: https://console.developers.google.com/ -isAvailable: true -useForm: false -scopes: - - profile - - email - - openid -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 - hostedDomain: - type: String - title: Hosted Domain - hint: (optional) Only for G Suite hosted domain. Leave empty otherwise. - order: 3 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Google. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/keycloak/authentication.js b/server/modules/authentication/keycloak/authentication.js deleted file mode 100644 index f315b6e51..000000000 --- a/server/modules/authentication/keycloak/authentication.js +++ /dev/null @@ -1,54 +0,0 @@ -const _ = require('lodash') - -// ------------------------------------ -// Keycloak Account -// ------------------------------------ - -const KeycloakStrategy = require('@exlinc/keycloak-passport') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new KeycloakStrategy({ - authorizationURL: conf.authorizationURL, - userInfoURL: conf.userInfoURL, - tokenURL: conf.tokenURL, - host: conf.host, - realm: conf.realm, - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - let displayName = profile.username - if (_.isString(profile.fullName) && profile.fullName.length > 0) { - displayName = profile.fullName - } - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - id: profile.keycloakId, - email: profile.email, - name: displayName, - picture: '' - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - ) - }, - logout (conf) { - if (!conf.logoutUpstream) { - return '/' - } else if (conf.logoutURL && conf.logoutURL.length > 5) { - return `${conf.logoutURL}?redirect_uri=${encodeURIComponent(WIKI.config.host)}` - } else { - WIKI.logger.warn('Keycloak logout URL is not configured!') - return '/' - } - } -} diff --git a/server/modules/authentication/keycloak/definition.yml b/server/modules/authentication/keycloak/definition.yml deleted file mode 100644 index 1caa249e8..000000000 --- a/server/modules/authentication/keycloak/definition.yml +++ /dev/null @@ -1,63 +0,0 @@ -key: keycloak -title: Keycloak -description: Keycloak is an open source software product to allow single sign-on with Identity Management and Access Management aimed at modern applications and services. -author: D4uS1 -logo: https://static.requarks.io/logo/keycloak.svg -icon: /_assets/icons/ultraviolet-keycloak.svg -color: blue-grey darken-2 -website: https://www.keycloak.org/ -useForm: false -isAvailable: true -props: - host: - type: String - title: Host - hint: e.g. https://your.keycloak-host.com - order: 1 - realm: - type: String - title: Realm - hint: The realm this application belongs to. - order: 2 - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 3 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 4 - authorizationURL: - type: String - title: Authorization Endpoint URL - hint: e.g. https://KEYCLOAK-HOST/auth/realms/YOUR-REALM/protocol/openid-connect/auth - order: 5 - tokenURL: - type: String - title: Token Endpoint URL - hint: e.g. https://KEYCLOAK-HOST/auth/realms/YOUR-REALM/protocol/openid-connect/token - order: 6 - userInfoURL: - type: String - title: User Info Endpoint URL - hint: e.g. https://KEYCLOAK-HOST/auth/realms/YOUR-REALM/protocol/openid-connect/userinfo - order: 7 - logoutUpstream: - type: Boolean - title: Logout from Keycloak on Logout - hint: Should the user be redirected to Keycloak logout mechanism upon logout - order: 8 - logoutURL: - type: String - title: Logout Endpoint URL - hint: e.g. https://KEYCLOAK-HOST/auth/realms/YOUR-REALM/protocol/openid-connect/logout - order: 9 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Keycloak. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/ldap/authentication.js b/server/modules/authentication/ldap/authentication.js deleted file mode 100644 index f3d4911bb..000000000 --- a/server/modules/authentication/ldap/authentication.js +++ /dev/null @@ -1,75 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// LDAP Account -// ------------------------------------ - -const LdapStrategy = require('passport-ldapauth').Strategy -const fs = require('fs') -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new LdapStrategy({ - server: { - url: conf.url, - bindDn: conf.bindDn, - bindCredentials: conf.bindCredentials, - searchBase: conf.searchBase, - searchFilter: conf.searchFilter, - tlsOptions: getTlsOptions(conf), - includeRaw: true - }, - usernameField: 'email', - passwordField: 'password', - passReqToCallback: true - }, async (req, profile, cb) => { - try { - const userId = _.get(profile, conf.mappingUID, null) - if (!userId) { - throw new Error('Invalid Unique ID field mapping!') - } - - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - id: userId, - email: String(_.get(profile, conf.mappingEmail, '')).split(',')[0], - displayName: _.get(profile, conf.mappingDisplayName, '???'), - picture: _.get(profile, `_raw.${conf.mappingPicture}`, '') - } - }) - cb(null, user) - } catch (err) { - if (WIKI.config.flags.ldapdebug) { - WIKI.logger.warn('LDAP LOGIN ERROR (c2): ', err) - } - cb(err, null) - } - } - )) - } -} - -function getTlsOptions(conf) { - if (!conf.tlsEnabled) { - return {} - } - - if (!conf.tlsCertPath) { - return { - rejectUnauthorized: conf.verifyTLSCertificate, - } - } - - const caList = [] - if (conf.verifyTLSCertificate) { - caList.push(fs.readFileSync(conf.tlsCertPath)) - } - - return { - rejectUnauthorized: conf.verifyTLSCertificate, - ca: caList - } -} diff --git a/server/modules/authentication/ldap/definition.yml b/server/modules/authentication/ldap/definition.yml deleted file mode 100644 index 51572fb71..000000000 --- a/server/modules/authentication/ldap/definition.yml +++ /dev/null @@ -1,88 +0,0 @@ -key: ldap -title: LDAP / Active Directory -description: Active Directory is a directory service that Microsoft developed for the Windows domain networks. -author: requarks.io -logo: https://static.requarks.io/logo/active-directory.svg -icon: /_assets/icons/ultraviolet-windows8.svg -color: blue darken-3 -vendor: Microsoft Corporation -website: https://www.microsoft.com/windowsserver -isAvailable: true -useForm: true -usernameType: username -props: - url: - title: LDAP URL - type: String - default: 'ldap://serverhost:389' - hint: (e.g. ldap://serverhost:389 or ldaps://serverhost:636) - order: 1 - bindDn: - title: Admin Bind DN - type: String - default: cn='root' - hint: The distinguished name (dn) of the account used for binding. - maxWidth: 600 - order: 2 - bindCredentials: - title: Admin Bind Credentials - type: String - hint: The password of the account used above for binding. - maxWidth: 600 - sensitive: true - order: 3 - searchBase: - title: Search Base - type: String - default: 'o=users,o=example.com' - hint: The base DN from which to search for users. - order: 4 - searchFilter: - title: Search Filter - type: String - default: '(uid={{username}})' - hint: The query to use to match username. {{username}} must be present and will be interpolated with the user provided username when performing the LDAP search. - order: 5 - tlsEnabled: - title: Use TLS - type: Boolean - default: false - order: 6 - verifyTLSCertificate: - title: Verify TLS Certificate - type: Boolean - default: true - order: 7 - tlsCertPath: - title: TLS Certificate Path - type: String - hint: Absolute path to the TLS certificate on the server. - order: 8 - mappingUID: - title: Unique ID Field Mapping - type: String - default: 'uid' - hint: The field storing the user unique identifier. Usually "uid" or "sAMAccountName". - maxWidth: 500 - order: 20 - mappingEmail: - title: Email Field Mapping - type: String - default: 'mail' - hint: The field storing the user email. Usually "mail". - maxWidth: 500 - order: 21 - mappingDisplayName: - title: Display Name Field Mapping - type: String - default: 'displayName' - hint: The field storing the user display name. Usually "displayName" or "cn". - maxWidth: 500 - order: 22 - mappingPicture: - title: Avatar Picture Field Mapping - type: String - default: 'jpegPhoto' - hint: The field storing the user avatar picture. Usually "jpegPhoto" or "thumbnailPhoto". - maxWidth: 500 - order: 23 diff --git a/server/modules/authentication/local/authentication.mjs b/server/modules/authentication/local/authentication.mjs deleted file mode 100644 index 71af987ed..000000000 --- a/server/modules/authentication/local/authentication.mjs +++ /dev/null @@ -1,45 +0,0 @@ -/* global WIKI */ -import bcrypt from 'bcryptjs' - -// ------------------------------------ -// Local Account -// ------------------------------------ - -import { Strategy } from 'passport-local' - -export default { - init (passport, strategyId, conf) { - passport.use(strategyId, - new Strategy({ - usernameField: 'email', - passwordField: 'password' - }, async (uEmail, uPassword, done) => { - try { - const user = await WIKI.db.users.query().findOne({ - email: uEmail.toLowerCase() - }) - if (user) { - const authStrategyData = user.auth[strategyId] - if (!authStrategyData) { - throw new Error('ERR_INVALID_STRATEGY') - } else if (await bcrypt.compare(uPassword, authStrategyData.password) !== true) { - throw new Error('ERR_LOGIN_FAILED') - } else if (!user.isActive) { - throw new Error('ERR_INACTIVE_USER') - } else if (authStrategyData.restrictLogin) { - throw new Error('ERR_LOGIN_RESTRICTED') - } else if (!user.isVerified) { - throw new Error('ERR_USER_NOT_VERIFIED') - } else { - done(null, user) - } - } else { - throw new Error('ERR_LOGIN_FAILED') - } - } catch (err) { - done(err, null) - } - }) - ) - } -} diff --git a/server/modules/authentication/local/definition.yml b/server/modules/authentication/local/definition.yml deleted file mode 100644 index 77478da23..000000000 --- a/server/modules/authentication/local/definition.yml +++ /dev/null @@ -1,25 +0,0 @@ -key: local -title: Local Database -description: Built-in authentication for Wiki.js -author: requarks.io -logo: https://static.requarks.io/logo/wikijs.svg -icon: /_assets/icons/ultraviolet-data-protection.svg -color: primary -vendor: 'Wiki.js' -website: 'https://js.wiki' -isAvailable: true -useForm: true -usernameType: email -props: - enforceTfa: - type: Boolean - title: Enforce Two-Factor Authentication - hint: Users will be required to setup 2FA the first time they login and cannot be disabled by the user. - icon: pin-pad - default: false - emailValidation: - type: Boolean - title: Email Validation - hint: Send a verification email to the user with a validation link when registering (if registration is enabled). - icon: received - default: true diff --git a/server/modules/authentication/microsoft/authentication.js b/server/modules/authentication/microsoft/authentication.js deleted file mode 100644 index 0daa4216f..000000000 --- a/server/modules/authentication/microsoft/authentication.js +++ /dev/null @@ -1,35 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Microsoft Account -// ------------------------------------ - -const WindowsLiveStrategy = require('passport-microsoft').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new WindowsLiveStrategy({ - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - scope: ['User.Read', 'email', 'openid', 'profile'], - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - picture: _.get(profile, 'photos[0].value', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - } - )) - } -} diff --git a/server/modules/authentication/microsoft/definition.yml b/server/modules/authentication/microsoft/definition.yml deleted file mode 100644 index 0b18c2e76..000000000 --- a/server/modules/authentication/microsoft/definition.yml +++ /dev/null @@ -1,26 +0,0 @@ -key: microsoft -title: Microsoft -description: Microsoft is a software company, best known for it's Windows, Office, Azure, Xbox and Surface products. -author: requarks.io -logo: https://static.requarks.io/logo/microsoft.svg -icon: /_assets/icons/ultraviolet-microsoft.svg -color: blue -website: https://apps.dev.microsoft.com/ -isAvailable: false -useForm: false -scopes: - - openid - - profile - - email -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 diff --git a/server/modules/authentication/oauth2/authentication.js b/server/modules/authentication/oauth2/authentication.js deleted file mode 100644 index 7c4213c37..000000000 --- a/server/modules/authentication/oauth2/authentication.js +++ /dev/null @@ -1,60 +0,0 @@ -const _ = require('lodash') - -// ------------------------------------ -// OAuth2 Account -// ------------------------------------ - -const OAuth2Strategy = require('passport-oauth2').Strategy - -module.exports = { - init (passport, conf) { - var client = new OAuth2Strategy({ - authorizationURL: conf.authorizationURL, - tokenURL: conf.tokenURL, - clientID: conf.clientId, - clientSecret: conf.clientSecret, - userInfoURL: conf.userInfoURL, - callbackURL: conf.callbackURL, - passReqToCallback: true, - scope: conf.scope - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - id: _.get(profile, conf.userIdClaim), - displayName: _.get(profile, conf.displayNameClaim, '???'), - email: _.get(profile, conf.emailClaim) - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - - client.userProfile = function (accesstoken, done) { - this._oauth2._useAuthorizationHeaderForGET = !conf.useQueryStringForAccessToken - this._oauth2.get(conf.userInfoURL, accesstoken, (err, data) => { - if (err) { - return done(err) - } - try { - data = JSON.parse(data) - } catch (e) { - return done(e) - } - done(null, data) - }) - } - passport.use(conf.key, client) - }, - logout (conf) { - if (!conf.logoutURL) { - return '/' - } else { - return conf.logoutURL - } - } -} diff --git a/server/modules/authentication/oauth2/definition.yml b/server/modules/authentication/oauth2/definition.yml deleted file mode 100644 index f606475ab..000000000 --- a/server/modules/authentication/oauth2/definition.yml +++ /dev/null @@ -1,80 +0,0 @@ -key: oauth2 -title: Generic OAuth2 -description: OAuth 2.0 is the industry-standard protocol for authorization. -author: requarks.io -logo: https://static.requarks.io/logo/oauth2.svg -icon: /_assets/icons/ultraviolet-oauth2.svg -color: blue-grey darken-2 -website: https://oauth.net/2/ -isAvailable: true -useForm: false -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 - authorizationURL: - type: String - title: Authorization Endpoint URL - hint: Application Authorization Endpoint URL - order: 3 - tokenURL: - type: String - title: Token Endpoint URL - hint: Application Token Endpoint URL - order: 4 - userInfoURL: - type: String - title: User Info Endpoint URL - hint: User Info Endpoint URL - order: 5 - userIdClaim: - type: String - title: ID Claim - hint: Field containing the user ID - default: id - maxWidth: 500 - order: 6 - displayNameClaim: - type: String - title: Display Name Claim - hint: Field containing user display name - default: displayName - maxWidth: 500 - order: 7 - emailClaim: - type: String - title: Email Claim - hint: Field containing the user email address - default: email - maxWidth: 500 - order: 8 - logoutURL: - type: String - title: Logout URL - hint: (optional) Logout URL on the OAuth2 provider where the user will be redirected to complete the logout process. - order: 9 - scope: - type: String - title: Scope - hint: (optional) Application Client permission scopes. - order: 10 - useQueryStringForAccessToken: - type: Boolean - default: false - title: Pass access token via GET query string to User Info Endpoint - hint: (optional) Pass the access token in an `access_token` parameter attached to the GET query string of the User Info Endpoint URL. Otherwise the access token will be passed in the Authorization header. - order: 11 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on the oauth2 server. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/oidc/authentication.js b/server/modules/authentication/oidc/authentication.js deleted file mode 100644 index 61bb117a7..000000000 --- a/server/modules/authentication/oidc/authentication.js +++ /dev/null @@ -1,44 +0,0 @@ -const _ = require('lodash') - -// ------------------------------------ -// OpenID Connect Account -// ------------------------------------ - -const OpenIDConnectStrategy = require('passport-openidconnect').Strategy - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new OpenIDConnectStrategy({ - authorizationURL: conf.authorizationURL, - tokenURL: conf.tokenURL, - clientID: conf.clientId, - clientSecret: conf.clientSecret, - issuer: conf.issuer, - userInfoURL: conf.userInfoURL, - callbackURL: conf.callbackURL, - passReqToCallback: true - }, async (req, iss, sub, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - email: _.get(profile, '_json.' + conf.emailClaim) - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - ) - }, - logout (conf) { - if (!conf.logoutURL) { - return '/' - } else { - return conf.logoutURL - } - } -} diff --git a/server/modules/authentication/oidc/definition.yml b/server/modules/authentication/oidc/definition.yml deleted file mode 100644 index afe8dae90..000000000 --- a/server/modules/authentication/oidc/definition.yml +++ /dev/null @@ -1,64 +0,0 @@ -key: oidc -title: Generic OpenID Connect / OAuth2 -description: OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. -author: requarks.io -logo: https://static.requarks.io/logo/oidc.svg -icon: /_assets/icons/ultraviolet-openid.svg -color: blue-grey darken-2 -website: http://openid.net/connect/ -isAvailable: true -useForm: false -scopes: - - openid - - profile - - email -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 - authorizationURL: - type: String - title: Authorization Endpoint URL - hint: Application Authorization Endpoint URL - order: 3 - tokenURL: - type: String - title: Token Endpoint URL - hint: Application Token Endpoint URL - order: 4 - userInfoURL: - type: String - title: User Info Endpoint URL - hint: User Info Endpoint URL - order: 5 - issuer: - type: String - title: Issuer - hint: Issuer URL - order: 6 - emailClaim: - type: String - title: Email Claim - hint: Field containing the email address - default: email - maxWidth: 500 - order: 7 - logoutURL: - type: String - title: Logout URL - hint: (optional) Logout URL on the OAuth2 provider where the user will be redirected to complete the logout process. - order: 8 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on OIDC server. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/okta/authentication.js b/server/modules/authentication/okta/authentication.js deleted file mode 100644 index 06fcc673a..000000000 --- a/server/modules/authentication/okta/authentication.js +++ /dev/null @@ -1,37 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Okta Account -// ------------------------------------ - -const OktaStrategy = require('passport-okta-oauth').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new OktaStrategy({ - audience: conf.audience, - clientID: conf.clientId, - clientSecret: conf.clientSecret, - idp: conf.idp, - callbackURL: conf.callbackURL, - response_type: 'code', - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - picture: _.get(profile, '_json.profile', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - ) - } -} diff --git a/server/modules/authentication/okta/definition.yml b/server/modules/authentication/okta/definition.yml deleted file mode 100644 index 1d8b04762..000000000 --- a/server/modules/authentication/okta/definition.yml +++ /dev/null @@ -1,45 +0,0 @@ -key: okta -title: Okta -description: Okta provide secure identity management and single sign-on to any application. -author: requarks.io -logo: https://static.requarks.io/logo/okta.svg -icon: /_assets/icons/ultraviolet-okta.svg -color: blue darken-1 -website: https://www.okta.com/ -isAvailable: true -useForm: false -scopes: - - profile - - email - - openid -props: - audience: - title: Org URL - type: String - hint: Okta organization URL (e.g. https://example.okta.com, https://example.oktapreview.com), found on the Developer Dashboard, in the upper right. - order: 1 - clientId: - title: Client ID - type: String - hint: 20 chars alphanumeric string - maxWidth: 400 - order: 2 - clientSecret: - title: Client Secret - type: String - hint: 40 chars alphanumeric string with a hyphen(s) - maxWidth: 600 - sensitive: true - order: 3 - idp: - title: Identity Provider ID (idp) - type: String - hint: (Optional) - 20 chars alphanumeric string - maxWidth: 400 - order: 4 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Okta. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/rocketchat/authentication.js b/server/modules/authentication/rocketchat/authentication.js deleted file mode 100644 index 6362f2364..000000000 --- a/server/modules/authentication/rocketchat/authentication.js +++ /dev/null @@ -1,62 +0,0 @@ -const _ = require('lodash') - -// ------------------------------------ -// Rocket.chat Account -// ------------------------------------ - -const OAuth2Strategy = require('passport-oauth2').Strategy - -module.exports = { - init (passport, conf) { - const siteURL = conf.siteURL.slice(-1) === '/' ? conf.siteURL.slice(0, -1) : conf.siteURL - - OAuth2Strategy.prototype.userProfile = function (accessToken, cb) { - this._oauth2.get(`${siteURL}/api/v1/me`, accessToken, (err, body, res) => { - if (err) { - WIKI.logger.warn('Rocket.chat - Failed to fetch user profile.') - return cb(err) - } - try { - const usr = JSON.parse(body) - cb(null, { - id: usr._id, - displayName: _.isEmpty(usr.name) ? usr.username : usr.name, - email: usr.emails[0].address, - picture: usr.avatarUrl - }) - } catch (err) { - WIKI.logger.warn('Rocket.chat - Failed to parse user profile.') - cb(err) - } - }) - } - - passport.use(conf.key, - new OAuth2Strategy({ - authorizationURL: `${siteURL}/oauth/authorize`, - tokenURL: `${siteURL}/oauth/token`, - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - ) - }, - logout (conf) { - if (!conf.logoutURL) { - return '/' - } else { - return conf.logoutURL - } - } -} diff --git a/server/modules/authentication/rocketchat/definition.yml b/server/modules/authentication/rocketchat/definition.yml deleted file mode 100644 index f0155af8c..000000000 --- a/server/modules/authentication/rocketchat/definition.yml +++ /dev/null @@ -1,37 +0,0 @@ -key: rocketchat -title: Rocket.chat -description: Communicate and collaborate with your team, share files, chat in real-time, or switch to video/audio conferencing. -author: requarks.io -logo: https://static.requarks.io/logo/rocketchat.svg -icon: /_assets/icons/ultraviolet-rocketchat.svg -color: red accent-3 -website: https://rocket.chat/ -isAvailable: true -useForm: false -scopes: - - openid - - profile - - email -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 - siteURL: - type: String - title: Rocket.chat Site URL - hint: The base URL of your Rocket.chat site (e.g. https://example.rocket.chat) - order: 3 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Rocket.chat. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/saml/authentication.js b/server/modules/authentication/saml/authentication.js deleted file mode 100644 index c16c5fbe4..000000000 --- a/server/modules/authentication/saml/authentication.js +++ /dev/null @@ -1,64 +0,0 @@ -const _ = require('lodash') - -// ------------------------------------ -// SAML Account -// ------------------------------------ - -const SAMLStrategy = require('passport-saml').Strategy - -module.exports = { - init (passport, conf) { - const samlConfig = { - callbackUrl: conf.callbackURL, - entryPoint: conf.entryPoint, - issuer: conf.issuer, - cert: (conf.cert || '').split('|'), - signatureAlgorithm: conf.signatureAlgorithm, - digestAlgorithm: conf.digestAlgorithm, - identifierFormat: conf.identifierFormat, - wantAssertionsSigned: conf.wantAssertionsSigned, - acceptedClockSkewMs: _.toSafeInteger(conf.acceptedClockSkewMs), - disableRequestedAuthnContext: conf.disableRequestedAuthnContext, - authnContext: (conf.authnContext || '').split('|'), - racComparison: conf.racComparison, - forceAuthn: conf.forceAuthn, - passive: conf.passive, - providerName: conf.providerName, - skipRequestCompression: conf.skipRequestCompression, - authnRequestBinding: conf.authnRequestBinding, - passReqToCallback: true - } - if (!_.isEmpty(conf.audience)) { - samlConfig.audience = conf.audience - } - if (!_.isEmpty(conf.privateKey)) { - samlConfig.privateKey = conf.privateKey - } - if (!_.isEmpty(conf.decryptionPvk)) { - samlConfig.decryptionPvk = conf.decryptionPvk - } - passport.use(conf.key, - new SAMLStrategy(samlConfig, async (req, profile, cb) => { - try { - const userId = _.get(profile, [conf.mappingUID], null) || _.get(profile, 'nameID', null) - if (!userId) { - throw new Error('Invalid or Missing Unique ID field!') - } - - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - id: userId, - email: _.get(profile, conf.mappingEmail, ''), - displayName: _.get(profile, conf.mappingDisplayName, '???'), - picture: _.get(profile, conf.mappingPicture, '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - }) - ) - } -} diff --git a/server/modules/authentication/saml/definition.yml b/server/modules/authentication/saml/definition.yml deleted file mode 100644 index c3d0e7ffe..000000000 --- a/server/modules/authentication/saml/definition.yml +++ /dev/null @@ -1,165 +0,0 @@ -key: saml -title: SAML 2.0 -description: Security Assertion Markup Language 2.0 (SAML 2.0) is a version of the SAML standard for exchanging authentication and authorization data between security domains. -author: requarks.io -logo: https://static.requarks.io/logo/saml.svg -icon: /_assets/icons/ultraviolet-saml.svg -color: red darken-3 -website: https://wiki.oasis-open.org/security/FrontPage -isAvailable: true -useForm: false -props: - entryPoint: - type: String - title: Entry Point - hint: Identity provider entrypoint (URL) - order: 1 - issuer: - type: String - title: Issuer - hint: Issuer string to supply to Identity Provider - order: 2 - audience: - type: String - title: Audience - hint: Expected SAML response Audience (if not provided, audience won't be verified) - order: 3 - cert: - type: String - title: Certificate - hint: Public PEM-encoded X.509 signing certificate. If the provider has multiple certificates that are valid, join them together using the | pipe symbol. - multiline: true - order: 4 - privateKey: - type: String - title: Private Key - hint: PEM formatted key used to sign the certificate. - multiline: true - order: 5 - decryptionPvk: - type: String - title: Decryption Private Key - hint: (Optional) - Private key that will be used to attempt to decrypt any encrypted assertions that are received. - multiline: true - order: 6 - signatureAlgorithm: - type: String - title: Signature Algorithm - hint: Signature algorithm used for signing requests - maxWidth: 400 - order: 7 - default: sha1 - enum: - - sha1 - - sha256 - - sha512 - digestAlgorithm: - type: String - title: Digest Algorithm - hint: Digest algorithm used to provide a digest for the signed data object - maxWidth: 400 - order: 8 - default: sha1 - enum: - - sha1 - - sha256 - - sha512 - identifierFormat: - type: String - title: Name Identifier format - default: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress' - order: 20 - wantAssertionsSigned: - type: Boolean - title: Always sign assertions - hint: If enabled, add WantAssertionsSigned="true" to the metadata, to specify that the IdP should always sign the assertions. - default: false - order: 21 - acceptedClockSkewMs: - type: Number - title: Accepted Clock Skew Milleseconds - hint: Time in milliseconds of skew that is acceptable between client and server when checking OnBefore and NotOnOrAfter assertion condition validity timestamps. Setting to -1 will disable checking these conditions entirely. - default: 0 - order: 22 - disableRequestedAuthnContext: - type: Boolean - title: Disable Requested Auth Context - hint: If enabled, do not request a specific authentication context. This is known to help when authenticating against Active Directory (AD FS) servers. - default: false - order: 23 - authnContext: - type: String - title: Auth Context - hint: Name identifier format to request auth context. For multiple values, join them together using the | pipe symbol. - default: urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport - order: 24 - racComparison: - type: String - title: RAC Comparison Type - hint: Requested Authentication Context comparison type. - maxWidth: 400 - order: 25 - default: exact - enum: - - exact - - minimum - - maximum - - better - forceAuthn: - type: Boolean - title: Force Initial Re-authentication - hint: If enabled, the initial SAML request from the service provider specifies that the IdP should force re-authentication of the user, even if they possess a valid session. - default: false - order: 26 - passive: - type: Boolean - title: Passive - hint: If enabled, the initial SAML request from the service provider specifies that the IdP should prevent visible user interaction. - default: false - order: 27 - providerName: - type: String - title: Provider Name - hint: Optional human-readable name of the requester for use by the presenter's user agent or the identity provider. - default: wiki.js - order: 28 - skipRequestCompression: - type: Boolean - title: Skip Request Compression - hint: If enabled, the SAML request from the service provider won't be compressed. - default: false - order: 29 - authnRequestBinding: - type: String - title: Request Binding - hint: Binding used for request authentication from IDP. - maxWidth: 400 - order: 30 - default: 'HTTP-POST' - enum: - - HTTP-Redirect - - HTTP-POST - mappingUID: - title: Unique ID Field Mapping - type: String - default: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' - hint: The field storing the user unique identifier. Can be a variable name or a URI-formatted string. - order: 40 - mappingEmail: - title: Email Field Mapping - type: String - default: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress' - hint: The field storing the user email. Can be a variable name or a URI-formatted string. - order: 41 - mappingDisplayName: - title: Display Name Field Mapping - type: String - default: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name' - hint: The field storing the user display name. Can be a variable name or a URI-formatted string. - order: 42 - mappingPicture: - title: Avatar Picture Field Mapping - type: String - default: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/picture' - hint: The field storing the user avatar picture. Can be a variable name or a URI-formatted string. - order: 43 diff --git a/server/modules/authentication/slack/authentication.js b/server/modules/authentication/slack/authentication.js deleted file mode 100644 index c8d568e6a..000000000 --- a/server/modules/authentication/slack/authentication.js +++ /dev/null @@ -1,36 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Slack Account -// ------------------------------------ - -const SlackStrategy = require('passport-slack-oauth2').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new SlackStrategy({ - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - team: conf.team, - scope: ['identity.basic', 'identity.email', 'identity.avatar'], - passReqToCallback: true - }, async (req, accessToken, refreshToken, { user: userProfile }, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...userProfile, - picture: _.get(userProfile, 'image_48', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - } - )) - } -} diff --git a/server/modules/authentication/slack/definition.yml b/server/modules/authentication/slack/definition.yml deleted file mode 100644 index 3b0f51efe..000000000 --- a/server/modules/authentication/slack/definition.yml +++ /dev/null @@ -1,37 +0,0 @@ -key: slack -title: Slack -description: Slack is a cloud-based set of proprietary team collaboration tools and services. -author: requarks.io -logo: https://static.requarks.io/logo/slack.svg -icon: /_assets/icons/ultraviolet-slack.svg -color: green -website: https://api.slack.com/docs/oauth -isAvailable: true -useForm: false -scopes: - - identity.basic - - identity.email - - identity.avatar -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - sensitive: true - order: 2 - team: - type: String - title: Team / Workspace ID - hint: Optional - Your unique team (workspace) identifier - order: 3 -refs: - callbackUrl: - title: Authorization Callback URL - hint: The callback endpoint to input on Slack. - icon: back - value: '{host}/login/{id}/callback' diff --git a/server/modules/authentication/twitch/authentication.js b/server/modules/authentication/twitch/authentication.js deleted file mode 100644 index e11ee4dc6..000000000 --- a/server/modules/authentication/twitch/authentication.js +++ /dev/null @@ -1,34 +0,0 @@ -/* global WIKI */ - -// ------------------------------------ -// Twitch Account -// ------------------------------------ - -const TwitchStrategy = require('passport-twitch-strategy').Strategy -const _ = require('lodash') - -module.exports = { - init (passport, conf) { - passport.use(conf.key, - new TwitchStrategy({ - clientID: conf.clientId, - clientSecret: conf.clientSecret, - callbackURL: conf.callbackURL, - passReqToCallback: true - }, async (req, accessToken, refreshToken, profile, cb) => { - try { - const user = await WIKI.db.users.processProfile({ - providerKey: req.params.strategy, - profile: { - ...profile, - picture: _.get(profile, 'profile_image_url', '') - } - }) - cb(null, user) - } catch (err) { - cb(err, null) - } - } - )) - } -} diff --git a/server/modules/authentication/twitch/definition.yml b/server/modules/authentication/twitch/definition.yml deleted file mode 100644 index 84f7587ad..000000000 --- a/server/modules/authentication/twitch/definition.yml +++ /dev/null @@ -1,23 +0,0 @@ -key: twitch -title: Twitch -description: Twitch is a live streaming video platform. -author: requarks.io -logo: https://static.requarks.io/logo/twitch.svg -icon: /_assets/icons/ultraviolet-twitch.svg -color: indigo darken-2 -website: https://dev.twitch.tv/docs/authentication/ -isAvailable: true -useForm: false -scopes: - - 'user:read:email' -props: - clientId: - type: String - title: Client ID - hint: Application Client ID - order: 1 - clientSecret: - type: String - title: Client Secret - hint: Application Client Secret - order: 2 diff --git a/server/modules/comments/commento/code.yml b/server/modules/comments/commento/code.yml deleted file mode 100644 index 2d4ca9116..000000000 --- a/server/modules/comments/commento/code.yml +++ /dev/null @@ -1,12 +0,0 @@ -main: | -
-body: | - diff --git a/server/modules/comments/commento/definition.yml b/server/modules/comments/commento/definition.yml deleted file mode 100644 index 904c7cf11..000000000 --- a/server/modules/comments/commento/definition.yml +++ /dev/null @@ -1,16 +0,0 @@ -key: commento -title: Commento -description: A fast, privacy-focused commenting platform. -author: requarks.io -logo: https://static.requarks.io/logo/commento.svg -website: https://commento.io/ -codeTemplate: true -isAvailable: true -props: - instanceUrl: - type: String - title: Instance URL - default: 'https://cdn.commento.io' - hint: The URL (without a trailing slash) to the Commento instance. Leave the default https://cdn.commento.io if using the cloud-hosted version. - order: 1 - diff --git a/server/modules/comments/default/comment.js b/server/modules/comments/default/comment.js deleted file mode 100644 index 4f878b982..000000000 --- a/server/modules/comments/default/comment.js +++ /dev/null @@ -1,157 +0,0 @@ -const md = require('markdown-it') -const mdEmoji = require('markdown-it-emoji') -const { JSDOM } = require('jsdom') -const createDOMPurify = require('dompurify') -const _ = require('lodash') -const { AkismetClient } = require('akismet-api') -const moment = require('moment') - -const window = new JSDOM('').window -const DOMPurify = createDOMPurify(window) - -let akismetClient = null - -const mkdown = md({ - html: false, - breaks: true, - linkify: true, - highlight(str, lang) { - return `
${_.escape(str)}
` - } -}) - -mkdown.use(mdEmoji) - -// ------------------------------------ -// Default Comment Provider -// ------------------------------------ - -module.exports = { - /** - * Init - */ - async init (config) { - WIKI.logger.info('(COMMENTS/DEFAULT) Initializing...') - if (WIKI.data.commentProvider.config.akismet && WIKI.data.commentProvider.config.akismet.length > 2) { - akismetClient = new AkismetClient({ - key: WIKI.data.commentProvider.config.akismet, - blog: WIKI.config.host, - lang: WIKI.config.lang.namespacing ? WIKI.config.lang.namespaces.join(', ') : WIKI.config.lang.code, - charset: 'UTF-8' - }) - try { - const isValid = await akismetClient.verifyKey() - if (!isValid) { - akismetClient = null - WIKI.logger.warn('(COMMENTS/DEFAULT) Akismet Key is invalid! [ DISABLED ]') - } else { - WIKI.logger.info('(COMMENTS/DEFAULT) Akismet key is valid. [ OK ]') - } - } catch (err) { - akismetClient = null - WIKI.logger.warn('(COMMENTS/DEFAULT) Unable to verify Akismet Key: ' + err.message) - } - } else { - akismetClient = null - } - WIKI.logger.info('(COMMENTS/DEFAULT) Initialization completed.') - }, - /** - * Create New Comment - */ - async create ({ page, replyTo, content, user }) { - // -> Build New Comment - const newComment = { - content, - render: DOMPurify.sanitize(mkdown.render(content)), - replyTo, - pageId: page.id, - authorId: user.id, - name: user.name, - email: user.email, - ip: user.ip - } - - // -> Check for Spam with Akismet - if (akismetClient) { - let userRole = 'user' - if (user.groups.indexOf(1) >= 0) { - userRole = 'administrator' - } else if (user.groups.indexOf(2) >= 0) { - userRole = 'guest' - } - - let isSpam = false - try { - isSpam = await akismetClient.checkSpam({ - ip: user.ip, - useragent: user.agentagent, - content, - name: user.name, - email: user.email, - permalink: `${WIKI.config.host}/${page.locale}/${page.path}`, - permalinkDate: page.updatedAt, - type: (replyTo > 0) ? 'reply' : 'comment', - role: userRole - }) - } catch (err) { - WIKI.logger.warn('Akismet Comment Validation: [ FAILED ]') - WIKI.logger.warn(err) - } - - if (isSpam) { - throw new Error('Comment was rejected because it is marked as spam.') - } - } - - // -> Check for minimum delay between posts - if (WIKI.data.commentProvider.config.minDelay > 0) { - const lastComment = await WIKI.db.comments.query().select('updatedAt').findOne('authorId', user.id).orderBy('updatedAt', 'desc') - if (lastComment && moment().subtract(WIKI.data.commentProvider.config.minDelay, 'seconds').isBefore(lastComment.updatedAt)) { - throw new Error('Your administrator has set a time limit before you can post another comment. Try again later.') - } - } - - // -> Save Comment to DB - const cm = await WIKI.db.comments.query().insert(newComment) - - // -> Return Comment ID - return cm.id - }, - /** - * Update an existing comment - */ - async update ({ id, content, user }) { - const renderedContent = DOMPurify.sanitize(mkdown.render(content)) - await WIKI.db.comments.query().findById(id).patch({ - render: renderedContent - }) - return renderedContent - }, - /** - * Delete an existing comment by ID - */ - async remove ({ id, user }) { - return WIKI.db.comments.query().findById(id).delete() - }, - /** - * Get the page ID from a comment ID - */ - async getPageIdFromCommentId (id) { - const result = await WIKI.db.comments.query().select('pageId').findById(id) - return (result) ? result.pageId : false - }, - /** - * Get a comment by ID - */ - async getCommentById (id) { - return WIKI.db.comments.query().findById(id) - }, - /** - * Get the total comments count for a page ID - */ - async count (pageId) { - const result = await WIKI.db.comments.query().count('* as total').where('pageId', pageId).first() - return _.toSafeInteger(result.total) - } -} diff --git a/server/modules/comments/default/definition.yml b/server/modules/comments/default/definition.yml deleted file mode 100644 index 4eceee521..000000000 --- a/server/modules/comments/default/definition.yml +++ /dev/null @@ -1,23 +0,0 @@ -key: default -title: Default -description: Built-in advanced comments tool. -author: requarks.io -logo: https://static.requarks.io/logo/wikijs-butterfly.svg -website: https://wiki.js.org -codeTemplate: false -isAvailable: true -props: - akismet: - type: String - title: Akismet API Key - default: '' - hint: 'Prevent spam by using the Akismet service. Enter your API key here to enable. Leave empty to disable.' - maxWidth: 650 - order: 1 - minDelay: - type: Number - title: Post delay - default: 30 - hint: 'Minimum delay (in seconds) between comments per account. Note that all guests are considered as a single account.' - maxWidth: 400 - order: 2 diff --git a/server/modules/comments/disqus/code.yml b/server/modules/comments/disqus/code.yml deleted file mode 100644 index e123d5b30..000000000 --- a/server/modules/comments/disqus/code.yml +++ /dev/null @@ -1,15 +0,0 @@ -main: | -
-body: | - diff --git a/server/modules/comments/disqus/definition.yml b/server/modules/comments/disqus/definition.yml deleted file mode 100644 index 61193925a..000000000 --- a/server/modules/comments/disqus/definition.yml +++ /dev/null @@ -1,15 +0,0 @@ -key: disqus -title: Disqus -description: Disqus help publishers power online discussions with comments. -author: requarks.io -logo: https://static.requarks.io/logo/disqus.svg -website: https://disqus.com/ -codeTemplate: true -isAvailable: true -props: - accountName: - type: String - title: Shortname - default: '' - hint: Unique identifier from Disqus to identify your website - order: 1 diff --git a/server/modules/extensions/git/ext.mjs b/server/modules/extensions/git/ext.mjs deleted file mode 100644 index d44ebc57e..000000000 --- a/server/modules/extensions/git/ext.mjs +++ /dev/null @@ -1,21 +0,0 @@ -import cmdExists from 'command-exists' - -export default { - key: 'git', - title: 'Git', - description: 'Distributed version control system. Required for the Git storage module.', - isInstalled: false, - isInstallable: false, - async isCompatible () { - return true - }, - async check () { - try { - await cmdExists('git') - this.isInstalled = true - } catch (err) { - this.isInstalled = false - } - return this.isInstalled - } -} diff --git a/server/modules/extensions/pandoc/ext.mjs b/server/modules/extensions/pandoc/ext.mjs deleted file mode 100644 index 7013d5cec..000000000 --- a/server/modules/extensions/pandoc/ext.mjs +++ /dev/null @@ -1,22 +0,0 @@ -import cmdExists from 'command-exists' -import os from 'node:os' - -export default { - key: 'pandoc', - title: 'Pandoc', - description: 'Convert between markup formats. Required for converting from other formats such as MediaWiki, AsciiDoc, Textile and other wikis.', - async isCompatible () { - return os.arch() === 'x64' - }, - isInstalled: false, - isInstallable: false, - async check () { - try { - await cmdExists('pandoc') - this.isInstalled = true - } catch (err) { - this.isInstalled = false - } - return this.isInstalled - } -} diff --git a/server/modules/extensions/puppeteer/ext.mjs b/server/modules/extensions/puppeteer/ext.mjs deleted file mode 100644 index e28b78ef6..000000000 --- a/server/modules/extensions/puppeteer/ext.mjs +++ /dev/null @@ -1,43 +0,0 @@ -import os from 'node:os' -import path from 'node:path' -import util from 'node:util' -import { exec as execSync } from 'node:child_process' -import fse from 'fs-extra' - -const exec = util.promisify(execSync) - -export default { - key: 'puppeteer', - title: 'Puppeteer', - description: 'Headless chromium browser for server-side rendering. Required for generating PDF versions of pages and render content elements on the server (e.g. Mermaid diagrams)', - async isCompatible () { - return os.arch() === 'x64' - }, - isInstalled: false, - isInstallable: true, - async check () { - try { - this.isInstalled = await fse.pathExists(path.join(WIKI.SERVERPATH, 'node_modules/puppeteer-core/.local-chromium')) - } catch (err) { - this.isInstalled = false - } - return this.isInstalled - }, - async install () { - try { - // TODO: https://pptr.dev/browsers-api/ - // const { stdout, stderr } = await exec('node install.js', { - // cwd: path.join(WIKI.SERVERPATH, 'node_modules/puppeteer-core'), - // timeout: 300000, - // windowsHide: true - // }) - // this.isInstalled = true - // WIKI.logger.info(stdout) - // WIKI.logger.warn(stderr) - throw new Error('Not implemented yet.') - } catch (err) { - WIKI.logger.error(err) - throw err - } - } -} diff --git a/server/modules/extensions/sharp/ext.mjs b/server/modules/extensions/sharp/ext.mjs deleted file mode 100644 index 19b6fe422..000000000 --- a/server/modules/extensions/sharp/ext.mjs +++ /dev/null @@ -1,88 +0,0 @@ -import fse from 'fs-extra' -import os from 'node:os' -import path from 'node:path' -import util from 'node:util' -import { exec as execSync } from 'node:child_process' -import { pipeline } from 'node:stream/promises' - -const exec = util.promisify(execSync) - -export default { - key: 'sharp', - title: 'Sharp', - description: 'Process and transform images. Required to generate thumbnails of uploaded images and perform transformations.', - async isCompatible () { - return os.arch() === 'x64' - }, - isInstalled: false, - isInstallable: true, - async check () { - this.isInstalled = await fse.pathExists(path.join(WIKI.SERVERPATH, 'node_modules/sharp/wiki_installed.txt')) - return this.isInstalled - }, - async install () { - try { - const { stdout, stderr } = await exec('node install/check', { - cwd: path.join(WIKI.SERVERPATH, 'node_modules/sharp'), - timeout: 120000, - windowsHide: true - }) - await fse.ensureFile(path.join(WIKI.SERVERPATH, 'node_modules/sharp/wiki_installed.txt')) - this.isInstalled = true - WIKI.logger.info(stdout) - WIKI.logger.warn(stderr) - } catch (err) { - WIKI.logger.error(err) - } - }, - sharp: null, - async load () { - if (!this.sharp) { - this.sharp = (await import('sharp')).default - } - }, - /** - * RESIZE IMAGE - */ - async resize ({ - format = 'png', - inputStream = null, - inputPath = null, - outputStream = null, - outputPath = null, - width = null, - height = null, - fit = 'cover', - background = { r: 0, g: 0, b: 0, alpha: 0 }, - kernel = 'lanczos3' - }) { - await this.load() - - if (inputPath) { - inputStream = fse.createReadStream(inputPath) - } - if (!inputStream) { - throw new Error('Failed to open readable input stream for image resizing.') - } - if (outputPath) { - outputStream = fse.createWriteStream(outputPath) - } - if (!outputStream) { - throw new Error('Failed to open writable output stream for image resizing.') - } - - if (format === 'svg') { - return pipeline([inputStream, outputStream]) - } else { - const transformer = this.sharp().resize({ - width, - height, - fit, - background, - kernel - }).toFormat(format) - - return pipeline([inputStream, transformer, outputStream]) - } - } -} diff --git a/server/modules/rendering/asciinema/definition.yml b/server/modules/rendering/asciinema/definition.yml deleted file mode 100644 index e1bba61c9..000000000 --- a/server/modules/rendering/asciinema/definition.yml +++ /dev/null @@ -1,7 +0,0 @@ -title: Asciinema -description: Embed asciinema players from compatible links -author: requarks.io -icon: mdi-theater -enabledDefault: false -dependsOn: core -props: {} diff --git a/server/modules/rendering/asciinema/renderer.mjs b/server/modules/rendering/asciinema/renderer.mjs deleted file mode 100644 index 67c19c898..000000000 --- a/server/modules/rendering/asciinema/renderer.mjs +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - init($, config) { - - } -} diff --git a/server/modules/rendering/blockquotes/definition.yml b/server/modules/rendering/blockquotes/definition.yml deleted file mode 100644 index c2a250db4..000000000 --- a/server/modules/rendering/blockquotes/definition.yml +++ /dev/null @@ -1,7 +0,0 @@ -title: Blockquotes -description: Parse blockquotes box styling -author: requarks.io -icon: mdi-alpha-t-box-outline -enabledDefault: true -dependsOn: core -props: {} diff --git a/server/modules/rendering/blockquotes/renderer.mjs b/server/modules/rendering/blockquotes/renderer.mjs deleted file mode 100644 index 67c19c898..000000000 --- a/server/modules/rendering/blockquotes/renderer.mjs +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - init($, config) { - - } -} diff --git a/server/modules/rendering/codehighlighter/definition.yml b/server/modules/rendering/codehighlighter/definition.yml deleted file mode 100644 index 55480e414..000000000 --- a/server/modules/rendering/codehighlighter/definition.yml +++ /dev/null @@ -1,8 +0,0 @@ -title: Code Highlighting Post-Processor -description: Syntax detector for programming code -author: requarks.io -icon: mdi-code-braces -enabledDefault: true -dependsOn: core -step: pre -props: {} diff --git a/server/modules/rendering/codehighlighter/renderer.mjs b/server/modules/rendering/codehighlighter/renderer.mjs deleted file mode 100644 index 0f19e63f0..000000000 --- a/server/modules/rendering/codehighlighter/renderer.mjs +++ /dev/null @@ -1,14 +0,0 @@ -const hljs = require('highlight.js') - -module.exports = { - async init($, config) { - $('pre > code').each((idx, elm) => { - const codeClasses = $(elm).attr('class') || '' - if (codeClasses.indexOf('language-') < 0) { - const result = hljs.highlightAuto($(elm).text()) - $(elm).addClass('language-', result.language) - } - $(elm).parent().addClass('prismjs line-numbers') - }) - } -} diff --git a/server/modules/rendering/core/definition.yml b/server/modules/rendering/core/definition.yml deleted file mode 100644 index c8df59910..000000000 --- a/server/modules/rendering/core/definition.yml +++ /dev/null @@ -1,27 +0,0 @@ -key: core -title: Core -description: Basic HTML Parser -author: requarks.io -icon: mdi-language-html5 -props: - absoluteLinks: - type: Boolean - default: false - title: Treat relative links as root absolute - hint: For example, a link to foo/bar on page xyz will render as /foo/bar instead of /xyz/foo/bar. - order: 1 - openExternalLinkNewTab: - type: Boolean - default: false - title: Open external links in a new tab - hint: External links will have a _blank target attribute added automatically. - order: 2 - relAttributeExternalLink: - type: String - default: noreferrer - title: Protect against XSS when opening _blank target links - hint: External links with _blank attribute will have an additional rel attribute. - order: 3 - enum: - - noreferrer - - noopener diff --git a/server/modules/rendering/core/renderer.mjs b/server/modules/rendering/core/renderer.mjs deleted file mode 100644 index 12f8b22e2..000000000 --- a/server/modules/rendering/core/renderer.mjs +++ /dev/null @@ -1,286 +0,0 @@ -import { reject } from 'lodash-es' -import * as cheerio from 'cheerio' -import uslug from 'uslug' -import pageHelper from '../../../helpers/page' -import { URL } from 'node:url' - -const mustacheRegExp = /(\{|{?){2}(.+?)(\}|}?){2}/i - -export async function render () { - const $ = cheerio.load(this.input, { - decodeEntities: true - }) - - if ($.root().children().length < 1) { - return '' - } - - // -------------------------------- - // STEP: PRE - // -------------------------------- - - for (const child of reject(this.children, ['step', 'post'])) { - const renderer = (await import(`../${kebabCase(child.key)}/renderer.mjs`)).render - await renderer($, child.config) - } - - // -------------------------------- - // Detect internal / external links - // -------------------------------- - - let internalRefs = [] - const reservedPrefixes = /^\/[a-z]\//i - const exactReservedPaths = /^\/[a-z]$/i - - const hasHostname = this.site.hostname !== '*' - - $('a').each((i, elm) => { - let href = $(elm).attr('href') - - // -> Ignore empty / anchor links, e-mail addresses, and telephone numbers - if (!href || href.length < 1 || href.indexOf('#') === 0 || - href.indexOf('mailto:') === 0 || href.indexOf('tel:') === 0) { - return - } - - // -> Strip host from local links - if (hasHostname && href.indexOf(`${this.site.hostname}/`) === 0) { - href = href.replace(this.site.hostname, '') - } - - // -> Assign local / external tag - if (href.indexOf('://') < 0) { - // -> Remove trailing slash - if (_.endsWith('/')) { - href = href.slice(0, -1) - } - - // -> Check for system prefix - if (reservedPrefixes.test(href) || exactReservedPaths.test(href)) { - $(elm).addClass(`is-system-link`) - } else if (href.indexOf('.') >= 0) { - $(elm).addClass(`is-asset-link`) - } else { - let pagePath = null - - // -> Add locale prefix if using namespacing - if (this.site.config.localeNamespacing) { - // -> Reformat paths - if (href.indexOf('/') !== 0) { - if (this.config.absoluteLinks) { - href = `/${this.page.locale}/${href}` - } else { - href = (this.page.path === 'home') ? `/${this.page.locale}/${href}` : `/${this.page.locale}/${this.page.path}/${href}` - } - } else if (href.charAt(3) !== '/') { - href = `/${this.page.locale}${href}` - } - - try { - const parsedUrl = new URL(`http://x${href}`) - pagePath = pageHelper.parsePath(parsedUrl.pathname) - } catch (err) { - return - } - } else { - // -> Reformat paths - if (href.indexOf('/') !== 0) { - if (this.config.absoluteLinks) { - href = `/${href}` - } else { - href = (this.page.path === 'home') ? `/${href}` : `/${this.page.path}/${href}` - } - } - - try { - const parsedUrl = new URL(`http://x${href}`) - pagePath = pageHelper.parsePath(parsedUrl.pathname) - } catch (err) { - return - } - } - // -> Save internal references - internalRefs.push({ - locale: pagePath.locale, - path: pagePath.path - }) - - $(elm).addClass(`is-internal-link`) - } - } else { - $(elm).addClass(`is-external-link`) - if (this.config.openExternalLinkNewTab) { - $(elm).attr('target', '_blank') - $(elm).attr('rel', this.config.relAttributeExternalLink) - } - } - - // -> Update element - $(elm).attr('href', href) - }) - - // -------------------------------- - // Detect internal link states - // -------------------------------- - - const pastLinks = await this.page.$relatedQuery('links') - - if (internalRefs.length > 0) { - // -> Find matching pages - const results = await WIKI.db.pages.query().column('id', 'path', 'locale').where(builder => { - internalRefs.forEach((ref, idx) => { - if (idx < 1) { - builder.where(ref) - } else { - builder.orWhere(ref) - } - }) - }) - - // -> Apply tag to internal links for found pages - $('a.is-internal-link').each((i, elm) => { - const href = $(elm).attr('href') - let hrefObj = {} - try { - const parsedUrl = new URL(`http://x${href}`) - hrefObj = pageHelper.parsePath(parsedUrl.pathname) - } catch (err) { - return - } - if (_.some(results, r => { - return r.locale === hrefObj.locale && r.path === hrefObj.path - })) { - $(elm).addClass(`is-valid-page`) - } else { - $(elm).addClass(`is-invalid-page`) - } - }) - - // -> Add missing links - const missingLinks = _.differenceWith(internalRefs, pastLinks, (nLink, pLink) => { - return nLink.locale === pLink.locale && nLink.path === pLink.path - }) - if (missingLinks.length > 0) { - if (WIKI.config.db.type === 'postgres') { - await WIKI.db.pageLinks.query().insert(missingLinks.map(lnk => ({ - pageId: this.page.id, - path: lnk.path, - locale: lnk.locale - }))) - } else { - for (const lnk of missingLinks) { - await WIKI.db.pageLinks.query().insert({ - pageId: this.page.id, - path: lnk.path, - locale: lnk.locale - }) - } - } - } - } - - // -> Remove outdated links - if (pastLinks) { - const outdatedLinks = _.differenceWith(pastLinks, internalRefs, (nLink, pLink) => { - return nLink.locale === pLink.locale && nLink.path === pLink.path - }) - if (outdatedLinks.length > 0) { - await WIKI.db.pageLinks.query().delete().whereIn('id', _.map(outdatedLinks, 'id')) - } - } - - // -------------------------------- - // Add header handles - // -------------------------------- - - let headers = [] - $('h1,h2,h3,h4,h5,h6').each((i, elm) => { - let headerSlug = uslug($(elm).text()) - // -> If custom ID is defined, try to use that instead - if ($(elm).attr('id')) { - headerSlug = $(elm).attr('id') - } - - // -> Cannot start with a number (CSS selector limitation) - if (headerSlug.match(/^\d/)) { - headerSlug = `h-${headerSlug}` - } - - // -> Make sure header is unique - if (headers.indexOf(headerSlug) >= 0) { - let isUnique = false - let hIdx = 1 - while (!isUnique) { - const headerSlugTry = `${headerSlug}-${hIdx}` - if (headers.indexOf(headerSlugTry) < 0) { - isUnique = true - headerSlug = headerSlugTry - } - hIdx++ - } - } - - // -> Add anchor - $(elm).attr('id', headerSlug).addClass('toc-header') - $(elm).prepend(`
`) - - headers.push(headerSlug) - }) - - // -------------------------------- - // Wrap non-empty root text nodes - // -------------------------------- - - $('body').contents().toArray().forEach(item => { - if (item && item.type === 'text' && item.parent.name === 'body' && item.data !== `\n` && item.data !== `\r`) { - $(item).wrap('
') - } - }) - - // -------------------------------- - // Escape mustache expresions - // -------------------------------- - - function iterateMustacheNode (node) { - const list = $(node).contents().toArray() - list.forEach(item => { - if (item && item.type === 'text') { - const rawText = $(item).text().replace(/\r?\n|\r/g, '') - if (mustacheRegExp.test(rawText)) { - $(item).parent().attr('v-pre', true) - } - } else { - iterateMustacheNode(item) - } - }) - } - iterateMustacheNode($.root()) - - $('pre').each((idx, elm) => { - $(elm).attr('v-pre', true) - }) - - // -------------------------------- - // STEP: POST - // -------------------------------- - - let output = decodeEscape($.html('body').replace('', '').replace('', '')) - - for (let child of _.sortBy(_.filter(this.children, ['step', 'post']), ['order'])) { - const renderer = require(`../${_.kebabCase(child.key)}/renderer.js`) - output = await renderer.init(output, child.config) - } - - return output -} - -function decodeEscape (string) { - return string.replace(/&#x([0-9a-f]{1,6});/ig, (entity, code) => { - code = parseInt(code, 16) - - // Don't unescape ASCII characters, assuming they're encoded for a good reason - if (code < 0x80) return entity - - return String.fromCodePoint(code) - }) -} diff --git a/server/modules/rendering/diagram/definition.yml b/server/modules/rendering/diagram/definition.yml deleted file mode 100644 index bdf9bf2bb..000000000 --- a/server/modules/rendering/diagram/definition.yml +++ /dev/null @@ -1,7 +0,0 @@ -title: Diagrams Post-Processor -description: HTML Processing for diagrams (draw.io) -author: requarks.io -icon: mdi-chart-multiline -enabledDefault: true -dependsOn: core -props: {} diff --git a/server/modules/rendering/diagram/renderer.mjs b/server/modules/rendering/diagram/renderer.mjs deleted file mode 100644 index 32b3088d2..000000000 --- a/server/modules/rendering/diagram/renderer.mjs +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - async init($, config) { - $(`pre.diagram`).each((idx, elm) => { - $(elm).children('svg').each((sidx, svg) => { - $(svg).removeAttr('content') - }) - $(elm).replaceWith($(`
${$(elm).html()}
`)) - }) - } -} diff --git a/server/modules/rendering/image-prefetch/definition.yml b/server/modules/rendering/image-prefetch/definition.yml deleted file mode 100644 index 8b456a6a0..000000000 --- a/server/modules/rendering/image-prefetch/definition.yml +++ /dev/null @@ -1,7 +0,0 @@ -title: Image Prefetch -description: Prefetch remotely rendered images (korki/plantuml) -author: requarks.io -icon: mdi-cloud-download-outline -enabledDefault: false -dependsOn: core -props: {} diff --git a/server/modules/rendering/image-prefetch/renderer.mjs b/server/modules/rendering/image-prefetch/renderer.mjs deleted file mode 100644 index 3e3eecd7b..000000000 --- a/server/modules/rendering/image-prefetch/renderer.mjs +++ /dev/null @@ -1,30 +0,0 @@ -// TODO: refactor to use fetch() - -// const prefetch = async (element) => { -// const url = element.attr(`src`) -// let response -// try { -// response = await request({ -// method: `GET`, -// url, -// resolveWithFullResponse: true -// }) -// } catch (err) { -// WIKI.logger.warn(`Failed to prefetch ${url}`) -// WIKI.logger.warn(err) -// return -// } -// const contentType = response.headers[`content-type`] -// const image = Buffer.from(response.body).toString('base64') -// element.attr('src', `data:${contentType};base64,${image}`) -// element.removeClass('prefetch-candidate') -// } - -module.exports = { - async init($) { - // const promises = $('img.prefetch-candidate').map((index, element) => { - // return prefetch($(element)) - // }).toArray() - // await Promise.all(promises) - } -} diff --git a/server/modules/rendering/mediaplayers/definition.yml b/server/modules/rendering/mediaplayers/definition.yml deleted file mode 100644 index 9839c0fb8..000000000 --- a/server/modules/rendering/mediaplayers/definition.yml +++ /dev/null @@ -1,7 +0,0 @@ -title: Media Players -description: Embed players such as Youtube, Vimeo, Soundcloud, etc. -author: requarks.io -icon: mdi-video -enabledDefault: true -dependsOn: core -props: {} diff --git a/server/modules/rendering/mediaplayers/renderer.mjs b/server/modules/rendering/mediaplayers/renderer.mjs deleted file mode 100644 index 67c19c898..000000000 --- a/server/modules/rendering/mediaplayers/renderer.mjs +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - init($, config) { - - } -} diff --git a/server/modules/rendering/mermaid/definition.yml b/server/modules/rendering/mermaid/definition.yml deleted file mode 100644 index e5c5ce833..000000000 --- a/server/modules/rendering/mermaid/definition.yml +++ /dev/null @@ -1,7 +0,0 @@ -title: Mermaid -description: Generate flowcharts from Mermaid syntax -author: requarks.io -icon: mdi-arrow-decision-outline -enabledDefault: true -dependsOn: core -props: {} diff --git a/server/modules/rendering/mermaid/renderer.mjs b/server/modules/rendering/mermaid/renderer.mjs deleted file mode 100644 index b4faf48ba..000000000 --- a/server/modules/rendering/mermaid/renderer.mjs +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - init($, config) { - $('pre.prismjs > code.language-mermaid').each((i, elm) => { - const mermaidContent = $(elm).html() - $(elm).parent().replaceWith(`
${mermaidContent}
`) - }) - } -} diff --git a/server/modules/rendering/security/definition.yml b/server/modules/rendering/security/definition.yml deleted file mode 100644 index 9beb29c9f..000000000 --- a/server/modules/rendering/security/definition.yml +++ /dev/null @@ -1,27 +0,0 @@ -title: Security -description: Filter and strips potentially dangerous content -author: requarks.io -icon: mdi-fire -enabledDefault: true -dependsOn: core -step: post -order: 99999 -props: - safeHTML: - type: Boolean - title: Sanitize HTML - default: true - hint: Sanitize HTML from unsafe attributes and tags that could lead to XSS attacks - order: 1 - allowDrawIoUnsafe: - type: Boolean - title: Allow Draw.io Unsafe Elements - default: true - hint: Draw.io diagrams may introduce some elements that are usually filtered. Turning off this option may cause some diagrams to be completely removed during the sanitization process. - order: 2 - allowIFrames: - type: Boolean - title: Allow iframes - default: false - hint: iframes will not be stripped if enabled. (Not recommended) - order: 3 diff --git a/server/modules/rendering/security/renderer.mjs b/server/modules/rendering/security/renderer.mjs deleted file mode 100644 index 3bf9b2dc0..000000000 --- a/server/modules/rendering/security/renderer.mjs +++ /dev/null @@ -1,42 +0,0 @@ -const { JSDOM } = require('jsdom') -const createDOMPurify = require('dompurify') - -module.exports = { - async init(input, config) { - if (config.safeHTML) { - const window = new JSDOM('').window - const DOMPurify = createDOMPurify(window) - - const allowedAttrs = ['v-pre', 'v-slot:tabs', 'v-slot:content', 'target'] - const allowedTags = ['tabset', 'template'] - - if (config.allowDrawIoUnsafe) { - allowedTags.push('foreignObject') - DOMPurify.addHook('uponSanitizeElement', (elm) => { - if (elm.querySelectorAll) { - const breaks = elm.querySelectorAll('foreignObject br, foreignObject p') - if (breaks && breaks.length) { - for (let i = 0; i < breaks.length; i++) { - breaks[i].parentNode.replaceChild( - window.document.createElement('div'), - breaks[i] - ) - } - } - } - }) - } - - if (config.allowIFrames) { - allowedTags.push('iframe') - allowedAttrs.push('allow') - } - - input = DOMPurify.sanitize(input, { - ADD_ATTR: allowedAttrs, - ADD_TAGS: allowedTags - }) - } - return input - } -} diff --git a/server/modules/rendering/tabset/definition.yml b/server/modules/rendering/tabset/definition.yml deleted file mode 100644 index c6c82c510..000000000 --- a/server/modules/rendering/tabset/definition.yml +++ /dev/null @@ -1,7 +0,0 @@ -title: Tabsets -description: Transform headers into tabs -author: requarks.io -icon: mdi-tab -enabledDefault: true -dependsOn: core -props: {} diff --git a/server/modules/rendering/tabset/renderer.mjs b/server/modules/rendering/tabset/renderer.mjs deleted file mode 100644 index 0b3631e8b..000000000 --- a/server/modules/rendering/tabset/renderer.mjs +++ /dev/null @@ -1,27 +0,0 @@ -const _ = require('lodash') - -module.exports = { - async init($, config) { - for (let i = 1; i < 6; i++) { - $(`h${i}.tabset`).each((idx, elm) => { - let content = `` - let tabs = [] - let tabContents = [] - $(elm).nextUntil(_.times(i, t => `h${t + 1}`).join(', '), `h${i + 1}`).each((hidx, hd) => { - tabs.push(`
  • ${$(hd).html()}
  • `) - let tabContent = '' - $(hd).nextUntil(_.times(i + 1, t => `h${t + 1}`).join(', ')).each((cidx, celm) => { - tabContent += $.html(celm) - $(celm).remove() - }) - tabContents.push(`
    ${tabContent}
    `) - $(hd).remove() - }) - content += `` - content += `` - content += `
    ` - $(elm).replaceWith($(content)) - }) - } - } -} diff --git a/server/modules/rendering/twemoji/definition.yml b/server/modules/rendering/twemoji/definition.yml deleted file mode 100644 index 49d8daaa7..000000000 --- a/server/modules/rendering/twemoji/definition.yml +++ /dev/null @@ -1,9 +0,0 @@ -title: Twemoji -description: Apply Twitter Emojis to all Unicode emojis -author: requarks.io -icon: mdi-emoticon-happy-outline -enabledDefault: true -dependsOn: core -step: post -order: 10 -props: {} diff --git a/server/modules/rendering/twemoji/renderer.mjs b/server/modules/rendering/twemoji/renderer.mjs deleted file mode 100644 index 9ba105392..000000000 --- a/server/modules/rendering/twemoji/renderer.mjs +++ /dev/null @@ -1,14 +0,0 @@ -// const twemoji = require('twemoji') - -// ------------------------------------ -// HTML - Twemoji -// ------------------------------------ - -module.exports = { - init (input, conf) { - // TODO: Must limit to text nodes only (exclude code blocks, already processed emojis, etc.) - // - // return twemoji.parse(input) - return input - } -} diff --git a/server/modules/storage/azure/definition.yml b/server/modules/storage/azure/definition.yml deleted file mode 100644 index 06b0a753a..000000000 --- a/server/modules/storage/azure/definition.yml +++ /dev/null @@ -1,56 +0,0 @@ -title: Azure Blob Storage -icon: '/_assets/icons/ultraviolet-azure.svg' -banner: '/_assets/storage/azure.jpg' -description: Azure Blob Storage is Microsoft's object storage solution for the cloud. Blob storage is optimized for storing massive amounts of unstructured data. -vendor: Microsoft Corporation -website: 'https://azure.microsoft.com' -assetDelivery: - isStreamingSupported: true - isDirectAccessSupported: true - defaultStreamingEnabled: true - defaultDirectAccessEnabled: true -contentTypes: - defaultTypesEnabled: ['images', 'documents', 'others', 'large'] - defaultLargeThreshold: '5MB' -versioning: - isSupported: false - defaultEnabled: false -sync: false -props: - accountName: - type: String - title: Account Name - default: '' - hint: Your unique account name. - icon: 3d-touch - order: 1 - accountKey: - type: String - title: Account Access Key - default: '' - hint: Either key 1 or key 2. - icon: key - sensitive: true - order: 2 - containerName: - type: String - title: Container Name - default: wiki - hint: Will automatically be created if it doesn't exist yet. - icon: shipping-container - order: 3 - storageTier: - type: String - title: Storage Tier - hint: Represents the access tier on a blob. Use Cool for lower storage costs but at higher retrieval costs. - icon: scan-stock - order: 4 - default: cool - enum: - - hot|Hot - - cool|Cool -actions: - exportAll: - label: Export All DB Assets to Azure - hint: Output all content from the DB to Azure Blog Storage, overwriting any existing data. If you enabled Azure Blog Storage after content was created or you temporarily disabled it, you'll want to execute this action to add the missing content. - icon: this-way-up diff --git a/server/modules/storage/azure/storage.js b/server/modules/storage/azure/storage.js deleted file mode 100644 index 6d7fa2ca6..000000000 --- a/server/modules/storage/azure/storage.js +++ /dev/null @@ -1,162 +0,0 @@ -const { BlobServiceClient, StorageSharedKeyCredential } = require('@azure/storage-blob') -const stream = require('stream') -const util = require('node:util') -const pipeline = util.promisify(stream.pipeline) -const pageHelper = require('../../../helpers/page.js') -const _ = require('lodash') - -const getFilePath = (page, pathKey) => { - const fileName = `${page[pathKey]}.${pageHelper.getFileExtension(page.contentType)}` - const withLocaleCode = WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode - return withLocaleCode ? `${page.localeCode}/${fileName}` : fileName -} - -module.exports = { - async activated() { - - }, - async deactivated() { - - }, - async init() { - WIKI.logger.info(`(STORAGE/AZURE) Initializing...`) - const { accountName, accountKey, containerName } = this.config - this.client = new BlobServiceClient( - `https://${accountName}.blob.core.windows.net`, - new StorageSharedKeyCredential(accountName, accountKey) - ) - this.container = this.client.getContainerClient(containerName) - try { - await this.container.create() - } catch (err) { - if (err.statusCode !== 409) { - WIKI.logger.warn(err) - throw err - } - } - WIKI.logger.info(`(STORAGE/AZURE) Initialization completed.`) - }, - async created (page) { - WIKI.logger.info(`(STORAGE/AZURE) Creating file ${page.path}...`) - const filePath = getFilePath(page, 'path') - const pageContent = page.injectMetadata() - const blockBlobClient = this.container.getBlockBlobClient(filePath) - await blockBlobClient.upload(pageContent, pageContent.length, { tier: this.config.storageTier }) - }, - async updated (page) { - WIKI.logger.info(`(STORAGE/AZURE) Updating file ${page.path}...`) - const filePath = getFilePath(page, 'path') - const pageContent = page.injectMetadata() - const blockBlobClient = this.container.getBlockBlobClient(filePath) - await blockBlobClient.upload(pageContent, pageContent.length, { tier: this.config.storageTier }) - }, - async deleted (page) { - WIKI.logger.info(`(STORAGE/AZURE) Deleting file ${page.path}...`) - const filePath = getFilePath(page, 'path') - const blockBlobClient = this.container.getBlockBlobClient(filePath) - await blockBlobClient.delete({ - deleteSnapshots: 'include' - }) - }, - async renamed(page) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Renaming file ${page.path} to ${page.destinationPath}...`) - let sourceFilePath = getFilePath(page, 'path') - let destinationFilePath = getFilePath(page, 'destinationPath') - if (WIKI.config.lang.namespacing) { - if (WIKI.config.lang.code !== page.localeCode) { - sourceFilePath = `${page.localeCode}/${sourceFilePath}` - } - if (WIKI.config.lang.code !== page.destinationLocaleCode) { - destinationFilePath = `${page.destinationLocaleCode}/${destinationFilePath}` - } - } - const sourceBlockBlobClient = this.container.getBlockBlobClient(sourceFilePath) - const destBlockBlobClient = this.container.getBlockBlobClient(destinationFilePath) - await destBlockBlobClient.syncCopyFromURL(sourceBlockBlobClient.url) - await sourceBlockBlobClient.delete({ - deleteSnapshots: 'include' - }) - }, - /** - * ASSET UPLOAD - * - * @param {Object} asset Asset to upload - */ - async assetUploaded (asset) { - WIKI.logger.info(`(STORAGE/AZURE) Creating new file ${asset.path}...`) - const blockBlobClient = this.container.getBlockBlobClient(asset.path) - await blockBlobClient.upload(asset.data, asset.data.length, { tier: this.config.storageTier }) - }, - /** - * ASSET DELETE - * - * @param {Object} asset Asset to delete - */ - async assetDeleted (asset) { - WIKI.logger.info(`(STORAGE/AZURE) Deleting file ${asset.path}...`) - const blockBlobClient = this.container.getBlockBlobClient(asset.path) - await blockBlobClient.delete({ - deleteSnapshots: 'include' - }) - }, - /** - * ASSET RENAME - * - * @param {Object} asset Asset to rename - */ - async assetRenamed (asset) { - WIKI.logger.info(`(STORAGE/AZURE) Renaming file from ${asset.path} to ${asset.destinationPath}...`) - const sourceBlockBlobClient = this.container.getBlockBlobClient(asset.path) - const destBlockBlobClient = this.container.getBlockBlobClient(asset.destinationPath) - await destBlockBlobClient.syncCopyFromURL(sourceBlockBlobClient.url) - await sourceBlockBlobClient.delete({ - deleteSnapshots: 'include' - }) - }, - async getLocalLocation () { - - }, - /** - * HANDLERS - */ - async exportAll() { - WIKI.logger.info(`(STORAGE/AZURE) Exporting all content to Azure Blob Storage...`) - - // -> Pages - await pipeline( - WIKI.db.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ - isPrivate: false - }).stream(), - new stream.Transform({ - objectMode: true, - transform: async (page, enc, cb) => { - const filePath = getFilePath(page, 'path') - WIKI.logger.info(`(STORAGE/AZURE) Adding page ${filePath}...`) - const pageContent = pageHelper.injectPageMetadata(page) - const blockBlobClient = this.container.getBlockBlobClient(filePath) - await blockBlobClient.upload(pageContent, pageContent.length, { tier: this.config.storageTier }) - cb() - } - }) - ) - - // -> Assets - const assetFolders = await WIKI.db.assetFolders.getAllPaths() - - await pipeline( - WIKI.db.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ - objectMode: true, - transform: async (asset, enc, cb) => { - const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename - WIKI.logger.info(`(STORAGE/AZURE) Adding asset ${filename}...`) - const blockBlobClient = this.container.getBlockBlobClient(filename) - await blockBlobClient.upload(asset.data, asset.data.length, { tier: this.config.storageTier }) - cb() - } - }) - ) - - WIKI.logger.info('(STORAGE/AZURE) All content has been pushed to Azure Blob Storage.') - } -} diff --git a/server/modules/storage/db/definition.yml b/server/modules/storage/db/definition.yml deleted file mode 100644 index fa1d0867a..000000000 --- a/server/modules/storage/db/definition.yml +++ /dev/null @@ -1,25 +0,0 @@ -title: 'Database' -icon: '/_assets/icons/ultraviolet-database.svg' -banner: '/_assets/storage/database.jpg' -description: 'The local PostgreSQL database can store any assets. It is however not recommended to store large files directly in the database as this can cause performance issues.' -vendor: 'Wiki.js' -website: 'https://js.wiki' -assetDelivery: - isStreamingSupported: true - isDirectAccessSupported: false - defaultStreamingEnabled: true - defaultDirectAccessEnabled: false -contentTypes: - defaultTypesEnabled: ['pages', 'images', 'documents', 'others', 'large'] - defaultLargeThreshold: '5MB' -versioning: - isSupported: true - defaultEnabled: false -sync: false -props: {} -actions: - purge: - label: Purge All Assets - hint: Delete all asset data from the database (not the metadata). Useful if you moved assets to another storage target and want to reduce the size of the database. - warn: This is a destructive action! Make sure all asset files are properly stored on another storage module! This action cannot be undone! - icon: explosion diff --git a/server/modules/storage/db/storage.mjs b/server/modules/storage/db/storage.mjs deleted file mode 100644 index c0798fede..000000000 --- a/server/modules/storage/db/storage.mjs +++ /dev/null @@ -1,25 +0,0 @@ -import fs from 'node:fs/promises' - -export default { - async activated () { }, - async deactivated () { }, - async init () { }, - async created (page) { }, - async updated (page) { }, - async deleted (page) { }, - async renamed (page) { }, - async assetUploaded ({ asset, tempFilePath, createReadStream }) { - await WIKI.db.knex('assets').where({ - id: asset.id - }).update({ - data: await fs.readFile(tempFilePath) - }) - return { - available: true - } - }, - async assetDeleted (asset) { }, - async assetRenamed (asset) { }, - async getLocalLocation () { }, - async exportAll () { } -} diff --git a/server/modules/storage/disk/common.js b/server/modules/storage/disk/common.js deleted file mode 100644 index 431272d43..000000000 --- a/server/modules/storage/disk/common.js +++ /dev/null @@ -1,170 +0,0 @@ -const fs = require('fs-extra') -const path = require('node:path') -const stream = require('node:stream') -const util = require('node:util') -const pipeline = util.promisify(stream.pipeline) -const klaw = require('klaw') -const mime = require('mime-types').lookup -const _ = require('lodash') - -const pageHelper = require('../../../helpers/page.js') - -module.exports = { - assetFolders: null, - async importFromDisk ({ fullPath, moduleName }) { - const rootUser = await WIKI.db.users.getRootUser() - - await pipeline( - klaw(fullPath, { - filter: (f) => { - return !_.includes(f, '.git') - } - }), - new stream.Transform({ - objectMode: true, - transform: async (file, enc, cb) => { - const relPath = file.path.substr(fullPath.length + 1) - if (file.stats.size < 1) { - // Skip directories and zero-byte files - return cb() - } else if (relPath && relPath.length > 3) { - WIKI.logger.info(`(STORAGE/${moduleName}) Processing ${relPath}...`) - const contentType = pageHelper.getContentType(relPath) - if (contentType) { - // -> Page - - try { - await this.processPage({ - user: rootUser, - relPath: relPath, - fullPath: fullPath, - contentType: contentType, - moduleName: moduleName - }) - } catch (err) { - WIKI.logger.warn(`(STORAGE/${moduleName}) Failed to process page ${relPath}`) - WIKI.logger.warn(err) - } - } else { - // -> Asset - - try { - await this.processAsset({ - user: rootUser, - relPath: relPath, - file: file, - contentType: contentType, - moduleName: moduleName - }) - } catch (err) { - WIKI.logger.warn(`(STORAGE/${moduleName}) Failed to process asset ${relPath}`) - WIKI.logger.warn(err) - } - } - } - cb() - } - }) - ) - this.clearFolderCache() - }, - - async processPage ({ user, fullPath, relPath, contentType, moduleName }) { - const normalizedRelPath = relPath.replace(/\\/g, '/') - const contentPath = pageHelper.getPagePath(normalizedRelPath) - const itemContents = await fs.readFile(path.join(fullPath, relPath), 'utf8') - const pageData = WIKI.db.pages.parseMetadata(itemContents, contentType) - const currentPage = await WIKI.db.pages.getPageFromDb({ - path: contentPath.path, - locale: contentPath.locale - }) - const newTags = !_.isNil(pageData.tags) ? _.get(pageData, 'tags', '').split(', ') : false - if (currentPage) { - // Already in the DB, can mark as modified - WIKI.logger.info(`(STORAGE/${moduleName}) Page marked as modified: ${normalizedRelPath}`) - await WIKI.db.pages.updatePage({ - id: currentPage.id, - title: _.get(pageData, 'title', currentPage.title), - description: _.get(pageData, 'description', currentPage.description) || '', - tags: newTags || currentPage.tags.map(t => t.tag), - isPublished: _.get(pageData, 'isPublished', currentPage.isPublished), - isPrivate: false, - content: pageData.content, - user: user, - skipStorage: true - }) - } else { - // Not in the DB, can mark as new - WIKI.logger.info(`(STORAGE/${moduleName}) Page marked as new: ${normalizedRelPath}`) - const pageEditor = await WIKI.db.editors.getDefaultEditor(contentType) - await WIKI.db.pages.createPage({ - path: contentPath.path, - locale: contentPath.locale, - title: _.get(pageData, 'title', _.last(contentPath.path.split('/'))), - description: _.get(pageData, 'description', '') || '', - tags: newTags || [], - isPublished: _.get(pageData, 'isPublished', true), - isPrivate: false, - content: pageData.content, - user: user, - editor: pageEditor, - skipStorage: true - }) - } - }, - - async processAsset ({ user, relPath, file, moduleName }) { - WIKI.logger.info(`(STORAGE/${moduleName}) Asset marked for import: ${relPath}`) - - // -> Get all folder paths - if (!this.assetFolders) { - this.assetFolders = await WIKI.db.assetFolders.getAllPaths() - } - - // -> Find existing folder - const filePathInfo = path.parse(file.path) - const folderPath = path.dirname(relPath).replace(/\\/g, '/') - let folderId = _.toInteger(_.findKey(this.assetFolders, fld => { return fld === folderPath })) || null - - // -> Create missing folder structure - if (!folderId && folderPath !== '.') { - const folderParts = folderPath.split('/') - let currentFolderPath = [] - let currentFolderParentId = null - for (const folderPart of folderParts) { - currentFolderPath.push(folderPart) - const existingFolderId = _.findKey(this.assetFolders, fld => { return fld === currentFolderPath.join('/') }) - if (!existingFolderId) { - const newFolderObj = await WIKI.db.assetFolders.query().insert({ - slug: folderPart, - name: folderPart, - parentId: currentFolderParentId - }) - _.set(this.assetFolders, newFolderObj.id, currentFolderPath.join('/')) - currentFolderParentId = newFolderObj.id - } else { - currentFolderParentId = _.toInteger(existingFolderId) - } - } - folderId = currentFolderParentId - } - - // -> Import asset - await WIKI.db.assets.upload({ - mode: 'import', - originalname: filePathInfo.base, - ext: filePathInfo.ext, - mimetype: mime(filePathInfo.base) || 'application/octet-stream', - size: file.stats.size, - folderId: folderId, - path: file.path, - assetPath: relPath, - user: user, - skipStorage: true - }) - }, - - clearFolderCache () { - this.assetFolders = null - } -} diff --git a/server/modules/storage/disk/definition.yml b/server/modules/storage/disk/definition.yml deleted file mode 100644 index b1d23b0ad..000000000 --- a/server/modules/storage/disk/definition.yml +++ /dev/null @@ -1,46 +0,0 @@ -title: Local File System -icon: '/_assets/icons/ultraviolet-hdd.svg' -banner: '/_assets/storage/disk.jpg' -description: Store files on the local file system or over network attached storage. Note that you must use replicated storage if using high-availability instances. -vendor: Wiki.js -website: 'https://js.wiki' -assetDelivery: - isStreamingSupported: true - isDirectAccessSupported: false - defaultStreamingEnabled: true - defaultDirectAccessEnabled: false -contentTypes: - defaultTypesEnabled: ['images', 'documents', 'others', 'large'] - defaultLargeThreshold: '5MB' -versioning: - isSupported: false - defaultEnabled: false -sync: false -internalSchedule: P1D -props: - path: - type: String - title: Path - hint: Absolute path without a trailing slash (e.g. /home/wiki/backup, C:\wiki\backup) - icon: symlink-directory - order: 1 - createDailyBackups: - type: Boolean - default: false - title: Create Daily Backups - hint: A tar.gz archive containing all content will be created daily in subfolder named _daily. Archives are kept for a month. - icon: archive-folder - order: 2 -actions: - dump: - label: Dump all content to disk - hint: Output all content from the DB to the local disk. If you enabled this module after content was created or you temporarily disabled this module, you'll want to execute this action to add the missing files. - icon: downloads - backup: - label: Create Backup - hint: Will create a manual backup archive at this point in time, in a subfolder named _manual, from the contents currently on disk. - icon: archive-folder - importAll: - label: Import Everything - hint: Will import all content currently in the local disk folder. - icon: database-daily-import diff --git a/server/modules/storage/disk/storage.js b/server/modules/storage/disk/storage.js deleted file mode 100644 index 7b9dbbdc5..000000000 --- a/server/modules/storage/disk/storage.js +++ /dev/null @@ -1,175 +0,0 @@ -const fs = require('fs-extra') -const path = require('node:path') -const tar = require('tar-fs') -const zlib = require('node:zlib') -const stream = require('node:stream') -const _ = require('lodash') -const util = require('node:util') -const pipeline = util.promisify(stream.pipeline) -const moment = require('moment') - -const pageHelper = require('../../../helpers/page') -const commonDisk = require('./common') - -module.exports = { - async activated() { - // not used - }, - async deactivated() { - // not used - }, - async init() { - WIKI.logger.info('(STORAGE/DISK) Initializing...') - await fs.ensureDir(this.config.path) - WIKI.logger.info('(STORAGE/DISK) Initialization completed.') - }, - async sync({ manual } = { manual: false }) { - if (this.config.createDailyBackups || manual) { - const dirPath = path.join(this.config.path, manual ? '_manual' : '_daily') - await fs.ensureDir(dirPath) - - const dateFilename = moment().format(manual ? 'YYYYMMDD-HHmmss' : 'DD') - - WIKI.logger.info(`(STORAGE/DISK) Creating backup archive...`) - await pipeline( - tar.pack(this.config.path, { - ignore: (filePath) => { - return filePath.indexOf('_daily') >= 0 || filePath.indexOf('_manual') >= 0 - } - }), - zlib.createGzip(), - fs.createWriteStream(path.join(dirPath, `wiki-${dateFilename}.tar.gz`)) - ) - WIKI.logger.info('(STORAGE/DISK) Backup archive created successfully.') - } - }, - async created(page) { - WIKI.logger.info(`(STORAGE/DISK) Creating file [${page.localeCode}] ${page.path}...`) - let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - if (WIKI.config.lang.code !== page.localeCode) { - fileName = `${page.localeCode}/${fileName}` - } - const filePath = path.join(this.config.path, fileName) - await fs.outputFile(filePath, page.injectMetadata(), 'utf8') - }, - async updated(page) { - WIKI.logger.info(`(STORAGE/DISK) Updating file [${page.localeCode}] ${page.path}...`) - let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - if (WIKI.config.lang.code !== page.localeCode) { - fileName = `${page.localeCode}/${fileName}` - } - const filePath = path.join(this.config.path, fileName) - await fs.outputFile(filePath, page.injectMetadata(), 'utf8') - }, - async deleted(page) { - WIKI.logger.info(`(STORAGE/DISK) Deleting file [${page.localeCode}] ${page.path}...`) - let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - if (WIKI.config.lang.code !== page.localeCode) { - fileName = `${page.localeCode}/${fileName}` - } - const filePath = path.join(this.config.path, fileName) - await fs.unlink(filePath) - }, - async renamed(page) { - WIKI.logger.info(`(STORAGE/DISK) Renaming file [${page.localeCode}] ${page.path} to [${page.destinationLocaleCode}] ${page.destinationPath}...`) - - let sourceFilePath = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - let destinationFilePath = `${page.destinationPath}.${pageHelper.getFileExtension(page.contentType)}` - - if (WIKI.config.lang.namespacing) { - if (WIKI.config.lang.code !== page.localeCode) { - sourceFilePath = `${page.localeCode}/${sourceFilePath}` - } - if (WIKI.config.lang.code !== page.destinationLocaleCode) { - destinationFilePath = `${page.destinationLocaleCode}/${destinationFilePath}` - } - } - - await fs.move(path.join(this.config.path, sourceFilePath), path.join(this.config.path, destinationFilePath), { overwrite: true }) - }, - /** - * ASSET UPLOAD - * - * @param {Object} asset Asset to upload - */ - async assetUploaded (asset) { - WIKI.logger.info(`(STORAGE/DISK) Creating new file ${asset.path}...`) - await fs.outputFile(path.join(this.config.path, asset.path), asset.data) - }, - /** - * ASSET DELETE - * - * @param {Object} asset Asset to delete - */ - async assetDeleted (asset) { - WIKI.logger.info(`(STORAGE/DISK) Deleting file ${asset.path}...`) - await fs.remove(path.join(this.config.path, asset.path)) - }, - /** - * ASSET RENAME - * - * @param {Object} asset Asset to rename - */ - async assetRenamed (asset) { - WIKI.logger.info(`(STORAGE/DISK) Renaming file from ${asset.path} to ${asset.destinationPath}...`) - await fs.move(path.join(this.config.path, asset.path), path.join(this.config.path, asset.destinationPath), { overwrite: true }) - }, - async getLocalLocation (asset) { - return path.join(this.config.path, asset.path) - }, - /** - * HANDLERS - */ - async dump() { - WIKI.logger.info(`(STORAGE/DISK) Dumping all content to disk...`) - - // -> Pages - await pipeline( - WIKI.db.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ - isPrivate: false - }).stream(), - new stream.Transform({ - objectMode: true, - transform: async (page, enc, cb) => { - let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - if (WIKI.config.lang.code !== page.localeCode) { - fileName = `${page.localeCode}/${fileName}` - } - WIKI.logger.info(`(STORAGE/DISK) Dumping page ${fileName}...`) - const filePath = path.join(this.config.path, fileName) - await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8') - cb() - } - }) - ) - - // -> Assets - const assetFolders = await WIKI.db.assetFolders.getAllPaths() - - await pipeline( - WIKI.db.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ - objectMode: true, - transform: async (asset, enc, cb) => { - const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename - WIKI.logger.info(`(STORAGE/DISK) Dumping asset ${filename}...`) - await fs.outputFile(path.join(this.config.path, filename), asset.data) - cb() - } - }) - ) - - WIKI.logger.info('(STORAGE/DISK) All content was dumped to disk successfully.') - }, - async backup() { - return this.sync({ manual: true }) - }, - async importAll() { - WIKI.logger.info(`(STORAGE/DISK) Importing all content from local disk folder to the DB...`) - await commonDisk.importFromDisk({ - fullPath: this.config.path, - moduleName: 'DISK' - }) - WIKI.logger.info('(STORAGE/DISK) Import completed.') - } -} diff --git a/server/modules/storage/gcs/definition.yml b/server/modules/storage/gcs/definition.yml deleted file mode 100644 index dcf80cdfd..000000000 --- a/server/modules/storage/gcs/definition.yml +++ /dev/null @@ -1,65 +0,0 @@ -title: Google Cloud Storage -icon: '/_assets/icons/ultraviolet-google.svg' -banner: '/_assets/storage/gcs.jpg' -description: Google Cloud Storage is an online file storage web service for storing and accessing data on Google Cloud Platform infrastructure. -vendor: Alphabet Inc. -website: 'https://cloud.google.com' -assetDelivery: - isStreamingSupported: true - isDirectAccessSupported: true - defaultStreamingEnabled: true - defaultDirectAccessEnabled: true -contentTypes: - defaultTypesEnabled: ['images', 'documents', 'others', 'large'] - defaultLargeThreshold: '5MB' -versioning: - isSupported: false - defaultEnabled: false -sync: false -props: - accountName: - type: String - title: Project ID - hint: The project ID from the Google Developer's Console (e.g. grape-spaceship-123). - icon: 3d-touch - default: '' - order: 1 - credentialsJSON: - type: String - title: JSON Credentials - hint: Contents of the JSON credentials file for the service account having Cloud Storage permissions. - icon: key - default: '' - multiline: true - sensitive: true - order: 2 - bucket: - type: String - title: Unique bucket name - hint: The unique bucket name to create (e.g. wiki-johndoe). - icon: open-box - order: 3 - storageTier: - type: String - title: Storage Tier - hint: Select the storage class to use when uploading new assets. - icon: scan-stock - order: 4 - default: STANDARD - enum: - - STANDARD|Standard - - NEARLINE|Nearline - - COLDLINE|Coldline - - ARCHIVE|Archive - apiEndpoint: - type: String - title: API Endpoint - hint: The API endpoint of the service used to make requests. - icon: api - default: storage.google.com - order: 5 -actions: - exportAll: - label: Export All DB Assets to GCS - hint: Output all content from the DB to Google Cloud Storage, overwriting any existing data. If you enabled Google Cloud Storage after content was created or you temporarily disabled it, you'll want to execute this action to add the missing content. - icon: this-way-up diff --git a/server/modules/storage/gcs/storage.js b/server/modules/storage/gcs/storage.js deleted file mode 100644 index 6f32973a5..000000000 --- a/server/modules/storage/gcs/storage.js +++ /dev/null @@ -1,162 +0,0 @@ -const { BlobServiceClient, StorageSharedKeyCredential } = require('@azure/storage-blob') -const stream = require('node:stream') -const util = require('node:util') -const pipeline = util.promisify(stream.pipeline) -const pageHelper = require('../../../helpers/page.js') -const _ = require('lodash') - -const getFilePath = (page, pathKey) => { - const fileName = `${page[pathKey]}.${pageHelper.getFileExtension(page.contentType)}` - const withLocaleCode = WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode - return withLocaleCode ? `${page.localeCode}/${fileName}` : fileName -} - -module.exports = { - async activated() { - - }, - async deactivated() { - - }, - async init() { - WIKI.logger.info(`(STORAGE/AZURE) Initializing...`) - const { accountName, accountKey, containerName } = this.config - this.client = new BlobServiceClient( - `https://${accountName}.blob.core.windows.net`, - new StorageSharedKeyCredential(accountName, accountKey) - ) - this.container = this.client.getContainerClient(containerName) - try { - await this.container.create() - } catch (err) { - if (err.statusCode !== 409) { - WIKI.logger.warn(err) - throw err - } - } - WIKI.logger.info(`(STORAGE/AZURE) Initialization completed.`) - }, - async created (page) { - WIKI.logger.info(`(STORAGE/AZURE) Creating file ${page.path}...`) - const filePath = getFilePath(page, 'path') - const pageContent = page.injectMetadata() - const blockBlobClient = this.container.getBlockBlobClient(filePath) - await blockBlobClient.upload(pageContent, pageContent.length, { tier: this.config.storageTier }) - }, - async updated (page) { - WIKI.logger.info(`(STORAGE/AZURE) Updating file ${page.path}...`) - const filePath = getFilePath(page, 'path') - const pageContent = page.injectMetadata() - const blockBlobClient = this.container.getBlockBlobClient(filePath) - await blockBlobClient.upload(pageContent, pageContent.length, { tier: this.config.storageTier }) - }, - async deleted (page) { - WIKI.logger.info(`(STORAGE/AZURE) Deleting file ${page.path}...`) - const filePath = getFilePath(page, 'path') - const blockBlobClient = this.container.getBlockBlobClient(filePath) - await blockBlobClient.delete({ - deleteSnapshots: 'include' - }) - }, - async renamed(page) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Renaming file ${page.path} to ${page.destinationPath}...`) - let sourceFilePath = getFilePath(page, 'path') - let destinationFilePath = getFilePath(page, 'destinationPath') - if (WIKI.config.lang.namespacing) { - if (WIKI.config.lang.code !== page.localeCode) { - sourceFilePath = `${page.localeCode}/${sourceFilePath}` - } - if (WIKI.config.lang.code !== page.destinationLocaleCode) { - destinationFilePath = `${page.destinationLocaleCode}/${destinationFilePath}` - } - } - const sourceBlockBlobClient = this.container.getBlockBlobClient(sourceFilePath) - const destBlockBlobClient = this.container.getBlockBlobClient(destinationFilePath) - await destBlockBlobClient.syncCopyFromURL(sourceBlockBlobClient.url) - await sourceBlockBlobClient.delete({ - deleteSnapshots: 'include' - }) - }, - /** - * ASSET UPLOAD - * - * @param {Object} asset Asset to upload - */ - async assetUploaded (asset) { - WIKI.logger.info(`(STORAGE/AZURE) Creating new file ${asset.path}...`) - const blockBlobClient = this.container.getBlockBlobClient(asset.path) - await blockBlobClient.upload(asset.data, asset.data.length, { tier: this.config.storageTier }) - }, - /** - * ASSET DELETE - * - * @param {Object} asset Asset to delete - */ - async assetDeleted (asset) { - WIKI.logger.info(`(STORAGE/AZURE) Deleting file ${asset.path}...`) - const blockBlobClient = this.container.getBlockBlobClient(asset.path) - await blockBlobClient.delete({ - deleteSnapshots: 'include' - }) - }, - /** - * ASSET RENAME - * - * @param {Object} asset Asset to rename - */ - async assetRenamed (asset) { - WIKI.logger.info(`(STORAGE/AZURE) Renaming file from ${asset.path} to ${asset.destinationPath}...`) - const sourceBlockBlobClient = this.container.getBlockBlobClient(asset.path) - const destBlockBlobClient = this.container.getBlockBlobClient(asset.destinationPath) - await destBlockBlobClient.syncCopyFromURL(sourceBlockBlobClient.url) - await sourceBlockBlobClient.delete({ - deleteSnapshots: 'include' - }) - }, - async getLocalLocation () { - - }, - /** - * HANDLERS - */ - async exportAll() { - WIKI.logger.info(`(STORAGE/AZURE) Exporting all content to Azure Blob Storage...`) - - // -> Pages - await pipeline( - WIKI.db.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ - isPrivate: false - }).stream(), - new stream.Transform({ - objectMode: true, - transform: async (page, enc, cb) => { - const filePath = getFilePath(page, 'path') - WIKI.logger.info(`(STORAGE/AZURE) Adding page ${filePath}...`) - const pageContent = pageHelper.injectPageMetadata(page) - const blockBlobClient = this.container.getBlockBlobClient(filePath) - await blockBlobClient.upload(pageContent, pageContent.length, { tier: this.config.storageTier }) - cb() - } - }) - ) - - // -> Assets - const assetFolders = await WIKI.db.assetFolders.getAllPaths() - - await pipeline( - WIKI.db.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ - objectMode: true, - transform: async (asset, enc, cb) => { - const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename - WIKI.logger.info(`(STORAGE/AZURE) Adding asset ${filename}...`) - const blockBlobClient = this.container.getBlockBlobClient(filename) - await blockBlobClient.upload(asset.data, asset.data.length, { tier: this.config.storageTier }) - cb() - } - }) - ) - - WIKI.logger.info('(STORAGE/AZURE) All content has been pushed to Azure Blob Storage.') - } -} diff --git a/server/modules/storage/git/definition.yml b/server/modules/storage/git/definition.yml deleted file mode 100644 index 7152a88b2..000000000 --- a/server/modules/storage/git/definition.yml +++ /dev/null @@ -1,152 +0,0 @@ -title: Local Git -icon: '/_assets/icons/ultraviolet-git.svg' -banner: '/_assets/storage/git.jpg' -description: Git is a version control system for tracking changes in computer files and coordinating work on those files among multiple people. If using GitHub, use the GitHub module instead! -vendor: Software Freedom Conservancy, Inc. -website: 'https://git-scm.com' -assetDelivery: - isStreamingSupported: true - isDirectAccessSupported: false - defaultStreamingEnabled: true - defaultDirectAccessEnabled: false -contentTypes: - defaultTypesEnabled: ['pages', 'images', 'documents', 'others', 'large'] - defaultLargeThreshold: '5MB' -versioning: - isSupported: true - defaultEnabled: true - isForceEnabled: true -sync: - supportedModes: - - sync - - push - - pull - defaultMode: sync - schedule: PT5M -props: - authType: - type: String - default: 'ssh' - title: Authentication Type - hint: Use SSH for maximum security. - icon: security-configuration - enum: - - basic|Basic - - ssh|SSH - enumDisplay: buttons - order: 1 - repoUrl: - type: String - title: Repository URI - hint: Git-compliant URI (e.g. git@server.com:org/repo.git for ssh, https://server.com/org/repo.git for basic) - icon: dns - order: 2 - branch: - type: String - default: 'main' - title: Branch - hint: The branch to use during pull / push - icon: code-fork - order: 3 - sshPrivateKeyMode: - type: String - title: SSH Private Key Mode - hint: The mode to use to load the private key. Fill in the corresponding field below. - icon: grand-master-key - order: 11 - default: inline - enum: - - path|File Path - - inline|Inline Contents - enumDisplay: buttons - if: - - { key: 'authType', eq: 'ssh' } - sshPrivateKeyPath: - type: String - title: SSH Private Key Path - hint: Absolute path to the key. The key must NOT be passphrase-protected. - icon: key - order: 12 - if: - - { key: 'authType', eq: 'ssh' } - - { key: 'sshPrivateKeyMode', eq: 'path' } - sshPrivateKeyContent: - type: String - title: SSH Private Key Contents - hint: Paste the contents of the private key. The key must NOT be passphrase-protected. - icon: key - multiline: true - sensitive: true - order: 13 - if: - - { key: 'authType', eq: 'ssh' } - - { key: 'sshPrivateKeyMode', eq: 'inline' } - verifySSL: - type: Boolean - default: true - title: Verify SSL Certificate - hint: Some hosts requires SSL certificate checking to be disabled. Leave enabled for proper security. - icon: security-ssl - order: 14 - basicUsername: - type: String - title: Username - hint: Basic Authentication Only - icon: test-account - order: 20 - if: - - { key: 'authType', eq: 'basic' } - basicPassword: - type: String - title: Password / PAT - hint: Basic Authentication Only - icon: password - sensitive: true - order: 21 - if: - - { key: 'authType', eq: 'basic' } - defaultEmail: - type: String - title: Default Author Email - default: 'name@company.com' - hint: 'Used as fallback in case the author of the change is not present.' - icon: email - order: 30 - defaultName: - type: String - title: Default Author Name - default: 'John Smith' - hint: 'Used as fallback in case the author of the change is not present.' - icon: customer - order: 31 - localRepoPath: - type: String - title: Local Repository Path - default: './data/repo' - hint: 'Path where the local git repository will be created.' - icon: symlink-directory - order: 32 - gitBinaryPath: - type: String - title: Git Binary Path - default: '' - hint: Optional - Absolute path to the Git binary, when not available in PATH. Leave empty to use the default PATH location (recommended). - icon: run-command - order: 50 -actions: - syncUntracked: - label: Add Untracked Changes - hint: Output all content from the DB to the local Git repository to ensure all untracked content is saved. If you enabled Git after content was created or you temporarily disabled Git, you'll want to execute this action to add the missing untracked changes. - icon: database-daily-export - sync: - label: Force Sync - hint: Will trigger an immediate sync operation, regardless of the current sync schedule. The sync direction is respected. - icon: synchronize - importAll: - label: Import Everything - hint: Will import all content currently in the local Git repository, regardless of the latest commit state. Useful for importing content from the remote repository created before git was enabled. - icon: database-daily-import - purge: - label: Purge Local Repository - hint: If you have unrelated merge histories, clearing the local repository can resolve this issue. This will not affect the remote repository or perform any commit. - icon: trash diff --git a/server/modules/storage/git/storage.js b/server/modules/storage/git/storage.js deleted file mode 100644 index 2813ab08c..000000000 --- a/server/modules/storage/git/storage.js +++ /dev/null @@ -1,470 +0,0 @@ -const path = require('node:path') -const sgit = require('simple-git/promise') -const fs = require('fs-extra') -const _ = require('lodash') -const stream = require('node:stream') -const util = require('node:util') -const pipeline = util.promisify(stream.pipeline) -const klaw = require('klaw') -const os = require('node:os') - -const pageHelper = require('../../../helpers/page') -const assetHelper = require('../../../helpers/asset') -const commonDisk = require('../disk/common') - -module.exports = { - git: null, - repoPath: path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'repo'), - async activated() { - // not used - }, - async deactivated() { - // not used - }, - /** - * INIT - */ - async init() { - WIKI.logger.info('(STORAGE/GIT) Initializing...') - this.repoPath = path.resolve(WIKI.ROOTPATH, this.config.localRepoPath) - await fs.ensureDir(this.repoPath) - this.git = sgit(this.repoPath) - - // Set custom binary path - if (!_.isEmpty(this.config.gitBinaryPath)) { - this.git.customBinary(this.config.gitBinaryPath) - } - - // Initialize repo (if needed) - WIKI.logger.info('(STORAGE/GIT) Checking repository state...') - const isRepo = await this.git.checkIsRepo() - if (!isRepo) { - WIKI.logger.info('(STORAGE/GIT) Initializing local repository...') - await this.git.init() - } - - // Disable quotePath - // Link https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath - await this.git.raw(['config', '--local', 'core.quotepath', false]) - - // Set default author - await this.git.raw(['config', '--local', 'user.email', this.config.defaultEmail]) - await this.git.raw(['config', '--local', 'user.name', this.config.defaultName]) - - // Purge existing remotes - WIKI.logger.info('(STORAGE/GIT) Listing existing remotes...') - const remotes = await this.git.getRemotes() - if (remotes.length > 0) { - WIKI.logger.info('(STORAGE/GIT) Purging existing remotes...') - for (let remote of remotes) { - await this.git.removeRemote(remote.name) - } - } - - // Add remote - WIKI.logger.info('(STORAGE/GIT) Setting SSL Verification config...') - await this.git.raw(['config', '--local', '--bool', 'http.sslVerify', _.toString(this.config.verifySSL)]) - switch (this.config.authType) { - case 'ssh': - WIKI.logger.info('(STORAGE/GIT) Setting SSH Command config...') - if (this.config.sshPrivateKeyMode === 'contents') { - try { - this.config.sshPrivateKeyPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'secure/git-ssh.pem') - await fs.outputFile(this.config.sshPrivateKeyPath, this.config.sshPrivateKeyContent + os.EOL, { - encoding: 'utf8', - mode: 0o600 - }) - } catch (err) { - console.error(err) - throw err - } - } - await this.git.addConfig('core.sshCommand', `ssh -i "${this.config.sshPrivateKeyPath}" -o StrictHostKeyChecking=no`) - WIKI.logger.info('(STORAGE/GIT) Adding origin remote via SSH...') - await this.git.addRemote('origin', this.config.repoUrl) - break - default: - WIKI.logger.info('(STORAGE/GIT) Adding origin remote via HTTP/S...') - let originUrl = '' - if (_.startsWith(this.config.repoUrl, 'http')) { - originUrl = this.config.repoUrl.replace('://', `://${encodeURI(this.config.basicUsername)}:${encodeURI(this.config.basicPassword)}@`) - } else { - originUrl = `https://${encodeURI(this.config.basicUsername)}:${encodeURI(this.config.basicPassword)}@${this.config.repoUrl}` - } - await this.git.addRemote('origin', originUrl) - break - } - - // Fetch updates for remote - WIKI.logger.info('(STORAGE/GIT) Fetch updates from remote...') - await this.git.raw(['remote', 'update', 'origin']) - - // Checkout branch - const branches = await this.git.branch() - if (!_.includes(branches.all, this.config.branch) && !_.includes(branches.all, `remotes/origin/${this.config.branch}`)) { - throw new Error('Invalid branch! Make sure it exists on the remote first.') - } - WIKI.logger.info(`(STORAGE/GIT) Checking out branch ${this.config.branch}...`) - await this.git.checkout(this.config.branch) - - // Perform initial sync - await this.sync() - - WIKI.logger.info('(STORAGE/GIT) Initialization completed.') - }, - /** - * SYNC - */ - async sync() { - const currentCommitLog = _.get(await this.git.log(['-n', '1', this.config.branch]), 'latest', {}) - - const rootUser = await WIKI.db.users.getRootUser() - - // Pull rebase - if (_.includes(['sync', 'pull'], this.mode)) { - WIKI.logger.info(`(STORAGE/GIT) Performing pull rebase from origin on branch ${this.config.branch}...`) - await this.git.pull('origin', this.config.branch, ['--rebase']) - } - - // Push - if (_.includes(['sync', 'push'], this.mode)) { - WIKI.logger.info(`(STORAGE/GIT) Performing push to origin on branch ${this.config.branch}...`) - let pushOpts = ['--signed=if-asked'] - if (this.mode === 'push') { - pushOpts.push('--force') - } - await this.git.push('origin', this.config.branch, pushOpts) - } - - // Process Changes - if (_.includes(['sync', 'pull'], this.mode)) { - const latestCommitLog = _.get(await this.git.log(['-n', '1', this.config.branch]), 'latest', {}) - - const diff = await this.git.diffSummary(['-M', currentCommitLog.hash, latestCommitLog.hash]) - if (_.get(diff, 'files', []).length > 0) { - let filesToProcess = [] - for (const f of diff.files) { - const fPath = path.join(this.repoPath, f.file) - let fStats = { size: 0 } - try { - fStats = await fs.stat(fPath) - } catch (err) { - if (err.code !== 'ENOENT') { - WIKI.logger.warn(`(STORAGE/GIT) Failed to access file ${f.file}! Skipping...`) - continue - } - } - - filesToProcess.push({ - ...f, - file: { - path: fPath, - stats: fStats - }, - relPath: f.file - }) - } - await this.processFiles(filesToProcess, rootUser) - } - } - }, - /** - * Process Files - * - * @param {Array} files Array of files to process - */ - async processFiles(files, user) { - for (const item of files) { - const contentType = pageHelper.getContentType(item.relPath) - const fileExists = await fs.pathExists(item.file) - if (!item.binary && contentType) { - // -> Page - - if (!fileExists && item.deletions > 0 && item.insertions === 0) { - // Page was deleted by git, can safely mark as deleted in DB - WIKI.logger.info(`(STORAGE/GIT) Page marked as deleted: ${item.relPath}`) - - const contentPath = pageHelper.getPagePath(item.relPath) - await WIKI.db.pages.deletePage({ - user: user, - path: contentPath.path, - locale: contentPath.locale, - skipStorage: true - }) - continue - } - - try { - await commonDisk.processPage({ - user, - relPath: item.relPath, - fullPath: this.repoPath, - contentType: contentType, - moduleName: 'GIT' - }) - } catch (err) { - WIKI.logger.warn(`(STORAGE/GIT) Failed to process ${item.relPath}`) - WIKI.logger.warn(err) - } - } else { - // -> Asset - - if (!fileExists && ((item.before > 0 && item.after === 0) || (item.deletions > 0 && item.insertions === 0))) { - // Asset was deleted by git, can safely mark as deleted in DB - WIKI.logger.info(`(STORAGE/GIT) Asset marked as deleted: ${item.relPath}`) - - const fileHash = assetHelper.generateHash(item.relPath) - const assetToDelete = await WIKI.db.assets.query().findOne({ hash: fileHash }) - if (assetToDelete) { - await WIKI.db.knex('assetData').where('id', assetToDelete.id).del() - await WIKI.db.assets.query().deleteById(assetToDelete.id) - await assetToDelete.deleteAssetCache() - } else { - WIKI.logger.info(`(STORAGE/GIT) Asset was not found in the DB, nothing to delete: ${item.relPath}`) - } - continue - } - - try { - await commonDisk.processAsset({ - user, - relPath: item.relPath, - file: item.file, - contentType: contentType, - moduleName: 'GIT' - }) - } catch (err) { - WIKI.logger.warn(`(STORAGE/GIT) Failed to process asset ${item.relPath}`) - WIKI.logger.warn(err) - } - } - } - }, - /** - * CREATE - * - * @param {Object} page Page to create - */ - async created(page) { - WIKI.logger.info(`(STORAGE/GIT) Committing new file [${page.localeCode}] ${page.path}...`) - let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) { - fileName = `${page.localeCode}/${fileName}` - } - const filePath = path.join(this.repoPath, fileName) - await fs.outputFile(filePath, page.injectMetadata(), 'utf8') - - const gitFilePath = `./${fileName}` - if ((await this.git.checkIgnore(gitFilePath)).length === 0) { - await this.git.add(gitFilePath) - await this.git.commit(`docs: create ${page.path}`, fileName, { - '--author': `"${page.authorName} <${page.authorEmail}>"` - }) - } - }, - /** - * UPDATE - * - * @param {Object} page Page to update - */ - async updated(page) { - WIKI.logger.info(`(STORAGE/GIT) Committing updated file [${page.localeCode}] ${page.path}...`) - let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) { - fileName = `${page.localeCode}/${fileName}` - } - const filePath = path.join(this.repoPath, fileName) - await fs.outputFile(filePath, page.injectMetadata(), 'utf8') - - const gitFilePath = `./${fileName}` - if ((await this.git.checkIgnore(gitFilePath)).length === 0) { - await this.git.add(gitFilePath) - await this.git.commit(`docs: update ${page.path}`, fileName, { - '--author': `"${page.authorName} <${page.authorEmail}>"` - }) - } - }, - /** - * DELETE - * - * @param {Object} page Page to delete - */ - async deleted(page) { - WIKI.logger.info(`(STORAGE/GIT) Committing removed file [${page.localeCode}] ${page.path}...`) - let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) { - fileName = `${page.localeCode}/${fileName}` - } - - const gitFilePath = `./${fileName}` - if ((await this.git.checkIgnore(gitFilePath)).length === 0) { - await this.git.rm(gitFilePath) - await this.git.commit(`docs: delete ${page.path}`, fileName, { - '--author': `"${page.authorName} <${page.authorEmail}>"` - }) - } - }, - /** - * RENAME - * - * @param {Object} page Page to rename - */ - async renamed(page) { - WIKI.logger.info(`(STORAGE/GIT) Committing file move from [${page.localeCode}] ${page.path} to [${page.destinationLocaleCode}] ${page.destinationPath}...`) - let sourceFileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - let destinationFileName = `${page.destinationPath}.${pageHelper.getFileExtension(page.contentType)}` - - if (WIKI.config.lang.namespacing) { - if (WIKI.config.lang.code !== page.localeCode) { - sourceFileName = `${page.localeCode}/${sourceFileName}` - } - if (WIKI.config.lang.code !== page.destinationLocaleCode) { - destinationFileName = `${page.destinationLocaleCode}/${destinationFileName}` - } - } - - const sourceFilePath = path.join(this.repoPath, sourceFileName) - const destinationFilePath = path.join(this.repoPath, destinationFileName) - await fs.move(sourceFilePath, destinationFilePath) - - await this.git.rm(`./${sourceFileName}`) - await this.git.add(`./${destinationFileName}`) - await this.git.commit(`docs: rename ${page.path} to ${page.destinationPath}`, [sourceFilePath, destinationFilePath], { - '--author': `"${page.moveAuthorName} <${page.moveAuthorEmail}>"` - }) - }, - /** - * ASSET UPLOAD - * - * @param {Object} asset Asset to upload - */ - async assetUploaded (asset) { - WIKI.logger.info(`(STORAGE/GIT) Committing new file ${asset.path}...`) - const filePath = path.join(this.repoPath, asset.path) - await fs.outputFile(filePath, asset.data, 'utf8') - - await this.git.add(`./${asset.path}`) - await this.git.commit(`docs: upload ${asset.path}`, asset.path, { - '--author': `"${asset.authorName} <${asset.authorEmail}>"` - }) - }, - /** - * ASSET DELETE - * - * @param {Object} asset Asset to upload - */ - async assetDeleted (asset) { - WIKI.logger.info(`(STORAGE/GIT) Committing removed file ${asset.path}...`) - - await this.git.rm(`./${asset.path}`) - await this.git.commit(`docs: delete ${asset.path}`, asset.path, { - '--author': `"${asset.authorName} <${asset.authorEmail}>"` - }) - }, - /** - * ASSET RENAME - * - * @param {Object} asset Asset to upload - */ - async assetRenamed (asset) { - WIKI.logger.info(`(STORAGE/GIT) Committing file move from ${asset.path} to ${asset.destinationPath}...`) - - await this.git.mv(`./${asset.path}`, `./${asset.destinationPath}`) - await this.git.commit(`docs: rename ${asset.path} to ${asset.destinationPath}`, [asset.path, asset.destinationPath], { - '--author': `"${asset.moveAuthorName} <${asset.moveAuthorEmail}>"` - }) - }, - async getLocalLocation (asset) { - return path.join(this.repoPath, asset.path) - }, - /** - * HANDLERS - */ - async importAll() { - WIKI.logger.info(`(STORAGE/GIT) Importing all content from local Git repo to the DB...`) - - const rootUser = await WIKI.db.users.getRootUser() - - await pipeline( - klaw(this.repoPath, { - filter: (f) => { - return !_.includes(f, '.git') - } - }), - new stream.Transform({ - objectMode: true, - transform: async (file, enc, cb) => { - const relPath = file.path.substr(this.repoPath.length + 1) - if (file.stats.size < 1) { - // Skip directories and zero-byte files - return cb() - } else if (relPath && relPath.length > 3) { - WIKI.logger.info(`(STORAGE/GIT) Processing ${relPath}...`) - await this.processFiles([{ - user: rootUser, - relPath, - file, - deletions: 0, - insertions: 0 - }], rootUser) - } - cb() - } - }) - ) - - commonDisk.clearFolderCache() - - WIKI.logger.info('(STORAGE/GIT) Import completed.') - }, - async syncUntracked() { - WIKI.logger.info(`(STORAGE/GIT) Adding all untracked content...`) - - // -> Pages - await pipeline( - WIKI.db.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ - isPrivate: false - }).stream(), - new stream.Transform({ - objectMode: true, - transform: async (page, enc, cb) => { - let fileName = `${page.path}.${pageHelper.getFileExtension(page.contentType)}` - if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) { - fileName = `${page.localeCode}/${fileName}` - } - WIKI.logger.info(`(STORAGE/GIT) Adding page ${fileName}...`) - const filePath = path.join(this.repoPath, fileName) - await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8') - await this.git.add(`./${fileName}`) - cb() - } - }) - ) - - // -> Assets - const assetFolders = await WIKI.db.assetFolders.getAllPaths() - - await pipeline( - WIKI.db.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ - objectMode: true, - transform: async (asset, enc, cb) => { - const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename - WIKI.logger.info(`(STORAGE/GIT) Adding asset ${filename}...`) - await fs.outputFile(path.join(this.repoPath, filename), asset.data) - await this.git.add(`./${filename}`) - cb() - } - }) - ) - - await this.git.commit(`docs: add all untracked content`) - WIKI.logger.info('(STORAGE/GIT) All content is now tracked.') - }, - async purge() { - WIKI.logger.info(`(STORAGE/GIT) Purging local repository...`) - await fs.emptyDir(this.repoPath) - WIKI.logger.info('(STORAGE/GIT) Local repository is now empty. Reinitializing...') - await this.init() - } -} diff --git a/server/modules/storage/github/definition.yml b/server/modules/storage/github/definition.yml deleted file mode 100644 index 5f110debc..000000000 --- a/server/modules/storage/github/definition.yml +++ /dev/null @@ -1,49 +0,0 @@ -title: GitHub -icon: '/_assets/icons/ultraviolet-github.svg' -banner: '/_assets/storage/github.jpg' -description: Millions of developers and companies build, ship, and maintain their software on GitHub - the largest and most advanced development platform in the world. -vendor: GitHub, Inc. -website: 'https://github.com' -assetDelivery: - isStreamingSupported: false - isDirectAccessSupported: false - defaultStreamingEnabled: false - defaultDirectAccessEnabled: false -contentTypes: - defaultTypesEnabled: ['pages', 'images', 'documents', 'others', 'large'] - defaultLargeThreshold: '5MB' -versioning: - isSupported: true - defaultEnabled: true - isForceEnabled: true -sync: false -setup: - handler: github - defaultValues: - accountType: org - org: '' - publicUrl: https:// -props: - appName: - readOnly: true - type: String - title: App Name - hint: Name of the generated app in GitHub. - icon: 3d-touch - repoFullName: - readOnly: true - type: String - title: GitHub Repository - hint: The GitHub repository used for content synchronization. - icon: github - repoDefaultBranch: - readOnly: true - type: String - title: Default Branch - hint: The repository default branch. - icon: code-fork -actions: - exportAll: - label: Export All DB Assets to GitHub - hint: Output all content from the DB to GitHub, overwriting any existing data. If you enabled GitHub after content was created or you temporarily disabled it, you'll want to execute this action to add the missing content. - icon: this-way-up diff --git a/server/modules/storage/github/storage.mjs b/server/modules/storage/github/storage.mjs deleted file mode 100644 index 0b5389791..000000000 --- a/server/modules/storage/github/storage.mjs +++ /dev/null @@ -1,209 +0,0 @@ -import { Octokit, App } from 'octokit' - -export default { - async activated () { }, - async deactivated () { }, - async init () { }, - - /** - * SETUP FUNCTIONS - */ - async setup (id, state) { - try { - switch (state.step) { - // -------------------------------------------- - // -> VALIDATE CALLBACK CODE AFTER APP CREATION - // -------------------------------------------- - case 'connect': { - const gh = new Octokit({ - userAgent: 'wikijs' - }) - const resp = await gh.request('POST /app-manifests/{code}/conversions', { - code: state.code - }) - if (resp.status > 200 && resp.status < 300) { - await WIKI.db.storage.query().patch({ - config: { - appId: resp.data.id, - appName: resp.data.name, - appSlug: resp.data.slug, - appClientId: resp.data.client_id, - appClientSecret: resp.data.client_secret, - appWebhookSecret: resp.data.webhook_secret, - appPem: resp.data.pem, - appPermissions: resp.data.permissions, - appEvents: resp.data.events, - ownerLogin: resp.data.owner?.login, - ownerId: resp.data.owner?.id - }, - state: { - current: 'ok', - setup: 'pendinginstall' - } - }).where('id', id) - return { - nextStep: 'installApp', - url: `https://github.com/apps/${resp.data.slug}/installations/new/permissions?target_id=${resp.data.owner?.id}` - } - } else { - throw new Error('GitHub refused the code or could not be reached.') - } - } - // ----------------------- - // VERIFY APP INSTALLATION - // ----------------------- - case 'verify': { - const tgt = await WIKI.db.storage.query().findById(id) - if (!tgt) { - throw new Error('Invalid Target ID') - } - - const ghApp = new App({ - appId: tgt.config.appId, - privateKey: tgt.config.appPem, - Octokit: Octokit.defaults({ - userAgent: 'wikijs' - }), - oauth: { - clientId: tgt.config.appClientId, - clientSecret: tgt.config.appClientSecret - }, - webhooks: { - secret: tgt.config.appWebhookSecret - } - }) - - // -> Find Installation ID - - let installId = null - let installTotal = 0 - for await (const { installation } of ghApp.eachInstallation.iterator()) { - if (installTotal < 1) { - installId = installation.id - WIKI.logger.debug(`Using GitHub App installation ID ${installId}`) - } - installTotal++ - } - if (installTotal < 1) { - throw new Error('App is not installed on any GitHub account!') - } else if (installTotal > 1) { - WIKI.logger.warn(`GitHub App ${tgt.config.appName} is installed on more than 1 account. Only the first one ${installId} will be used.`) - } - - // -> Fetch Repository Info - - let repo = null - let repoTotal = 0 - for await (const { repository } of ghApp.eachRepository.iterator({ installationId: installId })) { - if (repository.archived || repository.disabled) { - WIKI.logger.debug(`Skipping GitHub Repository ${repo.id} because of it is archived or disabled.`) - continue - } - if (repoTotal < 1) { - repo = repository - WIKI.logger.debug(`Using GitHub Repository ${repo.id}`) - } - repoTotal++ - } - if (repoTotal < 1) { - throw new Error('App is not installed on any GitHub repository!') - } else if (repoTotal > 1) { - WIKI.logger.warn(`GitHub App ${tgt.config.appName} is installed on more than 1 repository. Only the first one (${repo.full_name}) will be used.`) - } - - // -> Save install/repo info - - await WIKI.db.storage.query().patch({ - isEnabled: true, - config: { - ...tgt.config, - installId, - repoId: repo.id, - repoName: repo.name, - repoOwner: repo.owner?.login, - repoDefaultBranch: repo.default_branch, - repoFullName: repo.full_name - }, - state: { - current: 'ok', - setup: 'configured' - } - }).where('id', id) - - return { - nextStep: 'completed' - } - } - default: { - throw new Error('Invalid Setup Step') - } - } - } catch (err) { - WIKI.logger.warn('GitHub Storage Module Setup Failed:') - WIKI.logger.warn(err) - throw err - } - }, - async setupDestroy (id) { - try { - const tgt = await WIKI.db.storage.query().findById(id) - if (!tgt) { - throw new Error('Invalid Target ID') - } - - WIKI.logger.info('Resetting GitHub storage configuration...') - - const ghApp = new App({ - appId: tgt.config.appId, - privateKey: tgt.config.appPem, - Octokit: Octokit.defaults({ - userAgent: 'wikijs' - }), - oauth: { - clientId: tgt.config.appClientId, - clientSecret: tgt.config.appClientSecret - }, - webhooks: { - secret: tgt.config.appWebhookSecret - } - }) - - // -> Reset storage module config - - await WIKI.db.storage.query().patch({ - isEnabled: false, - config: {}, - state: { - current: 'ok', - setup: 'notconfigured' - } - }).where('id', id) - - // -> Try to delete installation on GitHub - - if (tgt.config.installId) { - try { - await ghApp.octokit.request('DELETE /app/installations/{installation_id}', { - installation_id: tgt.config.installId - }) - WIKI.logger.info('Deleted GitHub installation successfully.') - } catch (err) { - WIKI.logger.warn('Could not delete GitHub installation automatically. Please remove the installation on GitHub.') - } - } - } catch (err) { - WIKI.logger.warn('GitHub Storage Module Destroy Failed:') - WIKI.logger.warn(err) - throw err - } - }, - async created (page) { }, - async updated (page) { }, - async deleted (page) { }, - async renamed (page) { }, - async assetUploaded (asset) { }, - async assetDeleted (asset) { }, - async assetRenamed (asset) { }, - async getLocalLocation () { }, - async exportAll () { } -} diff --git a/server/modules/storage/s3/definition.yml b/server/modules/storage/s3/definition.yml deleted file mode 100644 index f948e0128..000000000 --- a/server/modules/storage/s3/definition.yml +++ /dev/null @@ -1,159 +0,0 @@ -title: AWS S3 / DigitalOcean Spaces -icon: '/_assets/icons/ultraviolet-amazon-web-services.svg' -banner: '/_assets/storage/s3.jpg' -description: Amazon Simple Storage Service (Amazon S3) is an object storage service offering industry-leading scalability, data availability, security, and performance. -vendor: Amazon.com, Inc. -website: 'https://aws.amazon.com' -assetDelivery: - isStreamingSupported: true - isDirectAccessSupported: true - defaultStreamingEnabled: true - defaultDirectAccessEnabled: true -contentTypes: - defaultTypesEnabled: ['images', 'documents', 'others', 'large'] - defaultLargeThreshold: '5MB' -versioning: - isSupported: false - defaultEnabled: false -sync: false -props: - mode: - type: String - title: Mode - hint: Select a preset configuration mode or define a custom one. - icon: tune - default: aws - order: 1 - enum: - - aws|AWS S3 - - do|DigitalOcean Spaces - - custom|Custom - awsRegion: - type: String - title: Region - hint: The AWS datacenter region where the bucket will be created. - icon: geography - default: us-east-1 - enum: - - af-south-1|af-south-1 - Africa (Cape Town) - - ap-east-1|ap-east-1 - Asia Pacific (Hong Kong) - - ap-southeast-3|ap-southeast-3 - Asia Pacific (Jakarta) - - ap-south-1|ap-south-1 - Asia Pacific (Mumbai) - - ap-northeast-3|ap-northeast-3 - Asia Pacific (Osaka) - - ap-northeast-2|ap-northeast-2 - Asia Pacific (Seoul) - - ap-southeast-1|ap-southeast-1 - Asia Pacific (Singapore) - - ap-southeast-2|ap-southeast-2 - Asia Pacific (Sydney) - - ap-northeast-1|ap-northeast-1 - Asia Pacific (Tokyo) - - ca-central-1|ca-central-1 - Canada (Central) - - cn-north-1|cn-north-1 - China (Beijing) - - cn-northwest-1|cn-northwest-1 - China (Ningxia) - - eu-central-1|eu-central-1 - Europe (Frankfurt) - - eu-west-1|eu-west-1 - Europe (Ireland) - - eu-west-2|eu-west-2 - Europe (London) - - eu-south-1|eu-south-1 - Europe (Milan) - - eu-west-3|eu-west-3 - Europe (Paris) - - eu-north-1|eu-north-1 - Europe (Stockholm) - - me-south-1|me-south-1 - Middle East (Bahrain) - - sa-east-1|sa-east-1 - South America (São Paulo) - - us-east-1|us-east-1 - US East (N. Virginia) - - us-east-2|us-east-2 - US East (Ohio) - - us-west-1|us-west-1 - US West (N. California) - - us-west-2|us-west-2 - US West (Oregon) - order: 2 - if: - - { key: 'mode', eq: 'aws' } - doRegion: - type: String - title: Region - hint: The DigitalOcean Spaces region - icon: geography - default: nyc3 - enum: - - ams3|Amsterdam - - fra1|Frankfurt - - nyc3|New York - - sfo2|San Francisco 2 - - sfo3|San Francisco 3 - - sgp1|Singapore - order: 2 - if: - - { key: 'mode', eq: 'do' } - endpoint: - type: String - title: Endpoint URI - hint: The full S3-compliant endpoint URI. - icon: dns - default: https://service.region.example.com - order: 2 - if: - - { key: 'mode', eq: 'custom' } - bucket: - type: String - title: Unique bucket name - hint: The unique bucket name to create (e.g. wiki-johndoe). - icon: open-box - order: 3 - accessKeyId: - type: String - title: Access Key ID - hint: The Access Key. - icon: 3d-touch - order: 4 - secretAccessKey: - type: String - title: Secret Access Key - hint: The Secret Access Key for the Access Key ID you created above. - icon: key - sensitive: true - order: 5 - storageTier: - type: String - title: Storage Tier - hint: The storage tier to use when adding files. - icon: scan-stock - order: 6 - default: STANDARD - enum: - - STANDARD|Standard - - STANDARD_IA|Standard Infrequent Access - - INTELLIGENT_TIERING|Intelligent Tiering - - ONEZONE_IA|One Zone Infrequent Access - - REDUCED_REDUNDANCY|Reduced Redundancy - - GLACIER_IR|Glacier Instant Retrieval - - GLACIER|Glacier Flexible Retrieval - - DEEP_ARCHIVE|Glacier Deep Archive - - OUTPOSTS|Outposts - if: - - { key: 'mode', eq: 'aws' } - sslEnabled: - type: Boolean - title: Use SSL - hint: Whether to enable SSL for requests - icon: secure - default: true - order: 10 - if: - - { key: 'mode', eq: 'custom' } - s3ForcePathStyle: - type: Boolean - title: Force Path Style for S3 objects - hint: Whether to force path style URLs for S3 objects. - icon: filtration - default: false - order: 11 - if: - - { key: 'mode', eq: 'custom' } - s3BucketEndpoint: - type: Boolean - title: Single Bucket Endpoint - hint: Whether the provided endpoint addresses an individual bucket. - icon: swipe-right - default: false - order: 12 - if: - - { key: 'mode', eq: 'custom' } -actions: - exportAll: - label: Export All DB Assets to S3 - hint: Output all content from the DB to S3, overwriting any existing data. If you enabled S3 after content was created or you temporarily disabled it, you'll want to execute this action to add the missing content. - icon: this-way-up diff --git a/server/modules/storage/s3/storage.js b/server/modules/storage/s3/storage.js deleted file mode 100644 index 41d1165ee..000000000 --- a/server/modules/storage/s3/storage.js +++ /dev/null @@ -1,164 +0,0 @@ -const S3 = require('aws-sdk/clients/s3') -const stream = require('node:stream') -const util = require('node:util') -const pipeline = util.promisify(stream.pipeline) -const _ = require('lodash') -const pageHelper = require('../../../helpers/page.js') - -/** - * Deduce the file path given the `page` object and the object's key to the page's path. - */ -const getFilePath = (page, pathKey) => { - const fileName = `${page[pathKey]}.${pageHelper.getFileExtension(page.contentType)}` - const withLocaleCode = WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode - return withLocaleCode ? `${page.localeCode}/${fileName}` : fileName -} - -/** - * Can be used with S3 compatible storage. - */ -module.exports = class S3CompatibleStorage { - constructor(storageName) { - this.storageName = storageName - } - async activated() { - // not used - } - async deactivated() { - // not used - } - async init() { - WIKI.logger.info(`(STORAGE/${this.storageName}) Initializing...`) - const { accessKeyId, secretAccessKey, bucket } = this.config - const s3Config = { - accessKeyId, - secretAccessKey, - params: { Bucket: bucket }, - apiVersions: '2006-03-01' - } - - if (!_.isNil(this.config.region)) { - s3Config.region = this.config.region - } - if (!_.isNil(this.config.endpoint)) { - s3Config.endpoint = this.config.endpoint - } - if (!_.isNil(this.config.sslEnabled)) { - s3Config.sslEnabled = this.config.sslEnabled - } - if (!_.isNil(this.config.s3ForcePathStyle)) { - s3Config.s3ForcePathStyle = this.config.s3ForcePathStyle - } - if (!_.isNil(this.config.s3BucketEndpoint)) { - s3Config.s3BucketEndpoint = this.config.s3BucketEndpoint - } - - this.s3 = new S3(s3Config) - - // determine if a bucket exists and you have permission to access it - await this.s3.headBucket().promise() - - WIKI.logger.info(`(STORAGE/${this.storageName}) Initialization completed.`) - } - async created(page) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Creating file ${page.path}...`) - const filePath = getFilePath(page, 'path') - await this.s3.putObject({ Key: filePath, Body: page.injectMetadata() }).promise() - } - async updated(page) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Updating file ${page.path}...`) - const filePath = getFilePath(page, 'path') - await this.s3.putObject({ Key: filePath, Body: page.injectMetadata() }).promise() - } - async deleted(page) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Deleting file ${page.path}...`) - const filePath = getFilePath(page, 'path') - await this.s3.deleteObject({ Key: filePath }).promise() - } - async renamed(page) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Renaming file ${page.path} to ${page.destinationPath}...`) - let sourceFilePath = getFilePath(page, 'path') - let destinationFilePath = getFilePath(page, 'destinationPath') - if (WIKI.config.lang.namespacing) { - if (WIKI.config.lang.code !== page.localeCode) { - sourceFilePath = `${page.localeCode}/${sourceFilePath}` - } - if (WIKI.config.lang.code !== page.destinationLocaleCode) { - destinationFilePath = `${page.destinationLocaleCode}/${destinationFilePath}` - } - } - await this.s3.copyObject({ CopySource: sourceFilePath, Key: destinationFilePath }).promise() - await this.s3.deleteObject({ Key: sourceFilePath }).promise() - } - /** - * ASSET UPLOAD - * - * @param {Object} asset Asset to upload - */ - async assetUploaded (asset) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Creating new file ${asset.path}...`) - await this.s3.putObject({ Key: asset.path, Body: asset.data }).promise() - } - /** - * ASSET DELETE - * - * @param {Object} asset Asset to delete - */ - async assetDeleted (asset) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Deleting file ${asset.path}...`) - await this.s3.deleteObject({ Key: asset.path }).promise() - } - /** - * ASSET RENAME - * - * @param {Object} asset Asset to rename - */ - async assetRenamed (asset) { - WIKI.logger.info(`(STORAGE/${this.storageName}) Renaming file from ${asset.path} to ${asset.destinationPath}...`) - await this.s3.copyObject({ CopySource: asset.path, Key: asset.destinationPath }).promise() - await this.s3.deleteObject({ Key: asset.path }).promise() - } - async getLocalLocation () { - - } - /** - * HANDLERS - */ - async exportAll() { - WIKI.logger.info(`(STORAGE/${this.storageName}) Exporting all content to the cloud provider...`) - - // -> Pages - await pipeline( - WIKI.db.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ - isPrivate: false - }).stream(), - new stream.Transform({ - objectMode: true, - transform: async (page, enc, cb) => { - const filePath = getFilePath(page, 'path') - WIKI.logger.info(`(STORAGE/${this.storageName}) Adding page ${filePath}...`) - await this.s3.putObject({ Key: filePath, Body: pageHelper.injectPageMetadata(page) }).promise() - cb() - } - }) - ) - - // -> Assets - const assetFolders = await WIKI.db.assetFolders.getAllPaths() - - await pipeline( - WIKI.db.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ - objectMode: true, - transform: async (asset, enc, cb) => { - const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename - WIKI.logger.info(`(STORAGE/${this.storageName}) Adding asset ${filename}...`) - await this.s3.putObject({ Key: filename, Body: asset.data }).promise() - cb() - } - }) - ) - - WIKI.logger.info(`(STORAGE/${this.storageName}) All content has been pushed to the cloud provider.`) - } -} diff --git a/server/modules/storage/sftp/definition.yml b/server/modules/storage/sftp/definition.yml deleted file mode 100644 index 192eb6c08..000000000 --- a/server/modules/storage/sftp/definition.yml +++ /dev/null @@ -1,94 +0,0 @@ -title: 'SFTP' -icon: '/_assets/icons/ultraviolet-nas.svg' -banner: '/_assets/storage/ssh.jpg' -description: 'Store files over a remote connection using the SSH File Transfer Protocol.' -vendor: 'Wiki.js' -website: 'https://js.wiki' -assetDelivery: - isStreamingSupported: false - isDirectAccessSupported: false - defaultStreamingEnabled: false - defaultDirectAccessEnabled: false -contentTypes: - defaultTypesEnabled: ['pages', 'images', 'documents', 'others', 'large'] - defaultLargeThreshold: '5MB' -versioning: - isSupported: false - defaultEnabled: false -sync: false -props: - host: - type: String - title: Host - default: '' - hint: Hostname or IP of the remote SSH server. - icon: dns - order: 1 - port: - type: Number - title: Port - default: 22 - hint: SSH port of the remote server. - icon: ethernet-off - order: 2 - authMode: - type: String - title: Authentication Method - default: 'privateKey' - hint: Whether to use Private Key or Password-based authentication. A private key is highly recommended for best security. - icon: grand-master-key - enum: - - privateKey|Private Key - - password|Password - enumDisplay: buttons - order: 3 - username: - type: String - title: Username - default: '' - hint: Username for authentication. - icon: test-account - order: 4 - privateKey: - type: String - title: Private Key Contents - default: '' - hint: Contents of the private key - icon: key - multiline: true - sensitive: true - order: 5 - if: - - { key: 'authMode', eq: 'privateKey' } - passphrase: - type: String - title: Private Key Passphrase - default: '' - hint: Passphrase if the private key is encrypted, leave empty otherwise - icon: password - sensitive: true - order: 6 - if: - - { key: 'authMode', eq: 'privateKey' } - password: - type: String - title: Password - default: '' - hint: Password for authentication - icon: password - sensitive: true - order: 6 - if: - - { key: 'authMode', eq: 'password' } - basePath: - type: String - title: Base Directory Path - default: '/root/wiki' - hint: Base directory where files will be transferred to. The path must already exists and be writable by the user. - icon: symlink-directory -actions: - exportAll: - label: Export All DB Assets to Remote - hint: Output all content from the DB to the remote SSH server, overwriting any existing data. If you enabled SFTP after content was created or you temporarily disabled it, you'll want to execute this action to add the missing content. - icon: this-way-up - diff --git a/server/modules/storage/sftp/storage.js b/server/modules/storage/sftp/storage.js deleted file mode 100644 index 0bd3e9bc5..000000000 --- a/server/modules/storage/sftp/storage.js +++ /dev/null @@ -1,161 +0,0 @@ -const SSH2Promise = require('ssh2-promise') -const _ = require('lodash') -const path = require('node:path') -const stream = require('node:stream') -const util = require('node:util') -const pipeline = util.promisify(stream.pipeline) -const pageHelper = require('../../../helpers/page.js') - -const getFilePath = (page, pathKey) => { - const fileName = `${page[pathKey]}.${pageHelper.getFileExtension(page.contentType)}` - const withLocaleCode = WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode - return withLocaleCode ? `${page.localeCode}/${fileName}` : fileName -} - -module.exports = { - client: null, - sftp: null, - async activated() { - - }, - async deactivated() { - - }, - async init() { - WIKI.logger.info(`(STORAGE/SFTP) Initializing...`) - this.client = new SSH2Promise({ - host: this.config.host, - port: this.config.port || 22, - username: this.config.username, - password: (this.config.authMode === 'password') ? this.config.password : null, - privateKey: (this.config.authMode === 'privateKey') ? this.config.privateKey : null, - passphrase: (this.config.authMode === 'privateKey') ? this.config.passphrase : null - }) - await this.client.connect() - this.sftp = this.client.sftp() - try { - await this.sftp.readdir(this.config.basePath) - } catch (err) { - WIKI.logger.warn(`(STORAGE/SFTP) ${err.message}`) - throw new Error(`Unable to read specified base directory: ${err.message}`) - } - WIKI.logger.info(`(STORAGE/SFTP) Initialization completed.`) - }, - async created(page) { - WIKI.logger.info(`(STORAGE/SFTP) Creating file ${page.path}...`) - const filePath = getFilePath(page, 'path') - await this.ensureDirectory(filePath) - await this.sftp.writeFile(path.posix.join(this.config.basePath, filePath), page.injectMetadata()) - }, - async updated(page) { - WIKI.logger.info(`(STORAGE/SFTP) Updating file ${page.path}...`) - const filePath = getFilePath(page, 'path') - await this.ensureDirectory(filePath) - await this.sftp.writeFile(path.posix.join(this.config.basePath, filePath), page.injectMetadata()) - }, - async deleted(page) { - WIKI.logger.info(`(STORAGE/SFTP) Deleting file ${page.path}...`) - const filePath = getFilePath(page, 'path') - await this.sftp.unlink(path.posix.join(this.config.basePath, filePath)) - }, - async renamed(page) { - WIKI.logger.info(`(STORAGE/SFTP) Renaming file ${page.path} to ${page.destinationPath}...`) - let sourceFilePath = getFilePath(page, 'path') - let destinationFilePath = getFilePath(page, 'destinationPath') - if (WIKI.config.lang.namespacing) { - if (WIKI.config.lang.code !== page.localeCode) { - sourceFilePath = `${page.localeCode}/${sourceFilePath}` - } - if (WIKI.config.lang.code !== page.destinationLocaleCode) { - destinationFilePath = `${page.destinationLocaleCode}/${destinationFilePath}` - } - } - await this.ensureDirectory(destinationFilePath) - await this.sftp.rename(path.posix.join(this.config.basePath, sourceFilePath), path.posix.join(this.config.basePath, destinationFilePath)) - }, - /** - * ASSET UPLOAD - * - * @param {Object} asset Asset to upload - */ - async assetUploaded (asset) { - WIKI.logger.info(`(STORAGE/SFTP) Creating new file ${asset.path}...`) - await this.ensureDirectory(asset.path) - await this.sftp.writeFile(path.posix.join(this.config.basePath, asset.path), asset.data) - }, - /** - * ASSET DELETE - * - * @param {Object} asset Asset to delete - */ - async assetDeleted (asset) { - WIKI.logger.info(`(STORAGE/SFTP) Deleting file ${asset.path}...`) - await this.sftp.unlink(path.posix.join(this.config.basePath, asset.path)) - }, - /** - * ASSET RENAME - * - * @param {Object} asset Asset to rename - */ - async assetRenamed (asset) { - WIKI.logger.info(`(STORAGE/SFTP) Renaming file from ${asset.path} to ${asset.destinationPath}...`) - await this.ensureDirectory(asset.destinationPath) - await this.sftp.rename(path.posix.join(this.config.basePath, asset.path), path.posix.join(this.config.basePath, asset.destinationPath)) - }, - async getLocalLocation () { - - }, - /** - * HANDLERS - */ - async exportAll() { - WIKI.logger.info(`(STORAGE/SFTP) Exporting all content to the remote server...`) - - // -> Pages - await pipeline( - WIKI.db.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ - isPrivate: false - }).stream(), - new stream.Transform({ - objectMode: true, - transform: async (page, enc, cb) => { - const filePath = getFilePath(page, 'path') - WIKI.logger.info(`(STORAGE/SFTP) Adding page ${filePath}...`) - await this.ensureDirectory(filePath) - await this.sftp.writeFile(path.posix.join(this.config.basePath, filePath), pageHelper.injectPageMetadata(page)) - cb() - } - }) - ) - - // -> Assets - const assetFolders = await WIKI.db.assetFolders.getAllPaths() - - await pipeline( - WIKI.db.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ - objectMode: true, - transform: async (asset, enc, cb) => { - const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename - WIKI.logger.info(`(STORAGE/SFTP) Adding asset ${filename}...`) - await this.ensureDirectory(filename) - await this.sftp.writeFile(path.posix.join(this.config.basePath, filename), asset.data) - cb() - } - }) - ) - - WIKI.logger.info('(STORAGE/SFTP) All content has been pushed to the remote server.') - }, - async ensureDirectory(filePath) { - if (filePath.indexOf('/') >= 0) { - try { - const folderPaths = _.dropRight(filePath.split('/')) - for (let i = 1; i <= folderPaths.length; i++) { - const folderSection = _.take(folderPaths, i).join('/') - await this.sftp.mkdir(path.posix.join(this.config.basePath, folderSection)) - } - } catch (err) {} - } - } -} diff --git a/server/package.json b/server/package.json deleted file mode 100644 index 0a2847033..000000000 --- a/server/package.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "name": "wiki-server", - "version": "3.0.0", - "releaseDate": "2023-01-01T01:01:01.000Z", - "description": "The most powerful and extensible open source Wiki software", - "main": "index.mjs", - "type": "module", - "private": true, - "dev": true, - "scripts": { - "start": "cd .. && node server", - "dev": "cd .. && nodemon server --watch server --ext mjs,js,json,graphql,gql", - "ncu": "ncu -i -x codemirror,codemirror-asciidoc", - "ncu-u": "ncu -u -x codemirror,codemirror-asciidoc" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Requarks/wiki.git" - }, - "keywords": [ - "wiki", - "wikis", - "docs", - "documentation", - "markdown", - "guides", - "knowledge base" - ], - "author": "Nicolas Giard", - "license": "AGPL-3.0", - "bugs": { - "url": "https://github.com/Requarks/wiki/issues" - }, - "homepage": "https://github.com/Requarks/wiki#readme", - "engines": { - "node": ">=18.0" - }, - "dependencies": { - "@apollo/server": "5.0.0", - "@as-integrations/express5": "1.1.2", - "@azure/storage-blob": "12.28.0", - "@exlinc/keycloak-passport": "1.0.2", - "@graphql-tools/schema": "10.0.25", - "@graphql-tools/utils": "10.9.1", - "@hexagon/base64": "2.0.4", - "@joplin/turndown-plugin-gfm": "1.0.62", - "@node-saml/passport-saml": "5.1.0", - "@root/csr": "0.8.1", - "@root/keypairs": "0.10.3", - "@root/pem": "1.0.4", - "@simplewebauthn/server": "13.1.2", - "@vue-email/compiler": "0.8.14", - "acme": "3.0.3", - "akismet-api": "6.0.0", - "aws-sdk": "2.1692.0", - "bcryptjs": "3.0.2", - "chalk": "5.4.1", - "cheerio": "1.1.2", - "chokidar": "4.0.3", - "chromium-pickle-js": "0.2.0", - "clean-css": "5.3.3", - "command-exists": "1.2.9", - "compression": "1.8.1", - "connect-session-knex": "5.0.0", - "cookie-parser": "1.4.7", - "cors": "2.8.5", - "cron-parser": "5.3.0", - "cuint": "0.2.2", - "custom-error-instance": "2.1.2", - "dependency-graph": "1.0.0", - "diff": "8.0.2", - "diff2html": "3.4.52", - "dompurify": "3.2.6", - "dotize": "0.6.0", - "emoji-regex": "10.4.0", - "eventemitter2": "6.4.9", - "express": "5.1.0", - "express-brute": "1.0.1", - "express-session": "1.18.2", - "file-type": "21.0.0", - "filesize": "11.0.2", - "fs-extra": "11.3.0", - "getos": "3.2.1", - "graphql": "16.11.0", - "graphql-list-fields": "2.0.4", - "graphql-rate-limit-directive": "2.0.6", - "graphql-tools": "9.0.20", - "graphql-upload": "17.0.0", - "gray-matter": "4.0.3", - "he": "1.2.0", - "highlight.js": "11.11.1", - "image-size": "2.0.2", - "js-base64": "3.7.7", - "js-binary": "1.2.0", - "js-yaml": "4.1.0", - "jsdom": "26.1.0", - "jsonwebtoken": "9.0.2", - "katex": "0.16.22", - "klaw": "4.1.0", - "knex": "3.1.0", - "lodash": "4.17.21", - "lodash-es": "4.17.21", - "luxon": "3.7.1", - "markdown-it": "14.1.0", - "markdown-it-abbr": "2.0.0", - "markdown-it-attrs": "4.3.1", - "markdown-it-decorate": "1.2.2", - "markdown-it-emoji": "3.0.0", - "markdown-it-expand-tabs": "1.0.13", - "markdown-it-footnote": "4.0.0", - "markdown-it-imsize": "2.0.1", - "markdown-it-mark": "4.0.0", - "markdown-it-mdc": "0.2.6", - "markdown-it-multimd-table": "4.2.3", - "markdown-it-sub": "2.0.0", - "markdown-it-sup": "2.0.0", - "markdown-it-task-lists": "2.1.1", - "mathjax": "3.2.2", - "mime-types": "3.0.1", - "ms": "2.1.3", - "multer": "2.0.2", - "nanoid": "5.1.5", - "node-2fa": "2.0.3", - "node-cache": "5.1.2", - "nodemailer": "7.0.5", - "objection": "3.1.5", - "octokit": "5.0.3", - "pako": "2.1.0", - "passport": "0.7.0", - "passport-auth0": "1.4.4", - "passport-cas": "0.1.1", - "passport-discord": "0.1.4", - "passport-dropbox-oauth2": "1.1.0", - "passport-facebook": "3.0.0", - "passport-github2": "0.1.12", - "passport-gitlab2": "5.0.0", - "passport-google-oauth20": "2.0.0", - "passport-jwt": "4.0.1", - "passport-ldapauth": "3.0.1", - "passport-local": "1.0.0", - "passport-microsoft": "2.1.0", - "passport-oauth2": "1.8.0", - "passport-okta-oauth": "0.0.1", - "passport-openidconnect": "0.1.2", - "passport-slack-oauth2": "1.2.0", - "passport-twitch-strategy": "2.2.0", - "pem-jwk": "2.0.0", - "pg": "8.16.3", - "pg-hstore": "2.3.4", - "pg-pubsub": "0.8.1", - "pg-query-stream": "4.10.3", - "pg-tsquery": "8.4.2", - "poolifier": "5.1.0", - "prom-client": "15.1.3", - "punycode": "2.3.1", - "puppeteer-core": "24.15.0", - "qr-image": "3.2.0", - "remove-markdown": "0.6.2", - "safe-regex": "2.1.1", - "sanitize-filename": "1.6.3", - "scim-query-filter-parser": "2.0.4", - "semver": "7.7.2", - "serve-favicon": "2.5.1", - "sharp": "0.34.3", - "simple-git": "3.28.0", - "socket.io": "4.8.1", - "striptags": "3.2.0", - "tar-fs": "3.1.0", - "turndown": "7.2.0", - "twemoji": "14.0.2", - "ufo": "1.6.1", - "uslug": "1.0.4", - "uuid": "11.1.0", - "validate.js": "0.13.1", - "vue": "3.5.18", - "xss": "1.0.15" - }, - "devDependencies": { - "eslint": "9.32.0", - "eslint-plugin-import": "2.32.0", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "7.2.1", - "neostandard": "0.12.2", - "nodemon": "3.1.10" - }, - "overrides": { - "@graphql-tools/utils": "10.5.5" - }, - "collective": { - "type": "opencollective", - "url": "https://opencollective.com/wikijs", - "logo": "https://opencollective.com/opencollective/logo.txt" - }, - "packageManager": "pnpm@9.12.2+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228" -} diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml deleted file mode 100644 index f3161c943..000000000 --- a/server/pnpm-lock.yaml +++ /dev/null @@ -1,10575 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@apollo/server': - specifier: 5.0.0 - version: 5.0.0(graphql@16.11.0) - '@as-integrations/express5': - specifier: 1.1.2 - version: 1.1.2(@apollo/server@5.0.0(graphql@16.11.0))(express@5.1.0) - '@azure/storage-blob': - specifier: 12.28.0 - version: 12.28.0 - '@exlinc/keycloak-passport': - specifier: 1.0.2 - version: 1.0.2 - '@graphql-tools/schema': - specifier: 10.0.25 - version: 10.0.25(graphql@16.11.0) - '@graphql-tools/utils': - specifier: 10.9.1 - version: 10.9.1(graphql@16.11.0) - '@hexagon/base64': - specifier: 2.0.4 - version: 2.0.4 - '@joplin/turndown-plugin-gfm': - specifier: 1.0.62 - version: 1.0.62 - '@node-saml/passport-saml': - specifier: 5.1.0 - version: 5.1.0 - '@root/csr': - specifier: 0.8.1 - version: 0.8.1 - '@root/keypairs': - specifier: 0.10.3 - version: 0.10.3 - '@root/pem': - specifier: 1.0.4 - version: 1.0.4 - '@simplewebauthn/server': - specifier: 13.1.2 - version: 13.1.2 - '@vue-email/compiler': - specifier: 0.8.14 - version: 0.8.14(typescript@5.6.3)(vue@3.5.18(typescript@5.6.3)) - acme: - specifier: 3.0.3 - version: 3.0.3 - akismet-api: - specifier: 6.0.0 - version: 6.0.0 - aws-sdk: - specifier: 2.1692.0 - version: 2.1692.0 - bcryptjs: - specifier: 3.0.2 - version: 3.0.2 - chalk: - specifier: 5.4.1 - version: 5.4.1 - cheerio: - specifier: 1.1.2 - version: 1.1.2 - chokidar: - specifier: 4.0.3 - version: 4.0.3 - chromium-pickle-js: - specifier: 0.2.0 - version: 0.2.0 - clean-css: - specifier: 5.3.3 - version: 5.3.3 - command-exists: - specifier: 1.2.9 - version: 1.2.9 - compression: - specifier: 1.8.1 - version: 1.8.1 - connect-session-knex: - specifier: 5.0.0 - version: 5.0.0(pg@8.16.3) - cookie-parser: - specifier: 1.4.7 - version: 1.4.7 - cors: - specifier: 2.8.5 - version: 2.8.5 - cron-parser: - specifier: 5.3.0 - version: 5.3.0 - cuint: - specifier: 0.2.2 - version: 0.2.2 - custom-error-instance: - specifier: 2.1.2 - version: 2.1.2 - dependency-graph: - specifier: 1.0.0 - version: 1.0.0 - diff: - specifier: 8.0.2 - version: 8.0.2 - diff2html: - specifier: 3.4.52 - version: 3.4.52 - dompurify: - specifier: 3.2.6 - version: 3.2.6 - dotize: - specifier: 0.6.0 - version: 0.6.0 - emoji-regex: - specifier: 10.4.0 - version: 10.4.0 - eventemitter2: - specifier: 6.4.9 - version: 6.4.9 - express: - specifier: 5.1.0 - version: 5.1.0 - express-brute: - specifier: 1.0.1 - version: 1.0.1(express@5.1.0) - express-session: - specifier: 1.18.2 - version: 1.18.2 - file-type: - specifier: 21.0.0 - version: 21.0.0 - filesize: - specifier: 11.0.2 - version: 11.0.2 - fs-extra: - specifier: 11.3.0 - version: 11.3.0 - getos: - specifier: 3.2.1 - version: 3.2.1 - graphql: - specifier: 16.11.0 - version: 16.11.0 - graphql-list-fields: - specifier: 2.0.4 - version: 2.0.4 - graphql-rate-limit-directive: - specifier: 2.0.6 - version: 2.0.6(@graphql-tools/utils@10.9.1(graphql@16.11.0))(graphql@16.11.0)(rate-limiter-flexible@5.0.4) - graphql-tools: - specifier: 9.0.20 - version: 9.0.20(graphql@16.11.0) - graphql-upload: - specifier: 17.0.0 - version: 17.0.0(@types/express@5.0.0)(graphql@16.11.0) - gray-matter: - specifier: 4.0.3 - version: 4.0.3 - he: - specifier: 1.2.0 - version: 1.2.0 - highlight.js: - specifier: 11.11.1 - version: 11.11.1 - image-size: - specifier: 2.0.2 - version: 2.0.2 - js-base64: - specifier: 3.7.7 - version: 3.7.7 - js-binary: - specifier: 1.2.0 - version: 1.2.0 - js-yaml: - specifier: 4.1.0 - version: 4.1.0 - jsdom: - specifier: 26.1.0 - version: 26.1.0 - jsonwebtoken: - specifier: 9.0.2 - version: 9.0.2 - katex: - specifier: 0.16.22 - version: 0.16.22 - klaw: - specifier: 4.1.0 - version: 4.1.0 - knex: - specifier: 3.1.0 - version: 3.1.0(pg@8.16.3) - lodash: - specifier: 4.17.21 - version: 4.17.21 - lodash-es: - specifier: 4.17.21 - version: 4.17.21 - luxon: - specifier: 3.7.1 - version: 3.7.1 - markdown-it: - specifier: 14.1.0 - version: 14.1.0 - markdown-it-abbr: - specifier: 2.0.0 - version: 2.0.0 - markdown-it-attrs: - specifier: 4.3.1 - version: 4.3.1(markdown-it@14.1.0) - markdown-it-decorate: - specifier: 1.2.2 - version: 1.2.2 - markdown-it-emoji: - specifier: 3.0.0 - version: 3.0.0 - markdown-it-expand-tabs: - specifier: 1.0.13 - version: 1.0.13 - markdown-it-footnote: - specifier: 4.0.0 - version: 4.0.0 - markdown-it-imsize: - specifier: 2.0.1 - version: 2.0.1 - markdown-it-mark: - specifier: 4.0.0 - version: 4.0.0 - markdown-it-mdc: - specifier: 0.2.6 - version: 0.2.6(@types/markdown-it@14.1.2)(markdown-it@14.1.0) - markdown-it-multimd-table: - specifier: 4.2.3 - version: 4.2.3 - markdown-it-sub: - specifier: 2.0.0 - version: 2.0.0 - markdown-it-sup: - specifier: 2.0.0 - version: 2.0.0 - markdown-it-task-lists: - specifier: 2.1.1 - version: 2.1.1 - mathjax: - specifier: 3.2.2 - version: 3.2.2 - mime-types: - specifier: 3.0.1 - version: 3.0.1 - ms: - specifier: 2.1.3 - version: 2.1.3 - multer: - specifier: 2.0.2 - version: 2.0.2 - nanoid: - specifier: 5.1.5 - version: 5.1.5 - node-2fa: - specifier: 2.0.3 - version: 2.0.3 - node-cache: - specifier: 5.1.2 - version: 5.1.2 - nodemailer: - specifier: 7.0.5 - version: 7.0.5 - objection: - specifier: 3.1.5 - version: 3.1.5(knex@3.1.0(pg@8.16.3)) - octokit: - specifier: 5.0.3 - version: 5.0.3 - pako: - specifier: 2.1.0 - version: 2.1.0 - passport: - specifier: 0.7.0 - version: 0.7.0 - passport-auth0: - specifier: 1.4.4 - version: 1.4.4 - passport-cas: - specifier: 0.1.1 - version: 0.1.1 - passport-discord: - specifier: 0.1.4 - version: 0.1.4 - passport-dropbox-oauth2: - specifier: 1.1.0 - version: 1.1.0 - passport-facebook: - specifier: 3.0.0 - version: 3.0.0 - passport-github2: - specifier: 0.1.12 - version: 0.1.12 - passport-gitlab2: - specifier: 5.0.0 - version: 5.0.0 - passport-google-oauth20: - specifier: 2.0.0 - version: 2.0.0 - passport-jwt: - specifier: 4.0.1 - version: 4.0.1 - passport-ldapauth: - specifier: 3.0.1 - version: 3.0.1 - passport-local: - specifier: 1.0.0 - version: 1.0.0 - passport-microsoft: - specifier: 2.1.0 - version: 2.1.0 - passport-oauth2: - specifier: 1.8.0 - version: 1.8.0 - passport-okta-oauth: - specifier: 0.0.1 - version: 0.0.1 - passport-openidconnect: - specifier: 0.1.2 - version: 0.1.2 - passport-slack-oauth2: - specifier: 1.2.0 - version: 1.2.0 - passport-twitch-strategy: - specifier: 2.2.0 - version: 2.2.0 - pem-jwk: - specifier: 2.0.0 - version: 2.0.0 - pg: - specifier: 8.16.3 - version: 8.16.3 - pg-hstore: - specifier: 2.3.4 - version: 2.3.4 - pg-pubsub: - specifier: 0.8.1 - version: 0.8.1 - pg-query-stream: - specifier: 4.10.3 - version: 4.10.3(pg@8.16.3) - pg-tsquery: - specifier: 8.4.2 - version: 8.4.2 - poolifier: - specifier: 5.1.0 - version: 5.1.0 - prom-client: - specifier: 15.1.3 - version: 15.1.3 - punycode: - specifier: 2.3.1 - version: 2.3.1 - puppeteer-core: - specifier: 24.15.0 - version: 24.15.0 - qr-image: - specifier: 3.2.0 - version: 3.2.0 - remove-markdown: - specifier: 0.6.2 - version: 0.6.2 - safe-regex: - specifier: 2.1.1 - version: 2.1.1 - sanitize-filename: - specifier: 1.6.3 - version: 1.6.3 - scim-query-filter-parser: - specifier: 2.0.4 - version: 2.0.4 - semver: - specifier: 7.7.2 - version: 7.7.2 - serve-favicon: - specifier: 2.5.1 - version: 2.5.1 - sharp: - specifier: 0.34.3 - version: 0.34.3 - simple-git: - specifier: 3.28.0 - version: 3.28.0 - socket.io: - specifier: 4.8.1 - version: 4.8.1 - striptags: - specifier: 3.2.0 - version: 3.2.0 - tar-fs: - specifier: 3.1.0 - version: 3.1.0 - turndown: - specifier: 7.2.0 - version: 7.2.0 - twemoji: - specifier: 14.0.2 - version: 14.0.2 - ufo: - specifier: 1.6.1 - version: 1.6.1 - uslug: - specifier: 1.0.4 - version: 1.0.4 - uuid: - specifier: 11.1.0 - version: 11.1.0 - validate.js: - specifier: 0.13.1 - version: 0.13.1 - vue: - specifier: 3.5.18 - version: 3.5.18(typescript@5.6.3) - xss: - specifier: 1.0.15 - version: 1.0.15 - devDependencies: - eslint: - specifier: 9.32.0 - version: 9.32.0(jiti@2.3.3) - eslint-plugin-import: - specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3)) - eslint-plugin-node: - specifier: 11.1.0 - version: 11.1.0(eslint@9.32.0(jiti@2.3.3)) - eslint-plugin-promise: - specifier: 7.2.1 - version: 7.2.1(eslint@9.32.0(jiti@2.3.3)) - neostandard: - specifier: 0.12.2 - version: 0.12.2(@typescript-eslint/utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3)))(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - nodemon: - specifier: 3.1.10 - version: 3.1.10 - -packages: - - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - - '@apollo/cache-control-types@1.0.3': - resolution: {integrity: sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==} - peerDependencies: - graphql: 14.x || 15.x || 16.x - - '@apollo/client@3.13.8': - resolution: {integrity: sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg==} - peerDependencies: - graphql: ^15.0.0 || ^16.0.0 - graphql-ws: ^5.5.5 || ^6.0.3 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc - subscriptions-transport-ws: ^0.9.0 || ^0.11.0 - peerDependenciesMeta: - graphql-ws: - optional: true - react: - optional: true - react-dom: - optional: true - subscriptions-transport-ws: - optional: true - - '@apollo/protobufjs@1.2.7': - resolution: {integrity: sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==} - hasBin: true - - '@apollo/server-gateway-interface@2.0.0': - resolution: {integrity: sha512-3HEMD6fSantG2My3jWkb9dvfkF9vJ4BDLRjMgsnD790VINtuPaEp+h3Hg9HOHiWkML6QsOhnaRqZ+gvhp3y8Nw==} - peerDependencies: - graphql: 14.x || 15.x || 16.x - - '@apollo/server@5.0.0': - resolution: {integrity: sha512-PHopOm7pr69k7eDJvCBU4cZy9Z19qyCFKB9/luLnf2YCatu2WOYhoQPNr3dAoe//xv0RZFhxXbRcnK6IXIP7Nw==} - engines: {node: '>=20'} - peerDependencies: - graphql: ^16.11.0 - - '@apollo/usage-reporting-protobuf@4.1.1': - resolution: {integrity: sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==} - - '@apollo/utils.createhash@3.0.1': - resolution: {integrity: sha512-CKrlySj4eQYftBE5MJ8IzKwIibQnftDT7yGfsJy5KSEEnLlPASX0UTpbKqkjlVEwPPd4mEwI7WOM7XNxEuO05A==} - engines: {node: '>=16'} - - '@apollo/utils.dropunuseddefinitions@2.0.1': - resolution: {integrity: sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==} - engines: {node: '>=14'} - peerDependencies: - graphql: 14.x || 15.x || 16.x - - '@apollo/utils.fetcher@3.1.0': - resolution: {integrity: sha512-Z3QAyrsQkvrdTuHAFwWDNd+0l50guwoQUoaDQssLOjkmnmVuvXlJykqlEJolio+4rFwBnWdoY1ByFdKaQEcm7A==} - engines: {node: '>=16'} - - '@apollo/utils.isnodelike@3.0.0': - resolution: {integrity: sha512-xrjyjfkzunZ0DeF6xkHaK5IKR8F1FBq6qV+uZ+h9worIF/2YSzA0uoBxGv6tbTeo9QoIQnRW4PVFzGix5E7n/g==} - engines: {node: '>=16'} - - '@apollo/utils.keyvaluecache@4.0.0': - resolution: {integrity: sha512-mKw1myRUkQsGPNB+9bglAuhviodJ2L2MRYLTafCMw5BIo7nbvCPNCkLnIHjZ1NOzH7SnMAr5c9LmXiqsgYqLZw==} - engines: {node: '>=20'} - - '@apollo/utils.logger@3.0.0': - resolution: {integrity: sha512-M8V8JOTH0F2qEi+ktPfw4RL7MvUycDfKp7aEap2eWXfL5SqWHN6jTLbj5f5fj1cceHpyaUSOZlvlaaryaxZAmg==} - engines: {node: '>=16'} - - '@apollo/utils.printwithreducedwhitespace@2.0.1': - resolution: {integrity: sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==} - engines: {node: '>=14'} - peerDependencies: - graphql: 14.x || 15.x || 16.x - - '@apollo/utils.removealiases@2.0.1': - resolution: {integrity: sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==} - engines: {node: '>=14'} - peerDependencies: - graphql: 14.x || 15.x || 16.x - - '@apollo/utils.sortast@2.0.1': - resolution: {integrity: sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==} - engines: {node: '>=14'} - peerDependencies: - graphql: 14.x || 15.x || 16.x - - '@apollo/utils.stripsensitiveliterals@2.0.1': - resolution: {integrity: sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==} - engines: {node: '>=14'} - peerDependencies: - graphql: 14.x || 15.x || 16.x - - '@apollo/utils.usagereporting@2.1.0': - resolution: {integrity: sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==} - engines: {node: '>=14'} - peerDependencies: - graphql: 14.x || 15.x || 16.x - - '@apollo/utils.withrequired@3.0.0': - resolution: {integrity: sha512-aaxeavfJ+RHboh7c2ofO5HHtQobGX4AgUujXP4CXpREHp9fQ9jPi6K9T1jrAKe7HIipoP0OJ1gd6JamSkFIpvA==} - engines: {node: '>=16'} - - '@as-integrations/express5@1.1.2': - resolution: {integrity: sha512-BxfwtcWNf2CELDkuPQxi5Zl3WqY/dQVJYafeCBOGoFQjv5M0fjhxmAFZ9vKx/5YKKNeok4UY6PkFbHzmQrdxIA==} - engines: {node: '>=20'} - peerDependencies: - '@apollo/server': ^4.0.0 || ^5.0.0 - express: ^5.0.0 - - '@asamuzakjp/css-color@3.2.0': - resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} - - '@azure/abort-controller@2.1.2': - resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} - engines: {node: '>=18.0.0'} - - '@azure/core-auth@1.10.0': - resolution: {integrity: sha512-88Djs5vBvGbHQHf5ZZcaoNHo6Y8BKZkt3cw2iuJIQzLEgH4Ox6Tm4hjFhbqOxyYsgIG/eJbFEHpxRIfEEWv5Ow==} - engines: {node: '>=20.0.0'} - - '@azure/core-client@1.10.0': - resolution: {integrity: sha512-O4aP3CLFNodg8eTHXECaH3B3CjicfzkxVtnrfLkOq0XNP7TIECGfHpK/C6vADZkWP75wzmdBnsIA8ksuJMk18g==} - engines: {node: '>=20.0.0'} - - '@azure/core-http-compat@2.3.0': - resolution: {integrity: sha512-qLQujmUypBBG0gxHd0j6/Jdmul6ttl24c8WGiLXIk7IHXdBlfoBqW27hyz3Xn6xbfdyVSarl1Ttbk0AwnZBYCw==} - engines: {node: '>=18.0.0'} - - '@azure/core-lro@2.7.2': - resolution: {integrity: sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw==} - engines: {node: '>=18.0.0'} - - '@azure/core-paging@1.6.2': - resolution: {integrity: sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA==} - engines: {node: '>=18.0.0'} - - '@azure/core-rest-pipeline@1.22.0': - resolution: {integrity: sha512-OKHmb3/Kpm06HypvB3g6Q3zJuvyXcpxDpCS1PnU8OV6AJgSFaee/covXBcPbWc6XDDxtEPlbi3EMQ6nUiPaQtw==} - engines: {node: '>=20.0.0'} - - '@azure/core-tracing@1.3.0': - resolution: {integrity: sha512-+XvmZLLWPe67WXNZo9Oc9CrPj/Tm8QnHR92fFAFdnbzwNdCH1h+7UdpaQgRSBsMY+oW1kHXNUZQLdZ1gHX3ROw==} - engines: {node: '>=20.0.0'} - - '@azure/core-util@1.13.0': - resolution: {integrity: sha512-o0psW8QWQ58fq3i24Q1K2XfS/jYTxr7O1HRcyUE9bV9NttLU+kYOH82Ixj8DGlMTOWgxm1Sss2QAfKK5UkSPxw==} - engines: {node: '>=20.0.0'} - - '@azure/core-xml@1.5.0': - resolution: {integrity: sha512-D/sdlJBMJfx7gqoj66PKVmhDDaU6TKA49ptcolxdas29X7AfvLTmfAGLjAcIMBK7UZ2o4lygHIqVckOlQU3xWw==} - engines: {node: '>=20.0.0'} - - '@azure/logger@1.3.0': - resolution: {integrity: sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==} - engines: {node: '>=20.0.0'} - - '@azure/storage-blob@12.28.0': - resolution: {integrity: sha512-VhQHITXXO03SURhDiGuHhvc/k/sD2WvJUS7hqhiVNbErVCuQoLtWql7r97fleBlIRKHJaa9R7DpBjfE0pfLYcA==} - engines: {node: '>=20.0.0'} - - '@azure/storage-common@12.0.0': - resolution: {integrity: sha512-QyEWXgi4kdRo0wc1rHum9/KnaWZKCdQGZK1BjU4fFL6Jtedp7KLbQihgTTVxldFy1z1ZPtuDPx8mQ5l3huPPbA==} - engines: {node: '>=20.0.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.28.0': - resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} - engines: {node: '>=6.9.0'} - - '@csstools/color-helpers@5.0.2': - resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} - engines: {node: '>=18'} - - '@csstools/css-calc@2.1.4': - resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-color-parser@3.0.10': - resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-parser-algorithms@3.0.5': - resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} - engines: {node: '>=18'} - peerDependencies: - '@csstools/css-tokenizer': ^3.0.4 - - '@csstools/css-tokenizer@3.0.4': - resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} - engines: {node: '>=18'} - - '@emnapi/core@1.4.5': - resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} - - '@emnapi/runtime@1.4.5': - resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} - - '@emnapi/wasi-threads@1.0.4': - resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} - - '@esbuild/android-arm@0.15.18': - resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/linux-loong64@0.15.18': - resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@eslint-community/eslint-utils@4.4.1': - resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.3.0': - resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.15.1': - resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.32.0': - resolution: {integrity: sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.3.4': - resolution: {integrity: sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@exlinc/keycloak-passport@1.0.2': - resolution: {integrity: sha512-mUZdBq5peaHRNf8pd6XxgNWk4aY477Gy9XqF0WGHBmCygA2tX4EOvnoI/yHhu0ceAY08g3ng9BbEFKlSMRHWcg==} - - '@graphql-tools/merge@9.1.1': - resolution: {integrity: sha512-BJ5/7Y7GOhTuvzzO5tSBFL4NGr7PVqTJY3KeIDlVTT8YLcTXtBR+hlrC3uyEym7Ragn+zyWdHeJ9ev+nRX1X2w==} - engines: {node: '>=16.0.0'} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - - '@graphql-tools/schema@10.0.25': - resolution: {integrity: sha512-/PqE8US8kdQ7lB9M5+jlW8AyVjRGCKU7TSktuW3WNKSKmDO0MK1wakvb5gGdyT49MjAIb4a3LWxIpwo5VygZuw==} - engines: {node: '>=16.0.0'} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - - '@graphql-tools/utils@10.9.1': - resolution: {integrity: sha512-B1wwkXk9UvU7LCBkPs8513WxOQ2H8Fo5p8HR1+Id9WmYE5+bd51vqN+MbrqvWczHCH2gwkREgHJN88tE0n1FCw==} - engines: {node: '>=16.0.0'} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - - '@graphql-typed-document-node/core@3.2.0': - resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - - '@hexagon/base64@1.1.28': - resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} - - '@hexagon/base64@2.0.4': - resolution: {integrity: sha512-H/ZY6rGyaEuk0mwQgZ3BVi9hMjFTYpBNFbmtOuec/pPibuGhCMXd8fGtwBaO0h44FkWMurysMsDrpkJsBRmoWQ==} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/gitignore-to-minimatch@1.0.2': - resolution: {integrity: sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@img/sharp-darwin-arm64@0.34.3': - resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.34.3': - resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.2.0': - resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.2.0': - resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.2.0': - resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.2.0': - resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-ppc64@1.2.0': - resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} - cpu: [ppc64] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.2.0': - resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.2.0': - resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': - resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.2.0': - resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.34.3': - resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.34.3': - resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-ppc64@0.34.3': - resolution: {integrity: sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ppc64] - os: [linux] - - '@img/sharp-linux-s390x@0.34.3': - resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.34.3': - resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.34.3': - resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.34.3': - resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.34.3': - resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-arm64@0.34.3': - resolution: {integrity: sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [win32] - - '@img/sharp-win32-ia32@0.34.3': - resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.34.3': - resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - - '@intlify/core-base@9.13.1': - resolution: {integrity: sha512-+bcQRkJO9pcX8d0gel9ZNfrzU22sZFSA0WVhfXrf5jdJOS24a+Bp8pozuS9sBI9Hk/tGz83pgKfmqcn/Ci7/8w==} - engines: {node: '>= 16'} - - '@intlify/message-compiler@9.13.1': - resolution: {integrity: sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==} - engines: {node: '>= 16'} - - '@intlify/shared@9.13.1': - resolution: {integrity: sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ==} - engines: {node: '>= 16'} - - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@joplin/turndown-plugin-gfm@1.0.62': - resolution: {integrity: sha512-Ts7cZ0Y9rIRgNkPtpXYB3BVjjSP2eeWzrPnQvJgNTC+FpopSjoaYjLQvPcEj1d6JcTMegnYoZK98/WJhm02Uaw==} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@kwsites/file-exists@1.1.1': - resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} - - '@kwsites/promise-deferred@1.1.1': - resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - - '@levischuck/tiny-cbor@0.2.11': - resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==} - - '@mixmark-io/domino@2.2.0': - resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} - - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - - '@node-saml/node-saml@5.1.0': - resolution: {integrity: sha512-t3cJnZ4aC7HhPZ6MGylGZULvUtBOZ6FzuUndaHGXjmIZHXnLfC/7L8a57O9Q9V7AxJGKAiRM5zu2wNm9EsvQpw==} - engines: {node: '>= 18'} - - '@node-saml/passport-saml@5.1.0': - resolution: {integrity: sha512-pBm+iFjv9eihcgeJuSUs4c0AuX1QEFdHwP8w1iaWCfDzXdeWZxUBU5HT2bY2S4dvNutcy+A9hYsH7ZLBGtgwDg==} - engines: {node: '>= 18'} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@nolyfill/is-core-module@1.0.39': - resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} - engines: {node: '>=12.4.0'} - - '@octokit/app@16.0.1': - resolution: {integrity: sha512-kgTeTsWmpUX+s3Fs4EK4w1K+jWCDB6ClxLSWUWTyhlw7+L3jHtuXDR4QtABu2GsmCMdk67xRhruiXotS3ay3Yw==} - engines: {node: '>= 20'} - - '@octokit/auth-app@8.0.2': - resolution: {integrity: sha512-dLTmmA9gUlqiAJZgozfOsZFfpN/OldH3xweb7lqSnngax5Rs+PfO5dDlokaBfc41H1xOtsLYV5QqR0DkBAtPmw==} - engines: {node: '>= 20'} - - '@octokit/auth-oauth-app@9.0.1': - resolution: {integrity: sha512-TthWzYxuHKLAbmxdFZwFlmwVyvynpyPmjwc+2/cI3cvbT7mHtsAW9b1LvQaNnAuWL+pFnqtxdmrU8QpF633i1g==} - engines: {node: '>= 20'} - - '@octokit/auth-oauth-device@8.0.1': - resolution: {integrity: sha512-TOqId/+am5yk9zor0RGibmlqn4V0h8vzjxlw/wYr3qzkQxl8aBPur384D1EyHtqvfz0syeXji4OUvKkHvxk/Gw==} - engines: {node: '>= 20'} - - '@octokit/auth-oauth-user@6.0.0': - resolution: {integrity: sha512-GV9IW134PHsLhtUad21WIeP9mlJ+QNpFd6V9vuPWmaiN25HEJeEQUcS4y5oRuqCm9iWDLtfIs+9K8uczBXKr6A==} - engines: {node: '>= 20'} - - '@octokit/auth-token@6.0.0': - resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} - engines: {node: '>= 20'} - - '@octokit/auth-unauthenticated@7.0.1': - resolution: {integrity: sha512-qVq1vdjLLZdE8kH2vDycNNjuJRCD1q2oet1nA/GXWaYlpDxlR7rdVhX/K/oszXslXiQIiqrQf+rdhDlA99JdTQ==} - engines: {node: '>= 20'} - - '@octokit/core@7.0.3': - resolution: {integrity: sha512-oNXsh2ywth5aowwIa7RKtawnkdH6LgU1ztfP9AIUCQCvzysB+WeU8o2kyyosDPwBZutPpjZDKPQGIzzrfTWweQ==} - engines: {node: '>= 20'} - - '@octokit/endpoint@11.0.0': - resolution: {integrity: sha512-hoYicJZaqISMAI3JfaDr1qMNi48OctWuOih1m80bkYow/ayPw6Jj52tqWJ6GEoFTk1gBqfanSoI1iY99Z5+ekQ==} - engines: {node: '>= 20'} - - '@octokit/graphql@9.0.1': - resolution: {integrity: sha512-j1nQNU1ZxNFx2ZtKmL4sMrs4egy5h65OMDmSbVyuCzjOcwsHq6EaYjOTGXPQxgfiN8dJ4CriYHk6zF050WEULg==} - engines: {node: '>= 20'} - - '@octokit/oauth-app@8.0.1': - resolution: {integrity: sha512-QnhMYEQpnYbEPn9cae+wXL2LuPMFglmfeuDJXXsyxIXdoORwkLK8y0cHhd/5du9MbO/zdG/BXixzB7EEwU63eQ==} - engines: {node: '>= 20'} - - '@octokit/oauth-authorization-url@8.0.0': - resolution: {integrity: sha512-7QoLPRh/ssEA/HuHBHdVdSgF8xNLz/Bc5m9fZkArJE5bb6NmVkDm3anKxXPmN1zh6b5WKZPRr3697xKT/yM3qQ==} - engines: {node: '>= 20'} - - '@octokit/oauth-methods@6.0.0': - resolution: {integrity: sha512-Q8nFIagNLIZgM2odAraelMcDssapc+lF+y3OlcIPxyAU+knefO8KmozGqfnma1xegRDP4z5M73ABsamn72bOcA==} - engines: {node: '>= 20'} - - '@octokit/openapi-types@25.1.0': - resolution: {integrity: sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==} - - '@octokit/openapi-webhooks-types@12.0.3': - resolution: {integrity: sha512-90MF5LVHjBedwoHyJsgmaFhEN1uzXyBDRLEBe7jlTYx/fEhPAk3P3DAJsfZwC54m8hAIryosJOL+UuZHB3K3yA==} - - '@octokit/plugin-paginate-graphql@6.0.0': - resolution: {integrity: sha512-crfpnIoFiBtRkvPqOyLOsw12XsveYuY2ieP6uYDosoUegBJpSVxGwut9sxUgFFcll3VTOTqpUf8yGd8x1OmAkQ==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' - - '@octokit/plugin-paginate-rest@13.1.1': - resolution: {integrity: sha512-q9iQGlZlxAVNRN2jDNskJW/Cafy7/XE52wjZ5TTvyhyOD904Cvx//DNyoO3J/MXJ0ve3rPoNWKEg5iZrisQSuw==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' - - '@octokit/plugin-rest-endpoint-methods@16.0.0': - resolution: {integrity: sha512-kJVUQk6/dx/gRNLWUnAWKFs1kVPn5O5CYZyssyEoNYaFedqZxsfYs7DwI3d67hGz4qOwaJ1dpm07hOAD1BXx6g==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' - - '@octokit/plugin-retry@8.0.1': - resolution: {integrity: sha512-KUoYR77BjF5O3zcwDQHRRZsUvJwepobeqiSSdCJ8lWt27FZExzb0GgVxrhhfuyF6z2B2zpO0hN5pteni1sqWiw==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=7' - - '@octokit/plugin-throttling@11.0.1': - resolution: {integrity: sha512-S+EVhy52D/272L7up58dr3FNSMXWuNZolkL4zMJBNIfIxyZuUcczsQAU4b5w6dewJXnKYVgSHSV5wxitMSW1kw==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': ^7.0.0 - - '@octokit/request-error@7.0.0': - resolution: {integrity: sha512-KRA7VTGdVyJlh0cP5Tf94hTiYVVqmt2f3I6mnimmaVz4UG3gQV/k4mDJlJv3X67iX6rmN7gSHCF8ssqeMnmhZg==} - engines: {node: '>= 20'} - - '@octokit/request@10.0.3': - resolution: {integrity: sha512-V6jhKokg35vk098iBqp2FBKunk3kMTXlmq+PtbV9Gl3TfskWlebSofU9uunVKhUN7xl+0+i5vt0TGTG8/p/7HA==} - engines: {node: '>= 20'} - - '@octokit/types@14.1.0': - resolution: {integrity: sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==} - - '@octokit/webhooks-methods@6.0.0': - resolution: {integrity: sha512-MFlzzoDJVw/GcbfzVC1RLR36QqkTLUf79vLVO3D+xn7r0QgxnFoLZgtrzxiQErAjFUOdH6fas2KeQJ1yr/qaXQ==} - engines: {node: '>= 20'} - - '@octokit/webhooks@14.1.1': - resolution: {integrity: sha512-4kN/yPhcZEP+X7iMMuBTk+dD4ZGOpU57F7kHKrFlD2SSY/Sxh01t79oVn4npchLdPIXvLKrQw0uBXhmEaiZAdw==} - engines: {node: '>= 20'} - - '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} - engines: {node: '>=8.0.0'} - - '@peculiar/asn1-android@2.4.0': - resolution: {integrity: sha512-YFueREq97CLslZZBI8dKzis7jMfEHSLxM+nr0Zdx1POiXFLjqqwoY5s0F1UimdBiEw/iKlHey2m56MRDv7Jtyg==} - - '@peculiar/asn1-ecc@2.4.0': - resolution: {integrity: sha512-fJiYUBCJBDkjh347zZe5H81BdJ0+OGIg0X9z06v8xXUoql3MFeENUX0JsjCaVaU9A0L85PefLPGYkIoGpTnXLQ==} - - '@peculiar/asn1-rsa@2.4.0': - resolution: {integrity: sha512-6PP75voaEnOSlWR9sD25iCQyLgFZHXbmxvUfnnDcfL6Zh5h2iHW38+bve4LfH7a60x7fkhZZNmiYqAlAff9Img==} - - '@peculiar/asn1-schema@2.4.0': - resolution: {integrity: sha512-umbembjIWOrPSOzEGG5vxFLkeM8kzIhLkgigtsOrfLKnuzxWxejAcUX+q/SoZCdemlODOcr5WiYa7+dIEzBXZQ==} - - '@peculiar/asn1-x509@2.4.0': - resolution: {integrity: sha512-F7mIZY2Eao2TaoVqigGMLv+NDdpwuBKU1fucHPONfzaBS4JXXCNCmfO0Z3dsy7JzKGqtDcYC1mr9JjaZQZNiuw==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@protobufjs/aspromise@1.1.2': - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - - '@protobufjs/base64@1.1.2': - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - - '@protobufjs/codegen@2.0.4': - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - - '@protobufjs/eventemitter@1.1.0': - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - - '@protobufjs/fetch@1.1.0': - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} - - '@protobufjs/float@1.0.2': - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - - '@protobufjs/path@1.1.2': - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - - '@protobufjs/pool@1.1.0': - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - - '@puppeteer/browsers@2.10.6': - resolution: {integrity: sha512-pHUn6ZRt39bP3698HFQlu2ZHCkS/lPcpv7fVQcGBSzNNygw171UXAKrCUhy+TEMw4lEttOKDgNpb04hwUAJeiQ==} - engines: {node: '>=18'} - hasBin: true - - '@root/acme@3.1.0': - resolution: {integrity: sha512-GAyaW63cpSYd2KvVp5lHLbCWeEhJPKZK9nsJvZJOKsD9Uv88KEttn4FpDZEJ+2q3Jsey0DWpuQ2I4ft0JV9p2w==} - - '@root/asn1@1.0.0': - resolution: {integrity: sha512-0lfZNuOULKJDJmdIkP8V9RnbV3XaK6PAHD3swnFy4tZwtlMDzLKoM/dfNad7ut8Hu3r91wy9uK0WA/9zym5mig==} - - '@root/csr@0.8.1': - resolution: {integrity: sha512-hKl0VuE549TK6SnS2Yn9nRvKbFZXn/oAg+dZJU/tlKl/f/0yRXeuUzf8akg3JjtJq+9E592zDqeXZ7yyrg8fSQ==} - - '@root/encoding@1.0.1': - resolution: {integrity: sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==} - - '@root/keypairs@0.10.3': - resolution: {integrity: sha512-hbmjVbk/G99Z1XlUzJM4VOAaR8jm4vMnfwpZL301FA24ubJ/bOjj6enCrz9gKsQvBO6RY4/R4MgUuWpXeqeZZQ==} - - '@root/pem@1.0.4': - resolution: {integrity: sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==} - - '@root/request@1.9.2': - resolution: {integrity: sha512-wVaL9yVV9oDR9UNbPZa20qgY+4Ch6YN8JUkaE4el/uuS5dmhD8Lusm/ku8qJVNtmQA56XLzEDCRS6/vfpiHK2A==} - - '@root/x509@0.7.2': - resolution: {integrity: sha512-ENq3LGYORK5NiMFHEVeNMt+fTXaC7DTS6sQXoqV+dFdfT0vmiL5cDLjaXQhaklJQq0NiwicZegzJRl1ZOTp3WQ==} - - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - - '@shikijs/core@1.0.0': - resolution: {integrity: sha512-UMKGMZ+8b88N0/n6DWwWth1PHsOaxjW+R2u+hzSiargZWTv+l3s1l8dhuIxUSsEUPlBDKLs2CSMiFZeviKQM1w==} - - '@simplewebauthn/server@13.1.2': - resolution: {integrity: sha512-VwoDfvLXSCaRiD+xCIuyslU0HLxVggeE5BL06+GbsP2l1fGf5op8e0c3ZtKoi+vSg1q4ikjtAghC23ze2Q3H9g==} - engines: {node: '>=20.0.0'} - - '@socket.io/component-emitter@3.1.2': - resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - - '@stylistic/eslint-plugin@2.11.0': - resolution: {integrity: sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=8.40.0' - - '@swc/wasm@1.4.16': - resolution: {integrity: sha512-Gxtpe4L7u29Asje8Y/1Ev6Fsw9AlztkyiZl6eKgXz3XmwOSVxo1FtC42Za7KEZsNyrRILH0D8hEDgcYRHzfdIA==} - - '@tokenizer/inflate@0.2.7': - resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==} - engines: {node: '>=18'} - - '@tokenizer/token@0.3.0': - resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - - '@tootallnate/quickjs-emscripten@0.23.0': - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - - '@tybys/wasm-util@0.10.0': - resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} - - '@types/aws-lambda@8.10.152': - resolution: {integrity: sha512-soT/c2gYBnT5ygwiHPmd9a1bftj462NWVk2tKCc1PYHSIacB2UwbTS2zYG4jzag1mRDuzg/OjtxQjQ2NKRB6Rw==} - - '@types/body-parser@1.19.6': - resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - - '@types/busboy@1.5.4': - resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} - - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/cookie@0.4.1': - resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} - - '@types/cors@2.8.17': - resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} - - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - - '@types/dompurify@3.0.5': - resolution: {integrity: sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/express-serve-static-core@4.19.6': - resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} - - '@types/express-serve-static-core@5.0.7': - resolution: {integrity: sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==} - - '@types/express@4.17.23': - resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} - - '@types/express@5.0.0': - resolution: {integrity: sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==} - - '@types/http-errors@2.0.5': - resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - - '@types/ldapjs@2.2.5': - resolution: {integrity: sha512-Lv/nD6QDCmcT+V1vaTRnEKE8UgOilVv5pHcQuzkU1LcRe4mbHHuUo/KHi0LKrpdHhQY8FJzryF38fcVdeUIrzg==} - - '@types/linkify-it@5.0.0': - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - - '@types/long@4.0.2': - resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} - - '@types/markdown-it@14.1.2': - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} - - '@types/mdurl@2.0.0': - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - - '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - - '@types/node@20.12.7': - resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} - - '@types/node@20.8.3': - resolution: {integrity: sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==} - - '@types/node@22.10.1': - resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} - - '@types/node@22.13.8': - resolution: {integrity: sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==} - - '@types/node@22.7.7': - resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} - - '@types/node@24.1.0': - resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==} - - '@types/notp@2.0.3': - resolution: {integrity: sha512-biFO/VNDdq/vH7PVN+WovqxhbRhvaA2daj1uAvMFKrcMQ12tfoSySud3vV8m9Zls6eM2FC8N9CpKbkLYJS1AAA==} - - '@types/object-path@0.11.4': - resolution: {integrity: sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==} - - '@types/passport-strategy@0.2.38': - resolution: {integrity: sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==} - - '@types/passport@1.0.17': - resolution: {integrity: sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==} - - '@types/qs@6.14.0': - resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - - '@types/qs@6.9.18': - resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==} - - '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - - '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - - '@types/send@0.17.5': - resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} - - '@types/serve-static@1.15.8': - resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} - - '@types/trusted-types@2.0.7': - resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - - '@types/xml-encryption@1.2.4': - resolution: {integrity: sha512-I69K/WW1Dv7j6O3jh13z0X8sLWJRXbu5xnHDl9yHzUNDUBtUoBY058eb5s+x/WG6yZC1h8aKdI2EoyEPjyEh+Q==} - - '@types/xml2js@0.4.14': - resolution: {integrity: sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==} - - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - - '@typescript-eslint/eslint-plugin@8.38.0': - resolution: {integrity: sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.38.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/parser@8.38.0': - resolution: {integrity: sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/project-service@8.38.0': - resolution: {integrity: sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/scope-manager@8.38.0': - resolution: {integrity: sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.38.0': - resolution: {integrity: sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/type-utils@8.38.0': - resolution: {integrity: sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/types@8.38.0': - resolution: {integrity: sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.38.0': - resolution: {integrity: sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/utils@8.38.0': - resolution: {integrity: sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/visitor-keys@8.38.0': - resolution: {integrity: sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typespec/ts-http-runtime@0.3.0': - resolution: {integrity: sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg==} - engines: {node: '>=20.0.0'} - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} - cpu: [arm] - os: [android] - - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} - cpu: [arm64] - os: [android] - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} - cpu: [arm64] - os: [darwin] - - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} - cpu: [x64] - os: [darwin] - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} - cpu: [x64] - os: [freebsd] - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} - cpu: [ppc64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} - cpu: [s390x] - os: [linux] - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} - cpu: [arm64] - os: [win32] - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} - cpu: [ia32] - os: [win32] - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} - cpu: [x64] - os: [win32] - - '@vue-email/cli@0.0.14': - resolution: {integrity: sha512-6AxKox1ydrouE1RHJJX8i0xoxlWprBan7o2kW4Qh7fYfGYLWW7DZklnTu+qtelXqkn/zXLDT2V0Ij20G7upkfw==} - hasBin: true - - '@vue-email/compiler@0.8.14': - resolution: {integrity: sha512-Z9zHYk7vY9S9WYz8xGf53oMDDQ5Di9Gn0/N0r/ifxEXwLgCcS/5EI3zqquiifXSnqWQJBD7pI18jQFwMgEq0Gw==} - peerDependencies: - vue: ^3.3.8 - - '@vue-email/tailwind@0.0.6': - resolution: {integrity: sha512-+t3yC1ym2fwa2KexOvdMDgB1Thpj3dcmMEztjSj6fa2tcuWmj/fTn+5yskzjtrokyqtc4dAqe7Da7uj1/j+dww==} - engines: {node: '>=18.0.0'} - - '@vue/compiler-core@3.5.18': - resolution: {integrity: sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==} - - '@vue/compiler-dom@3.5.18': - resolution: {integrity: sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==} - - '@vue/compiler-sfc@3.5.18': - resolution: {integrity: sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==} - - '@vue/compiler-ssr@3.5.18': - resolution: {integrity: sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==} - - '@vue/devtools-api@6.6.1': - resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} - - '@vue/reactivity@3.5.18': - resolution: {integrity: sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==} - - '@vue/runtime-core@3.5.18': - resolution: {integrity: sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==} - - '@vue/runtime-dom@3.5.18': - resolution: {integrity: sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==} - - '@vue/server-renderer@3.5.18': - resolution: {integrity: sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==} - peerDependencies: - vue: 3.5.18 - - '@vue/shared@3.5.18': - resolution: {integrity: sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==} - - '@whatwg-node/promise-helpers@1.3.2': - resolution: {integrity: sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==} - engines: {node: '>=16.0.0'} - - '@wry/caches@1.0.1': - resolution: {integrity: sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==} - engines: {node: '>=8'} - - '@wry/context@0.7.4': - resolution: {integrity: sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==} - engines: {node: '>=8'} - - '@wry/equality@0.5.7': - resolution: {integrity: sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==} - engines: {node: '>=8'} - - '@wry/trie@0.5.0': - resolution: {integrity: sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==} - engines: {node: '>=8'} - - '@xmldom/is-dom-node@1.0.1': - resolution: {integrity: sha512-CJDxIgE5I0FH+ttq/Fxy6nRpxP70+e2O048EPe85J2use3XKdatVM7dDVvFNjQudd9B49NPoZ+8PG49zj4Er8Q==} - engines: {node: '>= 16'} - - '@xmldom/xmldom@0.8.10': - resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} - engines: {node: '>=10.0.0'} - - abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - - abstract-logging@2.0.1: - resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} - - accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - - acme@3.0.3: - resolution: {integrity: sha512-NMEugs9cWvryNRidu9GeyV3EbqDlb5XFKQjaJ6E99RFpzrHM/iYYLImdrdpnkbS4vFTCrB2nMA7MQB0vAk801w==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} - - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - - akismet-api@6.0.0: - resolution: {integrity: sha512-IqPwdqKOpRXXJg/T2772BB1RoCFfB5kBX1Zeef98T/RkIIFuRqO1kPM4wAjgIdGtvP7YNQ8VYh9kTszpR0637g==} - engines: {node: '>=14.0.0'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - apg-conv-api@1.0.1: - resolution: {integrity: sha512-1h4LB3N/4+FcujMGQIp0OIKdNNlwyXF8e4duy6ACjBUdHSUT4z5PVyFaf9+ego52IpgNAAdQCl6Up9vTM9cvqg==} - - apg-lib@3.2.0: - resolution: {integrity: sha512-igSp4Zoq47Brp9B2mKXXE7tleC+bLWgMTgYSGCb5UIs3w+xz/qwCh2drtp7kyRtTN6GFcAwD3pXtqwtdfg+EHw==} - - append-field@1.0.0: - resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} - - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} - - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - - asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - - asn1.js@5.4.1: - resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} - - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - - asn1js@3.0.6: - resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} - engines: {node: '>=12.0.0'} - - assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - - ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} - - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - - async-retry@1.3.3: - resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} - - async@3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - available-typed-arrays@1.0.6: - resolution: {integrity: sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==} - engines: {node: '>= 0.4'} - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - aws-sdk@2.1692.0: - resolution: {integrity: sha512-x511uiJ/57FIsbgUe5csJ13k3uzu25uWQE+XqfBis/sB0SFoiElJWXRkgEAUh0U6n40eT3ay5Ue4oPkRMu1LYw==} - engines: {node: '>= 10.0.0'} - - axios@1.6.2: - resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==} - - b4a@1.6.7: - resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - - backoff@2.5.0: - resolution: {integrity: sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==} - engines: {node: '>= 0.6'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - bare-events@2.6.0: - resolution: {integrity: sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==} - - bare-fs@4.1.6: - resolution: {integrity: sha512-25RsLF33BqooOEFNdMcEhMpJy8EoR88zSMrnOQOaM3USnOK2VmaJ1uaQEwPA6AQjrv1lXChScosN6CzbwbO9OQ==} - engines: {bare: '>=1.16.0'} - peerDependencies: - bare-buffer: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - - bare-os@3.6.1: - resolution: {integrity: sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==} - engines: {bare: '>=1.14.0'} - - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - - bare-stream@2.6.5: - resolution: {integrity: sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==} - peerDependencies: - bare-buffer: '*' - bare-events: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - bare-events: - optional: true - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - base64id@2.0.0: - resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} - engines: {node: ^4.5.0 || >= 5.9} - - base64url@3.0.1: - resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==} - engines: {node: '>=6.0.0'} - - basic-ftp@5.0.5: - resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} - engines: {node: '>=10.0.0'} - - bcryptjs@2.4.3: - resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} - - bcryptjs@3.0.2: - resolution: {integrity: sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==} - hasBin: true - - before-after-hook@4.0.0: - resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - bintrees@1.0.2: - resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==} - - bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - - bn.js@4.12.0: - resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} - - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} - engines: {node: '>=18'} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - bottleneck@2.19.5: - resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} - - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - - buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@4.9.2: - resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} - - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - call-bind-apply-helpers@1.0.0: - resolution: {integrity: sha512-CCKAP2tkPau7D3GE8+V8R6sQubA9R5foIzGp+85EXCVSCivuxBNAWqcpn72PKYiIcqoViv/kcUDpaEIMBVi1lQ==} - engines: {node: '>= 0.4'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - - call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} - - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - cheerio-select@2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - - cheerio@1.1.2: - resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==} - engines: {node: '>=20.18.1'} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - chromium-bidi@7.2.0: - resolution: {integrity: sha512-gREyhyBstermK+0RbcJLbFhcQctg92AGgDe/h/taMJEOLRdtSswBAO9KmvltFSQWgM2LrwWu5SIuEUbdm3JsyQ==} - peerDependencies: - devtools-protocol: '*' - - chromium-pickle-js@0.2.0: - resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} - - clean-css@5.3.3: - resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} - engines: {node: '>= 10.0'} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clone@2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - - colorette@2.0.19: - resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - command-exists@1.2.9: - resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} - - commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} - - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} - - comment-parser@1.4.1: - resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} - engines: {node: '>= 12.0.0'} - - component-emitter@1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - - compressible@2.0.18: - resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} - engines: {node: '>= 0.6'} - - compression@1.8.1: - resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} - engines: {node: '>= 0.8.0'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - concat-stream@2.0.0: - resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} - engines: {'0': node >= 6.0} - - connect-session-knex@5.0.0: - resolution: {integrity: sha512-LNmgZriKjmZPkPDsB8rspdqdrsQ+aAoSXFDJA3/1OQxt3nlAWzUNghhTsFAiY95Pcp/tTS18n8rRwiBCDBIz5g==} - engines: {node: '>=18'} - - content-disposition@1.0.0: - resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} - engines: {node: '>= 0.6'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - cookie-parser@1.4.7: - resolution: {integrity: sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==} - engines: {node: '>= 0.8.0'} - - cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - - cookie-signature@1.0.7: - resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} - - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - cookiejar@2.1.4: - resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} - - core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - - cron-parser@5.3.0: - resolution: {integrity: sha512-IS4mnFu6n3CFgEmXjr+B2zzGHsjJmHEdN+BViKvYSiEn3KWss9ICRDETDX/VZldiW82B94OyAZm4LIT4vcKK0g==} - engines: {node: '>=18'} - - cross-inspect@1.0.1: - resolution: {integrity: sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==} - engines: {node: '>=16.0.0'} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - cssfilter@0.0.10: - resolution: {integrity: sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==} - - cssstyle@4.6.0: - resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} - engines: {node: '>=18'} - - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - cuint@0.2.2: - resolution: {integrity: sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==} - - custom-error-instance@2.1.2: - resolution: {integrity: sha512-YOrdiS4b/ItbPAtyEIpkhqryoul2Bu8vtX+SN2nmxsqPnqAfh48Nu9p6zdTp9iCgCoSb6Ib8B0y4UUznaVXgtA==} - - data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} - - data-urls@5.0.0: - resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} - engines: {node: '>=18'} - - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - db-errors@0.2.3: - resolution: {integrity: sha512-OOgqgDuCavHXjYSJoV2yGhv6SeG8nk42aoCSoyXLZUH7VwFG27rxbavU1z+VrZbZjphw5UkDQwUlD21MwZpUng==} - - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} - engines: {node: '>= 0.4'} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - dependency-graph@1.0.0: - resolution: {integrity: sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==} - engines: {node: '>=4'} - - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} - engines: {node: '>=8'} - - devtools-protocol@0.0.1464554: - resolution: {integrity: sha512-CAoP3lYfwAGQTaAXYvA6JZR0fjGUb7qec1qf4mToyoH2TZgUFeIqYcjh6f9jNuhHfuZiEdH+PONHYrLhRQX6aw==} - - dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - - diff2html@3.4.52: - resolution: {integrity: sha512-qhMg8/I3sZ4zm/6R/Kh0xd6qG6Vm86w6M+C9W+DuH1V8ACz+1cgEC8/k0ucjv6AGqZWzHm/8G1gh7IlrUqCMhg==} - engines: {node: '>=12'} - - diff@7.0.0: - resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} - engines: {node: '>=0.3.1'} - - diff@8.0.2: - resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} - engines: {node: '>=0.3.1'} - - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - - domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - - dompurify@3.2.6: - resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==} - - domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - - dotize@0.6.0: - resolution: {integrity: sha512-D2obkulxFLS9GOmT0c475tUcrPblWBHF/HtW/dKm5wLZyBV98QlV2PdRYQScOsuEhouUo3gBiQOZ1EBTib6tWg==} - - dset@3.1.4: - resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} - engines: {node: '>=4'} - - dunder-proto@1.0.0: - resolution: {integrity: sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==} - engines: {node: '>= 0.4'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - emoji-regex@10.4.0: - resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - encoding-sniffer@0.2.1: - resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} - - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - - engine.io-parser@5.2.3: - resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} - engines: {node: '>=10.0.0'} - - engine.io@6.6.2: - resolution: {integrity: sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==} - engines: {node: '>=10.2.0'} - - enhanced-resolve@5.18.2: - resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} - engines: {node: '>=10.13.0'} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} - - es-abstract@1.24.0: - resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.0.0: - resolution: {integrity: sha512-yHV74THqMJUyFKkHyN7hyENcEZM3Dj2a2IrdClY+IT4BFQHkIVwlh8s6uZfjsFydMdNHv0F5mWgAA3ajFbsvVQ==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - - esbuild-android-64@0.15.18: - resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - esbuild-android-arm64@0.15.18: - resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - esbuild-darwin-64@0.15.18: - resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - esbuild-darwin-arm64@0.15.18: - resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - esbuild-freebsd-64@0.15.18: - resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - esbuild-freebsd-arm64@0.15.18: - resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - esbuild-linux-32@0.15.18: - resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - esbuild-linux-64@0.15.18: - resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - esbuild-linux-arm64@0.15.18: - resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - esbuild-linux-arm@0.15.18: - resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - esbuild-linux-mips64le@0.15.18: - resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - esbuild-linux-ppc64le@0.15.18: - resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - esbuild-linux-riscv64@0.15.18: - resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - esbuild-linux-s390x@0.15.18: - resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - esbuild-netbsd-64@0.15.18: - resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - esbuild-openbsd-64@0.15.18: - resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - esbuild-sunos-64@0.15.18: - resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - esbuild-windows-32@0.15.18: - resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - esbuild-windows-64@0.15.18: - resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - esbuild-windows-arm64@0.15.18: - resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - esbuild@0.15.18: - resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} - engines: {node: '>=12'} - hasBin: true - - escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - - eslint-compat-utils@0.5.1: - resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} - engines: {node: '>=12'} - peerDependencies: - eslint: '>=6.0.0' - - eslint-import-context@0.1.9: - resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - peerDependencies: - unrs-resolver: ^1.0.0 - peerDependenciesMeta: - unrs-resolver: - optional: true - - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - - eslint-import-resolver-typescript@3.10.1: - resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - eslint-plugin-import-x: '*' - peerDependenciesMeta: - eslint-plugin-import: - optional: true - eslint-plugin-import-x: - optional: true - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-es-x@7.8.0: - resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '>=8' - - eslint-plugin-es@3.0.1: - resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} - engines: {node: '>=8.10.0'} - peerDependencies: - eslint: '>=4.19.1' - - eslint-plugin-import-x@4.16.1: - resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/utils': ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - eslint-import-resolver-node: '*' - peerDependenciesMeta: - '@typescript-eslint/utils': - optional: true - eslint-import-resolver-node: - optional: true - - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-n@17.21.0: - resolution: {integrity: sha512-1+iZ8We4ZlwVMtb/DcHG3y5/bZOdazIpa/4TySo22MLKdwrLcfrX0hbadnCvykSQCCmkAnWmIP8jZVb2AAq29A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=8.23.0' - - eslint-plugin-node@11.1.0: - resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} - engines: {node: '>=8.10.0'} - peerDependencies: - eslint: '>=5.16.0' - - eslint-plugin-promise@7.2.1: - resolution: {integrity: sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - - eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - - eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.32.0: - resolution: {integrity: sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - esm@3.2.25: - resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} - engines: {node: '>=6'} - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - eventemitter2@6.4.9: - resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} - - events@1.1.1: - resolution: {integrity: sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==} - engines: {node: '>=0.4.x'} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - - express-brute@1.0.1: - resolution: {integrity: sha512-ieZmwox3oIZdQCVjvvnwQvrKQumWdb/JjmC9mWplF42AuHCBXr6Yk/I+nLTRQx+9F+2aapOW9kYLwA6xIlwA9g==} - peerDependencies: - express: 4.x - - express-session@1.18.2: - resolution: {integrity: sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A==} - engines: {node: '>= 0.8.0'} - - express@5.1.0: - resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} - engines: {node: '>= 18'} - - extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - - extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - - extsprintf@1.4.1: - resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} - engines: {'0': node >=0.6.0} - - fast-content-type-parse@3.0.0: - resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - - fast-uri@3.0.3: - resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} - - fast-xml-parser@5.2.5: - resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} - hasBin: true - - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - file-type@21.0.0: - resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==} - engines: {node: '>=20'} - - filesize@11.0.2: - resolution: {integrity: sha512-s/iAeeWLk5BschUIpmdrF8RA8lhFZ/xDZgKw1Tan72oGws1/dFGB06nYEiyyssWUfjKNQTNRlrwMVjO9/hvXDw==} - engines: {node: '>= 10.4.0'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - follow-redirects@1.15.3: - resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - form-data@4.0.2: - resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} - engines: {node: '>= 6'} - - formidable@2.1.2: - resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - - fs-capacitor@8.0.0: - resolution: {integrity: sha512-+Lk6iSKajdGw+7XYxUkwIzreJ2G1JFlYOdnKJv5PzwFLVsoJYBpCuS7WPIUSNT1IbQaEWT1nhYU63Ud03DyzLA==} - engines: {node: ^14.17.0 || >=16.0.0} - - fs-extra@11.3.0: - resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} - engines: {node: '>=14.14'} - - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} - - get-intrinsic@1.2.3: - resolution: {integrity: sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==} - engines: {node: '>= 0.4'} - - get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} - - get-intrinsic@1.2.5: - resolution: {integrity: sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==} - engines: {node: '>= 0.4'} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} - - get-tsconfig@4.10.1: - resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} - - get-uri@6.0.5: - resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} - engines: {node: '>= 14'} - - getopts@2.3.0: - resolution: {integrity: sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==} - - getos@3.2.1: - resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.3.12: - resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} - engines: {node: '>=18'} - - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - - gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - graphql-list-fields@2.0.4: - resolution: {integrity: sha512-q3prnhAL/dBsD+vaGr83B8DzkBijg+Yh+lbt7qp2dW1fpuO+q/upzDXvFJstVsSAA8m11MHGkSxxyxXeLou4MA==} - - graphql-rate-limit-directive@2.0.6: - resolution: {integrity: sha512-2EYUwaVEsRfxZFyXEKse+EZ3xxLXHxN7ssIFoBt0GBNagWbIVhP5wG1mv1oEOp9CvDlSdC/hcM5zbhNMwAjYqw==} - peerDependencies: - '@graphql-tools/utils': ^8.0.0 || ^9.0.0 || ^10.0.0 - graphql: ^16.0.0 - rate-limiter-flexible: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - - graphql-tag@2.12.6: - resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} - engines: {node: '>=10'} - peerDependencies: - graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - - graphql-tools@9.0.20: - resolution: {integrity: sha512-n9T4EEVzfJyQ0N3XAH4bMKhrEhyllBkfFq/4bpnEzkmkvYJ2D120Y5YslqYvpq0kohPFU706Q6zTHrHOfbL7MA==} - engines: {node: '>=16.0.0'} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - - graphql-upload@17.0.0: - resolution: {integrity: sha512-AI42S1UR1mdqg+LQ7KqGbrgcf4l9gpPu/R0drM4vSA5C94NfIjYyCeCdpktEledvZoAL8JURLLeB53++WACo1w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=22.0.0} - peerDependencies: - '@types/express': 4.0.29 - 5 - '@types/koa': ^2.11.4 - graphql: ^16.3.0 - peerDependenciesMeta: - '@types/express': - optional: true - '@types/koa': - optional: true - - graphql@16.11.0: - resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - - gray-matter@4.0.3: - resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} - engines: {node: '>=6.0'} - - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.1: - resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - has@1.0.4: - resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} - engines: {node: '>= 0.4.0'} - - hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - hexoid@1.0.0: - resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} - engines: {node: '>=8'} - - highlight.js@11.11.1: - resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} - engines: {node: '>=12.0.0'} - - highlight.js@11.9.0: - resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==} - engines: {node: '>=12.0.0'} - - hogan.js@3.0.2: - resolution: {integrity: sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==} - hasBin: true - - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - - html-encoding-sniffer@4.0.0: - resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} - engines: {node: '>=18'} - - htmlparser2@10.0.0: - resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} - - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - - http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} - - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - ieee754@1.1.13: - resolution: {integrity: sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - - ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} - engines: {node: '>= 4'} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - image-size@2.0.2: - resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} - engines: {node: '>=16.x'} - hasBin: true - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - import-string@0.1.2: - resolution: {integrity: sha512-tOL7q/mHqoibjr5cm+S5yJv51t6YXVyBCBC5/q6zIbkPiKlvlOEUfpSze5CQX5ygqTIXpjyfFsOJoxe6PqiCVQ==} - peerDependencies: - typescript: ^5.0.0 - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - - interpret@2.2.0: - resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} - engines: {node: '>= 0.10'} - - ip-address@9.0.5: - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} - engines: {node: '>= 12'} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} - - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - - is-bun-module@2.0.0: - resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - - is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} - - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} - engines: {node: '>= 0.4'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - isomorphic-dompurify@2.7.0: - resolution: {integrity: sha512-0FTlXP/gEEWW+O/sXaO9yZ4bgegrHnOqzbdCNAMeO2KYIOVMAcqVIo+uTcWYd1+DmI+nV58vUmNW03nauoKn2w==} - engines: {node: '>=18'} - - iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} - - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - - jiti@1.21.0: - resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} - hasBin: true - - jiti@2.3.3: - resolution: {integrity: sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ==} - hasBin: true - - jmespath@0.16.0: - resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==} - engines: {node: '>= 0.6.0'} - - js-base64@3.7.7: - resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} - - js-binary@1.2.0: - resolution: {integrity: sha512-llsM9S4L5GR9BLH+5/z/7oAqKg0lRccUwBDaSyTiB8DZi3TJ97Jx7C90Xy0FdPec93a7VVmh2nMhTTDb1FjFDQ==} - engines: {node: '>=4'} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - - jsdom@24.1.3: - resolution: {integrity: sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==} - engines: {node: '>=18'} - peerDependencies: - canvas: ^2.11.2 - peerDependenciesMeta: - canvas: - optional: true - - jsdom@26.1.0: - resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} - engines: {node: '>=18'} - peerDependencies: - canvas: ^3.0.0 - peerDependenciesMeta: - canvas: - optional: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - - jsonfile@5.0.0: - resolution: {integrity: sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==} - - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - - jsonwebtoken@9.0.2: - resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} - engines: {node: '>=12', npm: '>=6'} - - jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - - jwa@1.4.1: - resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} - - jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} - - katex@0.16.22: - resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} - hasBin: true - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - - klaw@4.1.0: - resolution: {integrity: sha512-1zGZ9MF9H22UnkpVeuaGKOjfA2t6WrfdrJmGjy16ykcjnKQDmHVX+KI477rpbGevz/5FD4MC3xf1oxylBgcaQw==} - engines: {node: '>=14.14.0'} - - knex@3.1.0: - resolution: {integrity: sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==} - engines: {node: '>=16'} - hasBin: true - peerDependencies: - better-sqlite3: '*' - mysql: '*' - mysql2: '*' - pg: '*' - pg-native: '*' - sqlite3: '*' - tedious: '*' - peerDependenciesMeta: - better-sqlite3: - optional: true - mysql: - optional: true - mysql2: - optional: true - pg: - optional: true - pg-native: - optional: true - sqlite3: - optional: true - tedious: - optional: true - - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - - ldap-filter@0.3.3: - resolution: {integrity: sha512-/tFkx5WIn4HuO+6w9lsfxq4FN3O+fDZeO9Mek8dCD8rTUpqzRa766BOBO7BcGkn3X86m5+cBm1/2S/Shzz7gMg==} - engines: {node: '>=0.8'} - - ldapauth-fork@5.0.5: - resolution: {integrity: sha512-LWUk76+V4AOZbny/3HIPQtGPWZyA3SW2tRhsWIBi9imP22WJktKLHV1ofd8Jo/wY7Ve6vAT7FCI5mEn3blZTjw==} - engines: {node: '>=0.8.0'} - - ldapjs@2.3.3: - resolution: {integrity: sha512-75QiiLJV/PQqtpH+HGls44dXweviFwQ6SiIK27EqzKQ5jU/7UFrl2E5nLdQ3IYRBzJ/AVFJI66u0MZ0uofKYwg==} - engines: {node: '>=10.13.0'} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} - - lilconfig@3.1.1: - resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - - lodash.includes@4.3.0: - resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - - lodash.isboolean@3.0.3: - resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} - - lodash.isinteger@4.0.4: - resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} - - lodash.isnumber@3.0.3: - resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} - - lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - - lodash.isstring@4.0.1: - resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - - lodash.repeat@4.1.0: - resolution: {integrity: sha512-eWsgQW89IewS95ZOcr15HHCX6FVDxq3f2PNUIng3fyzsPev9imFQxIYdFZ6crl8L56UR6ZlGDLcEb3RZsCSSqw==} - - lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - loglevel@1.9.2: - resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} - engines: {node: '>= 0.6.0'} - - long-timeout@0.1.1: - resolution: {integrity: sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==} - - long@4.0.0: - resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} - - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@11.1.0: - resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} - engines: {node: 20 || >=22} - - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - - luxon@3.7.1: - resolution: {integrity: sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==} - engines: {node: '>=12'} - - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - - markdown-it-abbr@2.0.0: - resolution: {integrity: sha512-of7C8pXSjXjDojW4neNP+jD7inUYH/DO0Ca+K/4FUEccg0oHAEX/nfscw0jfz66PJbYWOAT9U8mjO21X5p6aAw==} - - markdown-it-attrs@4.3.1: - resolution: {integrity: sha512-/ko6cba+H6gdZ0DOw7BbNMZtfuJTRp9g/IrGIuz8lYc/EfnmWRpaR3CFPnNbVz0LDvF8Gf1hFGPqrQqq7De0rg==} - engines: {node: '>=6'} - peerDependencies: - markdown-it: '>= 9.0.0' - - markdown-it-decorate@1.2.2: - resolution: {integrity: sha512-7BFWJ97KBXgkaPVjKHISQnhSW8RWQ7yRNXpr8pPUV2Rw4GHvGrgb6CelKCM+GSijP0uSLCAVfc/knWIz+2v/Sw==} - - markdown-it-emoji@3.0.0: - resolution: {integrity: sha512-+rUD93bXHubA4arpEZO3q80so0qgoFJEKRkRbjKX8RTdca89v2kfyF+xR3i2sQTwql9tpPZPOQN5B+PunspXRg==} - - markdown-it-expand-tabs@1.0.13: - resolution: {integrity: sha512-ODpk98FWkGIq2vkwm2NOLt4G6TRgy3M9eTa9SFm06pUyOd0zjjYAwkhsjiCDU42pzKuz0ChiwBO0utuOj3LNOA==} - - markdown-it-footnote@4.0.0: - resolution: {integrity: sha512-WYJ7urf+khJYl3DqofQpYfEYkZKbmXmwxQV8c8mO/hGIhgZ1wOe7R4HLFNwqx7TjILbnC98fuyeSsin19JdFcQ==} - - markdown-it-imsize@2.0.1: - resolution: {integrity: sha512-5SH90ademqcR8ifQCBXRCfIR4HGfZZOh5pO0j2TglulfSQH+SBXM4Iw/QlTUbSoUwVZArCYgECoMvktDS2kP3w==} - - markdown-it-mark@4.0.0: - resolution: {integrity: sha512-YLhzaOsU9THO/cal0lUjfMjrqSMPjjyjChYM7oyj4DnyaXEzA8gnW6cVJeyCrCVeyesrY2PlEdUYJSPFYL4Nkg==} - - markdown-it-mdc@0.2.6: - resolution: {integrity: sha512-HxbEZoEmftdm/krWzwI3JcCWoeXTkAufme1gQt8MTN6nY7y2w/I0LI8U9TEERNPjBNtMOLaNaQsM1H+5K15UJQ==} - peerDependencies: - '@types/markdown-it': '*' - markdown-it: ^14.0.0 - - markdown-it-multimd-table@4.2.3: - resolution: {integrity: sha512-KepCr2OMJqm7IT6sOIbuqHGe+NERhgy66XMrc5lo6dHW7oaPzMDtYwR1EGwK16/blb6mCSg4jqityOe0o/H7HA==} - - markdown-it-sub@2.0.0: - resolution: {integrity: sha512-iCBKgwCkfQBRg2vApy9vx1C1Tu6D8XYo8NvevI3OlwzBRmiMtsJ2sXupBgEA7PPxiDwNni3qIUkhZ6j5wofDUA==} - - markdown-it-sup@2.0.0: - resolution: {integrity: sha512-5VgmdKlkBd8sgXuoDoxMpiU+BiEt3I49GItBzzw7Mxq9CxvnhE/k09HFli09zgfFDRixDQDfDxi0mgBCXtaTvA==} - - markdown-it-task-lists@2.1.1: - resolution: {integrity: sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==} - - markdown-it@14.1.0: - resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} - hasBin: true - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mathjax@3.2.2: - resolution: {integrity: sha512-Bt+SSVU8eBG27zChVewOicYs7Xsdt40qm4+UpHyX7k0/O9NliPc+x77k1/FEsPsjKPZGJvtRZM1vO+geW0OhGw==} - - mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime-types@3.0.1: - resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} - engines: {node: '>= 0.6'} - - mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - - minimalistic-assert@1.0.1: - resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - - minimatch@10.0.3: - resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} - engines: {node: 20 || >=22} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass@7.0.4: - resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} - engines: {node: '>=16 || 14 >=14.17'} - - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - - mkdirp@0.3.0: - resolution: {integrity: sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==} - deprecated: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.) - - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - - module-from-string@3.3.0: - resolution: {integrity: sha512-VsjwtQtXZloDF7ZpBXON53U4Zz02K1/njJmfZcK+QDlYKgdL0ETq8/FeuU0G9EHxdG5XiTaITcGaldDAqJpGXA==} - engines: {node: '>=12.20.0'} - - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - multer@2.0.2: - resolution: {integrity: sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==} - engines: {node: '>= 10.16.0'} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nanoid@5.1.5: - resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} - engines: {node: ^18 || >=20} - hasBin: true - - napi-postinstall@0.3.2: - resolution: {integrity: sha512-tWVJxJHmBWLy69PvO96TZMZDrzmw5KeiZBz3RHmiM2XZ9grBJ2WgMAFVVg25nqp3ZjTFUs2Ftw1JhscL3Teliw==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - - negotiator@0.6.4: - resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} - engines: {node: '>= 0.6'} - - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} - - neostandard@0.12.2: - resolution: {integrity: sha512-VZU8EZpSaNadp3rKEwBhVD1Kw8jE3AftQLkCyOaM7bWemL1LwsYRsBnAmXy2LjG9zO8t66qJdqB7ccwwORyrAg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - eslint: ^9.0.0 - - netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} - - node-2fa@2.0.3: - resolution: {integrity: sha512-PQldrOhjuoZyoydMvMSctllPN1ZPZ1/NwkEcgYwY9faVqE/OymxR+3awPpbWZxm6acLKqvmNqQmdqTsqYyflFw==} - - node-cache@5.1.2: - resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==} - engines: {node: '>= 8.0.0'} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-uuid@1.4.1: - resolution: {integrity: sha512-yli1av4CgutKcqitN8ILW9lMxOrsGJFrhy5jlwcY5GLYxC3dsMyvmKJOf2Zy55CK2e99gQfVnht67b6tmAdiDQ==} - deprecated: Use uuid module instead - - nodemailer@7.0.5: - resolution: {integrity: sha512-nsrh2lO3j4GkLLXoeEksAMgAOqxOv6QumNRVQTJwKH4nuiww6iC2y7GyANs9kRAxCexg3+lTWM3PZ91iLlVjfg==} - engines: {node: '>=6.0.0'} - - nodemon@3.1.10: - resolution: {integrity: sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==} - engines: {node: '>=10'} - hasBin: true - - nopt@1.0.10: - resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} - hasBin: true - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - notp@2.0.3: - resolution: {integrity: sha512-oBig/2uqkjQ5AkBuw4QJYwkEWa/q+zHxI5/I5z6IeP2NT0alpJFsP/trrfCC+9xOAgQSZXssNi962kp5KBmypQ==} - engines: {node: '> v0.6.0'} - - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - nwsapi@2.2.21: - resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} - - oauth@0.10.0: - resolution: {integrity: sha512-1orQ9MT1vHFGQxhuy7E/0gECD3fd2fCC+PIX+/jgmU/gI3EpRocXtmtvxCO5x3WZ443FLTLFWNDjl5MPJf9u+Q==} - - oauth@0.9.15: - resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - - object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object-path@0.11.8: - resolution: {integrity: sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==} - engines: {node: '>= 10.12.0'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - - objection@3.1.5: - resolution: {integrity: sha512-Hx/ipAwXSuRBbOMWFKtRsAN0yITafqXtWB4OT4Z9wED7ty1h7bOnBdhLtcNus23GwLJqcMsRWdodL2p5GwlnfQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - knex: '>=1.0.1' - - octokit@5.0.3: - resolution: {integrity: sha512-+bwYsAIRmYv30NTmBysPIlgH23ekVDriB07oRxlPIAH5PI0yTMSxg5i5Xy0OetcnZw+nk/caD4szD7a9YZ3QyQ==} - engines: {node: '>= 20'} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - on-headers@1.1.0: - resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} - engines: {node: '>= 0.8'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - optimism@0.18.1: - resolution: {integrity: sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - pac-proxy-agent@7.2.0: - resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} - engines: {node: '>= 14'} - - pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} - - pako@2.1.0: - resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse5-htmlparser2-tree-adapter@7.1.0: - resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} - - parse5-parser-stream@7.1.2: - resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} - - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - passport-auth0@1.4.4: - resolution: {integrity: sha512-PFkjMfsfXSwgn94QCrZl2hObRHiqrAJffyeUvI8e8HqTG7MfOlyzWO3wSL5dlH+MUGR5+DQr+vtXFFu6Sx8cfg==} - - passport-cas@0.1.1: - resolution: {integrity: sha512-xZnzTW4frJlO88/kS+BCEnzpSXl360K7Q/ANhtyjQ0S+Z6UMTytyXPMxWwcAt2TxUDVi2UQID4fW0goKB0TCEQ==} - - passport-discord@0.1.4: - resolution: {integrity: sha512-VJWPYqSOmh7SaCLw/C+k1ZqCzJnn2frrmQRx1YrcPJ3MQ+Oa31XclbbmqFICSvl8xv3Fqd6YWQ4H4p1MpIN9rA==} - - passport-dropbox-oauth2@1.1.0: - resolution: {integrity: sha512-u79BoonqfrZDmV44s1y2FMK4cml66W/Hy9ExVY8abErMS+08YXAzOkOQGOHdfpGSaelKLwrgDL2cNWRUA+jh+A==} - engines: {node: '>= 0.4.0'} - - passport-facebook@3.0.0: - resolution: {integrity: sha512-K/qNzuFsFISYAyC1Nma4qgY/12V3RSLFdFVsPKXiKZt434wOvthFW1p7zKa1iQihQMRhaWorVE1o3Vi1o+ZgeQ==} - engines: {node: '>= 0.4.0'} - - passport-github2@0.1.12: - resolution: {integrity: sha512-3nPUCc7ttF/3HSP/k9sAXjz3SkGv5Nki84I05kSQPo01Jqq1NzJACgMblCK0fGcv9pKCG/KXU3AJRDGLqHLoIw==} - engines: {node: '>= 0.8.0'} - - passport-gitlab2@5.0.0: - resolution: {integrity: sha512-cXQMgM6JQx9wHVh7JLH30D8fplfwjsDwRz+zS0pqC8JS+4bNmc1J04NGp5g2M4yfwylH9kQRrMN98GxMw7q7cg==} - engines: {node: '>= 6.0.0'} - - passport-google-oauth20@2.0.0: - resolution: {integrity: sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==} - engines: {node: '>= 0.4.0'} - - passport-jwt@4.0.1: - resolution: {integrity: sha512-UCKMDYhNuGOBE9/9Ycuoyh7vP6jpeTp/+sfMJl7nLff/t6dps+iaeE0hhNkKN8/HZHcJ7lCdOyDxHdDoxoSvdQ==} - - passport-ldapauth@3.0.1: - resolution: {integrity: sha512-TRRx3BHi8GC8MfCT9wmghjde/EGeKjll7zqHRRfGRxXbLcaDce2OftbQrFG7/AWaeFhR6zpZHtBQ/IkINdLVjQ==} - engines: {node: '>=0.8.0'} - - passport-local@1.0.0: - resolution: {integrity: sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==} - engines: {node: '>= 0.4.0'} - - passport-microsoft@2.1.0: - resolution: {integrity: sha512-7bOcjEmZCHg5qD55iHaMD/mgBxPtXLbqAwmKox5IsqOSEU50WJk5nQKK4lxKdBHLZ0hf+gzrFgDsTybJP18/JA==} - engines: {node: '>= 0.4.0'} - - passport-oauth1@1.3.0: - resolution: {integrity: sha512-8T/nX4gwKTw0PjxP1xfD0QhrydQNakzeOpZ6M5Uqdgz9/a/Ag62RmJxnZQ4LkbdXGrRehQHIAHNAu11rCP46Sw==} - engines: {node: '>= 0.4.0'} - - passport-oauth2@1.8.0: - resolution: {integrity: sha512-cjsQbOrXIDE4P8nNb3FQRCCmJJ/utnFKEz2NX209f7KOHPoX18gF7gBzBbLLsj2/je4KrgiwLLGjf0lm9rtTBA==} - engines: {node: '>= 0.4.0'} - - passport-oauth@1.0.0: - resolution: {integrity: sha512-4IZNVsZbN1dkBzmEbBqUxDG8oFOIK81jqdksE3HEb/vI3ib3FMjbiZZ6MTtooyYZzmKu0BfovjvT1pdGgIq+4Q==} - engines: {node: '>= 0.4.0'} - - passport-okta-oauth@0.0.1: - resolution: {integrity: sha512-VfeXnJuCMfsUOavugPdj4QGSuwSGwdkb6D4vBqQRN961jcDgLEfMYWLRqxh7KuBn6PdMGa5k0hChsbSWkkPDng==} - - passport-openidconnect@0.1.2: - resolution: {integrity: sha512-JX3rTyW+KFZ/E9OF/IpXJPbyLO9vGzcmXB5FgSP2jfL3LGKJPdV7zUE8rWeKeeI/iueQggOeFa3onrCmhxXZTg==} - engines: {node: '>= 0.6.0'} - - passport-slack-oauth2@1.2.0: - resolution: {integrity: sha512-SeQl8uPoi4ajhzgIvwQM7gW/6yPrKH0hPFjxcP/426SOZ0M9ZNDOfSa32q3NTw7KcwYOTjyWX/2xdJndQE7Rkg==} - - passport-strategy@1.0.0: - resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} - engines: {node: '>= 0.4.0'} - - passport-twitch-strategy@2.2.0: - resolution: {integrity: sha512-PjESpFVnJk6GIX2EOtkuyk01K81ACDG8IiLJu6yOtOyaMti24/afMtqBcqDrsKqz0RHrx206AfWcI6Q4Tvy4OQ==} - - passport@0.7.0: - resolution: {integrity: sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==} - engines: {node: '>= 0.4.0'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.10.2: - resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} - engines: {node: '>=16 || 14 >=14.17'} - - path-to-regexp@8.2.0: - resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} - engines: {node: '>=16'} - - pause@0.0.1: - resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} - - pem-jwk@2.0.0: - resolution: {integrity: sha512-rFxu7rVoHgQ5H9YsP50dDWf0rHjreVA2z0yPiWr5WdH/UHb29hKtF7h6l8vNd1cbYR1t0QL+JKhW55a2ZV4KtA==} - engines: {node: '>=5.10.0'} - hasBin: true - - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - - peowly@1.3.2: - resolution: {integrity: sha512-BYIrwr8JCXY49jUZscgw311w9oGEKo7ux/s+BxrhKTQbiQ0iYNdZNJ5LgagaeercQdFHwnR7Z5IxxFWVQ+BasQ==} - engines: {node: '>=18.6.0'} - - pg-cloudflare@1.2.7: - resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} - - pg-connection-string@2.6.2: - resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} - - pg-connection-string@2.9.1: - resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} - - pg-cursor@2.15.3: - resolution: {integrity: sha512-eHw63TsiGtFEfAd7tOTZ+TLy+i/2ePKS20H84qCQ+aQ60pve05Okon9tKMC+YN3j6XyeFoHnaim7Lt9WVafQsA==} - peerDependencies: - pg: ^8 - - pg-format@1.0.4: - resolution: {integrity: sha512-YyKEF78pEA6wwTAqOUaHIN/rWpfzzIuMh9KdAhc3rSLQ/7zkRFcCgYBAEGatDstLyZw4g0s9SNICmaTGnBVeyw==} - engines: {node: '>=4.0'} - - pg-hstore@2.3.4: - resolution: {integrity: sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA==} - engines: {node: '>= 0.8.x'} - - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-pool@3.10.1: - resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} - peerDependencies: - pg: '>=8.0' - - pg-protocol@1.10.3: - resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} - - pg-pubsub@0.8.1: - resolution: {integrity: sha512-b/EHOwCrag4isghc4XgRipeAjfgyNg1DiL3Dwwh1Ojp91Lriltn5eg2nSWjBe4pzcFzhTM6HiB7LOG9NN1nx5g==} - engines: {node: ^14.18.0 || >=16.0.0} - - pg-query-stream@4.10.3: - resolution: {integrity: sha512-h2utrzpOIzeT9JfaqfvBbVuvCfBjH86jNfVrGGTbyepKAIOyTfDew0lAt8bbJjs9n/I5bGDl7S2sx6h5hPyJxw==} - peerDependencies: - pg: ^8 - - pg-tsquery@8.4.2: - resolution: {integrity: sha512-waJSlBIKE+shDhuDpuQglTH6dG5zakDhnrnxu8XB8V5c7yoDSuy4pOxY6t2dyoxTjaKMcMmlByJN7n9jx9eqMA==} - engines: {node: '>=10'} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - - pg@8.16.3: - resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} - engines: {node: '>= 16.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true - - pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - pkginfo@0.2.3: - resolution: {integrity: sha512-7W7wTrE/NsY8xv/DTGjwNIyNah81EQH0MWcTzrHL6pOpMocOGZc0Mbdz9aXxSrp+U0mSmkU8jrNCDCfUs3sOBg==} - engines: {node: '>= 0.4.0'} - - pony-cause@1.1.1: - resolution: {integrity: sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==} - engines: {node: '>=12.0.0'} - - pony-cause@2.1.10: - resolution: {integrity: sha512-3IKLNXclQgkU++2fSi93sQ6BznFuxSLB11HdvZQ6JW/spahf/P1pAHBQEahr20rs0htZW0UDkM1HmA+nZkXKsw==} - engines: {node: '>=12.0.0'} - - poolifier@5.1.0: - resolution: {integrity: sha512-F3cjdjEY18hzfL3QfppwQO+gkqYu9IRmrJAmAm7+iWAUE+OBn9koXFR0pFwxNXqCda/+4360v5RLJEor5/ELTA==} - engines: {node: '>=20.11.0', pnpm: '>=9.0.0'} - - possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} - - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - - postcss-css-variables@0.19.0: - resolution: {integrity: sha512-Hr0WEYKLK9VCrY15anHXOd4RCvJy/xRvCnWdplGBeLInwEj6Z14hgzTb2W/39dYTCnS8hnHUfU4/F1zxX0IZuQ==} - peerDependencies: - postcss: ^8.2.6 - - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 - - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 - - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - - postcss-nested@6.0.1: - resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - - postcss-selector-parser@6.0.16: - resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} - engines: {node: '>=4'} - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - postcss@8.4.47: - resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} - engines: {node: ^10 || ^12 || >=14} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - - precond@0.2.3: - resolution: {integrity: sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==} - engines: {node: '>= 0.6'} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - - prom-client@15.1.3: - resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==} - engines: {node: ^16 || ^18 || >=20} - - promised-retry@0.5.0: - resolution: {integrity: sha512-jbYvN6UGE+/3E1g0JmgDPchUc+4VI4cBaPjdr2Lso22xfFqut2warEf6IhWuhPJKbJYVOQAyCt2Jx+01ORCItg==} - engines: {node: ^14.17.0 || >=16.0.0} - - prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - proxy-agent@6.5.0: - resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} - engines: {node: '>= 14'} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - psl@1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - - pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} - - punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - - punycode@1.3.2: - resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - puppeteer-core@24.15.0: - resolution: {integrity: sha512-2iy0iBeWbNyhgiCGd/wvGrDSo73emNFjSxYOcyAqYiagkYt5q4cPfVXaVDKBsukgc2fIIfLAalBZlaxldxdDYg==} - engines: {node: '>=18'} - - pvtsutils@1.3.6: - resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - - pvutils@1.1.3: - resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} - engines: {node: '>=6.0.0'} - - qr-image@3.2.0: - resolution: {integrity: sha512-rXKDS5Sx3YipVsqmlMJsJsk6jXylEpiHRC2+nJy66fxA5ExYyGa4PqwteW69SaVmAb2OQ18HbYriT7cGQMbduw==} - - qs@6.11.2: - resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} - engines: {node: '>=0.6'} - - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} - engines: {node: '>=0.6'} - - querystring@0.2.0: - resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} - engines: {node: '>=0.4.x'} - deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. - - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - random-bytes@1.0.0: - resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} - engines: {node: '>= 0.8'} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - rate-limiter-flexible@5.0.4: - resolution: {integrity: sha512-ftYHrIfSqWYDIJZ4yPTrgOduByAp+86gUS9iklv0JoXVM8eQCAjTnydCj1hAT4MmhmkSw86NaFEJ28m/LC1pKA==} - - raw-body@3.0.0: - resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} - engines: {node: '>= 0.8'} - - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - rechoir@0.8.0: - resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} - engines: {node: '>= 10.13.0'} - - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - - regexp-tree@0.1.27: - resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} - hasBin: true - - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} - - regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - - rehackt@0.1.0: - resolution: {integrity: sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==} - peerDependencies: - '@types/react': '*' - react: '*' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - - remove-markdown@0.6.2: - resolution: {integrity: sha512-EijDXJZbzpGbQBd852ViUzcqgpMujthM+SAEHiWCMcZonRbZ+xViWKLJA/vrwbDwYdxrs1aFDjpBhcGrZoJRGA==} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true - - resolve@1.22.6: - resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==} - hasBin: true - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true - - retry@0.13.1: - resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} - engines: {node: '>= 4'} - - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} - - rrweb-cssom@0.7.1: - resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} - - rrweb-cssom@0.8.0: - resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - - safe-regex@2.1.1: - resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - sanitize-filename@1.6.3: - resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} - - sax@0.6.1: - resolution: {integrity: sha512-8ip+qnRh7m8OEyvoM1JoSBzlrepp3ajVR8nqgrfTig+TewfyvTijl0am8/anFqgbcdz62ofEUKE1hHNDCdbeSQ==} - - sax@1.2.1: - resolution: {integrity: sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==} - - saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} - - scim-query-filter-parser@2.0.4: - resolution: {integrity: sha512-RVzPHmmnqz36dhSRbyFCDBhU43p3h+UK5JItUI8CzxGTQrX/cSUvBPh/Qy9dbQdXVK79/0hYTqhdJPfDP0ZAcA==} - engines: {node: '>=8'} - - scule@1.3.0: - resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - - section-matter@1.0.0: - resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} - engines: {node: '>=4'} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - - send@1.2.0: - resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} - engines: {node: '>= 18'} - - serve-favicon@2.5.1: - resolution: {integrity: sha512-JndLBslCLA/ebr7rS3d+/EKkzTsTi1jI2T9l+vHfAaGJ7A7NhtDpSZ0lx81HCNWnnE0yHncG+SSnVf9IMxOwXQ==} - engines: {node: '>= 0.8.0'} - - serve-static@2.2.0: - resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} - engines: {node: '>= 18'} - - set-function-length@1.2.0: - resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==} - engines: {node: '>= 0.4'} - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - sha.js@2.4.12: - resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} - engines: {node: '>= 0.10'} - hasBin: true - - sharp@0.34.3: - resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - shiki@1.0.0: - resolution: {integrity: sha512-rOUGJa3yFGgOrEoiELYxraoBbag3ZWf9bpodlr05Wjm85Scx8OIX+otdSefq9Pk7L47TKEzGodSQb4L38jka6A==} - - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - simple-git@3.28.0: - resolution: {integrity: sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==} - - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - - simple-update-notifier@2.0.0: - resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} - engines: {node: '>=10'} - - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - - socket.io-adapter@2.5.5: - resolution: {integrity: sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==} - - socket.io-parser@4.2.4: - resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} - engines: {node: '>=10.0.0'} - - socket.io@4.8.1: - resolution: {integrity: sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==} - engines: {node: '>=10.2.0'} - - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} - - socks@2.8.6: - resolution: {integrity: sha512-pe4Y2yzru68lXCb38aAqRf5gvN8YdjP1lok5o0J7BOHljkyCGKVz7H3vpVIXKD27rj2giOJ7DwVyk/GWrPHDWA==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - - stable-hash-x@0.2.0: - resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} - engines: {node: '>=12.0.0'} - - stable-hash@0.0.5: - resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} - - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} - - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - streamx@2.22.1: - resolution: {integrity: sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} - - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} - - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-bom-string@1.0.0: - resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} - engines: {node: '>=0.10.0'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - striptags@3.2.0: - resolution: {integrity: sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==} - - strnum@2.1.1: - resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} - - strtok3@10.3.4: - resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} - engines: {node: '>=18'} - - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - superagent@8.1.2: - resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} - engines: {node: '>=6.4.0 <13 || >=14'} - - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - symbol-observable@4.0.0: - resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} - engines: {node: '>=0.10'} - - symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - - tailwindcss@3.4.3: - resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==} - engines: {node: '>=14.0.0'} - hasBin: true - - tapable@2.2.2: - resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} - engines: {node: '>=6'} - - tar-fs@3.1.0: - resolution: {integrity: sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==} - - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} - - tarn@3.0.2: - resolution: {integrity: sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==} - engines: {node: '>=8.0.0'} - - tdigest@0.1.2: - resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==} - - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - thirty-two@1.0.2: - resolution: {integrity: sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==} - engines: {node: '>=0.2.6'} - - tildify@2.0.0: - resolution: {integrity: sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==} - engines: {node: '>=8'} - - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} - engines: {node: '>=12.0.0'} - - tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - - tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} - hasBin: true - - to-buffer@1.2.1: - resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} - engines: {node: '>= 0.4'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - toad-cache@3.7.0: - resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} - engines: {node: '>=12'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - token-types@6.0.4: - resolution: {integrity: sha512-MD9MjpVNhVyH4fyd5rKphjvt/1qj+PtQUz65aFqAZA6XniWAuSFRjLk3e2VALEFlh9OwBpXUN7rfeqSnT/Fmkw==} - engines: {node: '>=14.16'} - - touch@3.1.1: - resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} - hasBin: true - - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} - - tough-cookie@5.1.2: - resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} - engines: {node: '>=16'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - tr46@5.1.1: - resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} - engines: {node: '>=18'} - - truncate-utf8-bytes@1.0.2: - resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} - - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - ts-declaration-location@1.0.7: - resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} - peerDependencies: - typescript: '>=4.0.0' - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - ts-invariant@0.10.3: - resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==} - engines: {node: '>=8'} - - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - turndown@7.2.0: - resolution: {integrity: sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==} - - twemoji-parser@14.0.0: - resolution: {integrity: sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==} - - twemoji@14.0.2: - resolution: {integrity: sha512-BzOoXIe1QVdmsUmZ54xbEH+8AgtOKUiG53zO5vVP2iUu6h5u9lN15NcuS6te4OY96qx0H7JK9vjjl9WQbkTRuA==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} - - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} - - typed-query-selector@2.12.0: - resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==} - - typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - - typescript-eslint@8.38.0: - resolution: {integrity: sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} - engines: {node: '>=14.17'} - hasBin: true - - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - - uid-safe@2.1.5: - resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} - engines: {node: '>= 0.8'} - - uid2@0.0.3: - resolution: {integrity: sha512-5gSP1liv10Gjp8cMEnFd6shzkL/D6W1uhXSFNCxDC+YI8+L8wkCYCbJ7n77Ezb4wE/xzMogecE+DtamEe9PZjg==} - - uid2@0.0.4: - resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==} - - uint8array-extras@1.4.0: - resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} - engines: {node: '>=18'} - - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - - undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - - underscore@1.13.6: - resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} - - underscore@1.6.0: - resolution: {integrity: sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ==} - - underscore@1.8.3: - resolution: {integrity: sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg==} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - - undici-types@7.8.0: - resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} - - undici@7.12.0: - resolution: {integrity: sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==} - engines: {node: '>=20.18.1'} - - universal-github-app-jwt@2.2.2: - resolution: {integrity: sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw==} - - universal-user-agent@7.0.3: - resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} - - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - unorm@1.6.0: - resolution: {integrity: sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==} - engines: {node: '>= 0.4.0'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - - url@0.10.3: - resolution: {integrity: sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==} - - uslug@1.0.4: - resolution: {integrity: sha512-Jrbpp/NS3TvIGNjfJT1sn3/BCeykoxR8GbNYW5lF6fUscLkbXFwj1b7m4DvIkHm8k3Qr6Co68lbTmoZTMGk/ow==} - engines: {node: '>= 0.4.0'} - - utf8-byte-length@1.0.4: - resolution: {integrity: sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} - hasBin: true - - uuid@8.0.0: - resolution: {integrity: sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==} - hasBin: true - - validate.js@0.13.1: - resolution: {integrity: sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g==} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - vasync@2.2.1: - resolution: {integrity: sha512-Hq72JaTpcTFdWiNA4Y22Amej2GH3BFmBaKPPlDZ4/oC8HNn2ISHLkFrJU4Ds8R3jcUi7oo5Y9jcMHKjES+N9wQ==} - engines: {'0': node >=0.6.0} - - verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - - verror@1.10.1: - resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} - engines: {node: '>=0.6.0'} - - vue-email@0.8.11: - resolution: {integrity: sha512-jWxTGULYtZ8kerm2U+cuyUPvq6YfRzy/4P479EaznoUF1Xw5xmQTDCc61WZzqIvf43MKBsDc33cQ1MCybti/OA==} - hasBin: true - peerDependencies: - vue: ^3.4.15 - - vue-i18n@9.13.1: - resolution: {integrity: sha512-mh0GIxx0wPtPlcB1q4k277y0iKgo25xmDPWioVVYanjPufDBpvu5ySTjP5wOrSvlYQ2m1xI+CFhGdauv/61uQg==} - engines: {node: '>= 16'} - peerDependencies: - vue: ^3.0.0 - - vue@3.5.18: - resolution: {integrity: sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - - whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} - - whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} - - whatwg-url@14.2.0: - resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} - engines: {node: '>=18'} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.14: - resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.16: - resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} - engines: {node: '>= 0.4'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - ws@8.17.1: - resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xml-crypto@6.1.2: - resolution: {integrity: sha512-leBOVQdVi8FvPJrMYoum7Ici9qyxfE4kVi+AkpUoYCSXaQF4IlBm1cneTK9oAxR61LpYxTx7lNcsnBIeRpGW2w==} - engines: {node: '>=16'} - - xml-encryption@3.1.0: - resolution: {integrity: sha512-PV7qnYpoAMXbf1kvQkqMScLeQpjCMixddAKq9PtqVrho8HnYbBOWNfG0kA4R7zxQDo7w9kiYAyzS/ullAyO55Q==} - - xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} - - xml2js@0.4.4: - resolution: {integrity: sha512-9ERdxLOo4EazMDHAS/vsuZiTXIMur6ydcRfzGrFVJ4qM78zD3ohUgPJC7NYpGwd5rnS0ufSydMJClh6jyH+V0w==} - - xml2js@0.6.2: - resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} - engines: {node: '>=4.0.0'} - - xmlbuilder@11.0.1: - resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} - engines: {node: '>=4.0'} - - xmlbuilder@15.1.1: - resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} - engines: {node: '>=8.0'} - - xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - - xpath@0.0.32: - resolution: {integrity: sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==} - engines: {node: '>=0.6.0'} - - xpath@0.0.33: - resolution: {integrity: sha512-NNXnzrkDrAzalLhIUc01jO2mOzXGXh1JwPgkihcLLzw98c0WgYDmmjSh1Kl3wzaxSVWMuA+fe0WTWOBDWCBmNA==} - engines: {node: '>=0.6.0'} - - xpath@0.0.34: - resolution: {integrity: sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==} - engines: {node: '>=0.6.0'} - - xss@1.0.15: - resolution: {integrity: sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==} - engines: {node: '>= 0.10.0'} - hasBin: true - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yaml@2.8.0: - resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} - engines: {node: '>= 14.6'} - hasBin: true - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - zen-observable-ts@1.2.5: - resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} - - zen-observable@0.8.15: - resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} - - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - -snapshots: - - '@alloc/quick-lru@5.2.0': {} - - '@apollo/cache-control-types@1.0.3(graphql@16.11.0)': - dependencies: - graphql: 16.11.0 - - '@apollo/client@3.13.8(graphql@16.11.0)': - dependencies: - '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) - '@wry/caches': 1.0.1 - '@wry/equality': 0.5.7 - '@wry/trie': 0.5.0 - graphql: 16.11.0 - graphql-tag: 2.12.6(graphql@16.11.0) - hoist-non-react-statics: 3.3.2 - optimism: 0.18.1 - prop-types: 15.8.1 - rehackt: 0.1.0 - symbol-observable: 4.0.0 - ts-invariant: 0.10.3 - tslib: 2.8.1 - zen-observable-ts: 1.2.5 - transitivePeerDependencies: - - '@types/react' - optional: true - - '@apollo/protobufjs@1.2.7': - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/long': 4.0.2 - long: 4.0.0 - - '@apollo/server-gateway-interface@2.0.0(graphql@16.11.0)': - dependencies: - '@apollo/usage-reporting-protobuf': 4.1.1 - '@apollo/utils.fetcher': 3.1.0 - '@apollo/utils.keyvaluecache': 4.0.0 - '@apollo/utils.logger': 3.0.0 - graphql: 16.11.0 - - '@apollo/server@5.0.0(graphql@16.11.0)': - dependencies: - '@apollo/cache-control-types': 1.0.3(graphql@16.11.0) - '@apollo/server-gateway-interface': 2.0.0(graphql@16.11.0) - '@apollo/usage-reporting-protobuf': 4.1.1 - '@apollo/utils.createhash': 3.0.1 - '@apollo/utils.fetcher': 3.1.0 - '@apollo/utils.isnodelike': 3.0.0 - '@apollo/utils.keyvaluecache': 4.0.0 - '@apollo/utils.logger': 3.0.0 - '@apollo/utils.usagereporting': 2.1.0(graphql@16.11.0) - '@apollo/utils.withrequired': 3.0.0 - '@graphql-tools/schema': 10.0.25(graphql@16.11.0) - async-retry: 1.3.3 - body-parser: 2.2.0 - cors: 2.8.5 - finalhandler: 2.1.0 - graphql: 16.11.0 - loglevel: 1.9.2 - lru-cache: 11.1.0 - negotiator: 1.0.0 - uuid: 11.1.0 - whatwg-mimetype: 4.0.0 - transitivePeerDependencies: - - supports-color - - '@apollo/usage-reporting-protobuf@4.1.1': - dependencies: - '@apollo/protobufjs': 1.2.7 - - '@apollo/utils.createhash@3.0.1': - dependencies: - '@apollo/utils.isnodelike': 3.0.0 - sha.js: 2.4.12 - - '@apollo/utils.dropunuseddefinitions@2.0.1(graphql@16.11.0)': - dependencies: - graphql: 16.11.0 - - '@apollo/utils.fetcher@3.1.0': {} - - '@apollo/utils.isnodelike@3.0.0': {} - - '@apollo/utils.keyvaluecache@4.0.0': - dependencies: - '@apollo/utils.logger': 3.0.0 - lru-cache: 11.1.0 - - '@apollo/utils.logger@3.0.0': {} - - '@apollo/utils.printwithreducedwhitespace@2.0.1(graphql@16.11.0)': - dependencies: - graphql: 16.11.0 - - '@apollo/utils.removealiases@2.0.1(graphql@16.11.0)': - dependencies: - graphql: 16.11.0 - - '@apollo/utils.sortast@2.0.1(graphql@16.11.0)': - dependencies: - graphql: 16.11.0 - lodash.sortby: 4.7.0 - - '@apollo/utils.stripsensitiveliterals@2.0.1(graphql@16.11.0)': - dependencies: - graphql: 16.11.0 - - '@apollo/utils.usagereporting@2.1.0(graphql@16.11.0)': - dependencies: - '@apollo/usage-reporting-protobuf': 4.1.1 - '@apollo/utils.dropunuseddefinitions': 2.0.1(graphql@16.11.0) - '@apollo/utils.printwithreducedwhitespace': 2.0.1(graphql@16.11.0) - '@apollo/utils.removealiases': 2.0.1(graphql@16.11.0) - '@apollo/utils.sortast': 2.0.1(graphql@16.11.0) - '@apollo/utils.stripsensitiveliterals': 2.0.1(graphql@16.11.0) - graphql: 16.11.0 - - '@apollo/utils.withrequired@3.0.0': {} - - '@as-integrations/express5@1.1.2(@apollo/server@5.0.0(graphql@16.11.0))(express@5.1.0)': - dependencies: - '@apollo/server': 5.0.0(graphql@16.11.0) - express: 5.1.0 - - '@asamuzakjp/css-color@3.2.0': - dependencies: - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - lru-cache: 10.4.3 - - '@azure/abort-controller@2.1.2': - dependencies: - tslib: 2.8.1 - - '@azure/core-auth@1.10.0': - dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-util': 1.13.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@azure/core-client@1.10.0': - dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.10.0 - '@azure/core-rest-pipeline': 1.22.0 - '@azure/core-tracing': 1.3.0 - '@azure/core-util': 1.13.0 - '@azure/logger': 1.3.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@azure/core-http-compat@2.3.0': - dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-client': 1.10.0 - '@azure/core-rest-pipeline': 1.22.0 - transitivePeerDependencies: - - supports-color - - '@azure/core-lro@2.7.2': - dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-util': 1.13.0 - '@azure/logger': 1.3.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@azure/core-paging@1.6.2': - dependencies: - tslib: 2.8.1 - - '@azure/core-rest-pipeline@1.22.0': - dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.10.0 - '@azure/core-tracing': 1.3.0 - '@azure/core-util': 1.13.0 - '@azure/logger': 1.3.0 - '@typespec/ts-http-runtime': 0.3.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@azure/core-tracing@1.3.0': - dependencies: - tslib: 2.8.1 - - '@azure/core-util@1.13.0': - dependencies: - '@azure/abort-controller': 2.1.2 - '@typespec/ts-http-runtime': 0.3.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@azure/core-xml@1.5.0': - dependencies: - fast-xml-parser: 5.2.5 - tslib: 2.8.1 - - '@azure/logger@1.3.0': - dependencies: - '@typespec/ts-http-runtime': 0.3.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@azure/storage-blob@12.28.0': - dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.10.0 - '@azure/core-client': 1.10.0 - '@azure/core-http-compat': 2.3.0 - '@azure/core-lro': 2.7.2 - '@azure/core-paging': 1.6.2 - '@azure/core-rest-pipeline': 1.22.0 - '@azure/core-tracing': 1.3.0 - '@azure/core-util': 1.13.0 - '@azure/core-xml': 1.5.0 - '@azure/logger': 1.3.0 - '@azure/storage-common': 12.0.0 - events: 3.3.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@azure/storage-common@12.0.0': - dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.10.0 - '@azure/core-http-compat': 2.3.0 - '@azure/core-rest-pipeline': 1.22.0 - '@azure/core-tracing': 1.3.0 - '@azure/core-util': 1.13.0 - '@azure/logger': 1.3.0 - events: 3.3.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.27.1': {} - - '@babel/parser@7.28.0': - dependencies: - '@babel/types': 7.28.2 - - '@babel/types@7.28.2': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@csstools/color-helpers@5.0.2': {} - - '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-color-parser@3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/color-helpers': 5.0.2 - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': - dependencies: - '@csstools/css-tokenizer': 3.0.4 - - '@csstools/css-tokenizer@3.0.4': {} - - '@emnapi/core@1.4.5': - dependencies: - '@emnapi/wasi-threads': 1.0.4 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.4.5': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.0.4': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/android-arm@0.15.18': - optional: true - - '@esbuild/linux-loong64@0.15.18': - optional: true - - '@eslint-community/eslint-utils@4.4.1(eslint@9.32.0(jiti@2.3.3))': - dependencies: - eslint: 9.32.0(jiti@2.3.3) - eslint-visitor-keys: 3.4.3 - - '@eslint-community/eslint-utils@4.7.0(eslint@9.32.0(jiti@2.3.3))': - dependencies: - eslint: 9.32.0(jiti@2.3.3) - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/config-array@0.21.0': - dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.1(supports-color@5.5.0) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.3.0': {} - - '@eslint/core@0.15.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.1': - dependencies: - ajv: 6.12.6 - debug: 4.4.1(supports-color@5.5.0) - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.32.0': {} - - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.3.4': - dependencies: - '@eslint/core': 0.15.1 - levn: 0.4.1 - - '@exlinc/keycloak-passport@1.0.2': - dependencies: - passport-oauth2: 1.8.0 - - '@graphql-tools/merge@9.1.1(graphql@16.11.0)': - dependencies: - '@graphql-tools/utils': 10.9.1(graphql@16.11.0) - graphql: 16.11.0 - tslib: 2.8.1 - - '@graphql-tools/schema@10.0.25(graphql@16.11.0)': - dependencies: - '@graphql-tools/merge': 9.1.1(graphql@16.11.0) - '@graphql-tools/utils': 10.9.1(graphql@16.11.0) - graphql: 16.11.0 - tslib: 2.8.1 - - '@graphql-tools/utils@10.9.1(graphql@16.11.0)': - dependencies: - '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) - '@whatwg-node/promise-helpers': 1.3.2 - cross-inspect: 1.0.1 - dset: 3.1.4 - graphql: 16.11.0 - tslib: 2.8.1 - - '@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)': - dependencies: - graphql: 16.11.0 - - '@hexagon/base64@1.1.28': {} - - '@hexagon/base64@2.0.4': {} - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 - - '@humanwhocodes/gitignore-to-minimatch@1.0.2': {} - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@img/sharp-darwin-arm64@0.34.3': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.0 - optional: true - - '@img/sharp-darwin-x64@0.34.3': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.0 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.2.0': - optional: true - - '@img/sharp-libvips-darwin-x64@1.2.0': - optional: true - - '@img/sharp-libvips-linux-arm64@1.2.0': - optional: true - - '@img/sharp-libvips-linux-arm@1.2.0': - optional: true - - '@img/sharp-libvips-linux-ppc64@1.2.0': - optional: true - - '@img/sharp-libvips-linux-s390x@1.2.0': - optional: true - - '@img/sharp-libvips-linux-x64@1.2.0': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.2.0': - optional: true - - '@img/sharp-linux-arm64@0.34.3': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.0 - optional: true - - '@img/sharp-linux-arm@0.34.3': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.0 - optional: true - - '@img/sharp-linux-ppc64@0.34.3': - optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.0 - optional: true - - '@img/sharp-linux-s390x@0.34.3': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.0 - optional: true - - '@img/sharp-linux-x64@0.34.3': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.0 - optional: true - - '@img/sharp-linuxmusl-arm64@0.34.3': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 - optional: true - - '@img/sharp-linuxmusl-x64@0.34.3': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.0 - optional: true - - '@img/sharp-wasm32@0.34.3': - dependencies: - '@emnapi/runtime': 1.4.5 - optional: true - - '@img/sharp-win32-arm64@0.34.3': - optional: true - - '@img/sharp-win32-ia32@0.34.3': - optional: true - - '@img/sharp-win32-x64@0.34.3': - optional: true - - '@intlify/core-base@9.13.1': - dependencies: - '@intlify/message-compiler': 9.13.1 - '@intlify/shared': 9.13.1 - - '@intlify/message-compiler@9.13.1': - dependencies: - '@intlify/shared': 9.13.1 - source-map-js: 1.2.1 - - '@intlify/shared@9.13.1': {} - - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@joplin/turndown-plugin-gfm@1.0.62': {} - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.4': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 - - '@kwsites/file-exists@1.1.1': - dependencies: - debug: 4.4.1(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - '@kwsites/promise-deferred@1.1.1': {} - - '@levischuck/tiny-cbor@0.2.11': {} - - '@mixmark-io/domino@2.2.0': {} - - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.4.5 - '@emnapi/runtime': 1.4.5 - '@tybys/wasm-util': 0.10.0 - optional: true - - '@node-saml/node-saml@5.1.0': - dependencies: - '@types/debug': 4.1.12 - '@types/qs': 6.14.0 - '@types/xml-encryption': 1.2.4 - '@types/xml2js': 0.4.14 - '@xmldom/is-dom-node': 1.0.1 - '@xmldom/xmldom': 0.8.10 - debug: 4.4.1(supports-color@5.5.0) - xml-crypto: 6.1.2 - xml-encryption: 3.1.0 - xml2js: 0.6.2 - xmlbuilder: 15.1.1 - xpath: 0.0.34 - transitivePeerDependencies: - - supports-color - - '@node-saml/passport-saml@5.1.0': - dependencies: - '@node-saml/node-saml': 5.1.0 - '@types/express': 4.17.23 - '@types/passport': 1.0.17 - '@types/passport-strategy': 0.2.38 - passport: 0.7.0 - passport-strategy: 1.0.0 - transitivePeerDependencies: - - supports-color - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - - '@nolyfill/is-core-module@1.0.39': {} - - '@octokit/app@16.0.1': - dependencies: - '@octokit/auth-app': 8.0.2 - '@octokit/auth-unauthenticated': 7.0.1 - '@octokit/core': 7.0.3 - '@octokit/oauth-app': 8.0.1 - '@octokit/plugin-paginate-rest': 13.1.1(@octokit/core@7.0.3) - '@octokit/types': 14.1.0 - '@octokit/webhooks': 14.1.1 - - '@octokit/auth-app@8.0.2': - dependencies: - '@octokit/auth-oauth-app': 9.0.1 - '@octokit/auth-oauth-user': 6.0.0 - '@octokit/request': 10.0.3 - '@octokit/request-error': 7.0.0 - '@octokit/types': 14.1.0 - toad-cache: 3.7.0 - universal-github-app-jwt: 2.2.2 - universal-user-agent: 7.0.3 - - '@octokit/auth-oauth-app@9.0.1': - dependencies: - '@octokit/auth-oauth-device': 8.0.1 - '@octokit/auth-oauth-user': 6.0.0 - '@octokit/request': 10.0.3 - '@octokit/types': 14.1.0 - universal-user-agent: 7.0.3 - - '@octokit/auth-oauth-device@8.0.1': - dependencies: - '@octokit/oauth-methods': 6.0.0 - '@octokit/request': 10.0.3 - '@octokit/types': 14.1.0 - universal-user-agent: 7.0.3 - - '@octokit/auth-oauth-user@6.0.0': - dependencies: - '@octokit/auth-oauth-device': 8.0.1 - '@octokit/oauth-methods': 6.0.0 - '@octokit/request': 10.0.3 - '@octokit/types': 14.1.0 - universal-user-agent: 7.0.3 - - '@octokit/auth-token@6.0.0': {} - - '@octokit/auth-unauthenticated@7.0.1': - dependencies: - '@octokit/request-error': 7.0.0 - '@octokit/types': 14.1.0 - - '@octokit/core@7.0.3': - dependencies: - '@octokit/auth-token': 6.0.0 - '@octokit/graphql': 9.0.1 - '@octokit/request': 10.0.3 - '@octokit/request-error': 7.0.0 - '@octokit/types': 14.1.0 - before-after-hook: 4.0.0 - universal-user-agent: 7.0.3 - - '@octokit/endpoint@11.0.0': - dependencies: - '@octokit/types': 14.1.0 - universal-user-agent: 7.0.3 - - '@octokit/graphql@9.0.1': - dependencies: - '@octokit/request': 10.0.3 - '@octokit/types': 14.1.0 - universal-user-agent: 7.0.3 - - '@octokit/oauth-app@8.0.1': - dependencies: - '@octokit/auth-oauth-app': 9.0.1 - '@octokit/auth-oauth-user': 6.0.0 - '@octokit/auth-unauthenticated': 7.0.1 - '@octokit/core': 7.0.3 - '@octokit/oauth-authorization-url': 8.0.0 - '@octokit/oauth-methods': 6.0.0 - '@types/aws-lambda': 8.10.152 - universal-user-agent: 7.0.3 - - '@octokit/oauth-authorization-url@8.0.0': {} - - '@octokit/oauth-methods@6.0.0': - dependencies: - '@octokit/oauth-authorization-url': 8.0.0 - '@octokit/request': 10.0.3 - '@octokit/request-error': 7.0.0 - '@octokit/types': 14.1.0 - - '@octokit/openapi-types@25.1.0': {} - - '@octokit/openapi-webhooks-types@12.0.3': {} - - '@octokit/plugin-paginate-graphql@6.0.0(@octokit/core@7.0.3)': - dependencies: - '@octokit/core': 7.0.3 - - '@octokit/plugin-paginate-rest@13.1.1(@octokit/core@7.0.3)': - dependencies: - '@octokit/core': 7.0.3 - '@octokit/types': 14.1.0 - - '@octokit/plugin-rest-endpoint-methods@16.0.0(@octokit/core@7.0.3)': - dependencies: - '@octokit/core': 7.0.3 - '@octokit/types': 14.1.0 - - '@octokit/plugin-retry@8.0.1(@octokit/core@7.0.3)': - dependencies: - '@octokit/core': 7.0.3 - '@octokit/request-error': 7.0.0 - '@octokit/types': 14.1.0 - bottleneck: 2.19.5 - - '@octokit/plugin-throttling@11.0.1(@octokit/core@7.0.3)': - dependencies: - '@octokit/core': 7.0.3 - '@octokit/types': 14.1.0 - bottleneck: 2.19.5 - - '@octokit/request-error@7.0.0': - dependencies: - '@octokit/types': 14.1.0 - - '@octokit/request@10.0.3': - dependencies: - '@octokit/endpoint': 11.0.0 - '@octokit/request-error': 7.0.0 - '@octokit/types': 14.1.0 - fast-content-type-parse: 3.0.0 - universal-user-agent: 7.0.3 - - '@octokit/types@14.1.0': - dependencies: - '@octokit/openapi-types': 25.1.0 - - '@octokit/webhooks-methods@6.0.0': {} - - '@octokit/webhooks@14.1.1': - dependencies: - '@octokit/openapi-webhooks-types': 12.0.3 - '@octokit/request-error': 7.0.0 - '@octokit/webhooks-methods': 6.0.0 - - '@opentelemetry/api@1.9.0': {} - - '@peculiar/asn1-android@2.4.0': - dependencies: - '@peculiar/asn1-schema': 2.4.0 - asn1js: 3.0.6 - tslib: 2.8.1 - - '@peculiar/asn1-ecc@2.4.0': - dependencies: - '@peculiar/asn1-schema': 2.4.0 - '@peculiar/asn1-x509': 2.4.0 - asn1js: 3.0.6 - tslib: 2.8.1 - - '@peculiar/asn1-rsa@2.4.0': - dependencies: - '@peculiar/asn1-schema': 2.4.0 - '@peculiar/asn1-x509': 2.4.0 - asn1js: 3.0.6 - tslib: 2.8.1 - - '@peculiar/asn1-schema@2.4.0': - dependencies: - asn1js: 3.0.6 - pvtsutils: 1.3.6 - tslib: 2.8.1 - - '@peculiar/asn1-x509@2.4.0': - dependencies: - '@peculiar/asn1-schema': 2.4.0 - asn1js: 3.0.6 - pvtsutils: 1.3.6 - tslib: 2.8.1 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@protobufjs/aspromise@1.1.2': {} - - '@protobufjs/base64@1.1.2': {} - - '@protobufjs/codegen@2.0.4': {} - - '@protobufjs/eventemitter@1.1.0': {} - - '@protobufjs/fetch@1.1.0': - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - - '@protobufjs/float@1.0.2': {} - - '@protobufjs/inquire@1.1.0': {} - - '@protobufjs/path@1.1.2': {} - - '@protobufjs/pool@1.1.0': {} - - '@protobufjs/utf8@1.1.0': {} - - '@puppeteer/browsers@2.10.6': - dependencies: - debug: 4.4.1(supports-color@5.5.0) - extract-zip: 2.0.1 - progress: 2.0.3 - proxy-agent: 6.5.0 - semver: 7.7.2 - tar-fs: 3.1.0 - yargs: 17.7.2 - transitivePeerDependencies: - - bare-buffer - - supports-color - - '@root/acme@3.1.0': - dependencies: - '@root/csr': 0.8.1 - '@root/encoding': 1.0.1 - '@root/keypairs': 0.10.3 - '@root/pem': 1.0.4 - '@root/request': 1.9.2 - '@root/x509': 0.7.2 - - '@root/asn1@1.0.0': - dependencies: - '@root/encoding': 1.0.1 - - '@root/csr@0.8.1': - dependencies: - '@root/asn1': 1.0.0 - '@root/pem': 1.0.4 - '@root/x509': 0.7.2 - - '@root/encoding@1.0.1': {} - - '@root/keypairs@0.10.3': - dependencies: - '@root/encoding': 1.0.1 - '@root/pem': 1.0.4 - '@root/x509': 0.7.2 - - '@root/pem@1.0.4': {} - - '@root/request@1.9.2': {} - - '@root/x509@0.7.2': - dependencies: - '@root/asn1': 1.0.0 - '@root/encoding': 1.0.1 - - '@rtsao/scc@1.1.0': {} - - '@shikijs/core@1.0.0': {} - - '@simplewebauthn/server@13.1.2': - dependencies: - '@hexagon/base64': 1.1.28 - '@levischuck/tiny-cbor': 0.2.11 - '@peculiar/asn1-android': 2.4.0 - '@peculiar/asn1-ecc': 2.4.0 - '@peculiar/asn1-rsa': 2.4.0 - '@peculiar/asn1-schema': 2.4.0 - '@peculiar/asn1-x509': 2.4.0 - - '@socket.io/component-emitter@3.1.2': {} - - '@stylistic/eslint-plugin@2.11.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3)': - dependencies: - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - eslint: 9.32.0(jiti@2.3.3) - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - estraverse: 5.3.0 - picomatch: 4.0.3 - transitivePeerDependencies: - - supports-color - - typescript - - '@swc/wasm@1.4.16': {} - - '@tokenizer/inflate@0.2.7': - dependencies: - debug: 4.4.1(supports-color@5.5.0) - fflate: 0.8.2 - token-types: 6.0.4 - transitivePeerDependencies: - - supports-color - - '@tokenizer/token@0.3.0': {} - - '@tootallnate/quickjs-emscripten@0.23.0': {} - - '@tybys/wasm-util@0.10.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@types/aws-lambda@8.10.152': {} - - '@types/body-parser@1.19.6': - dependencies: - '@types/connect': 3.4.38 - '@types/node': 24.1.0 - - '@types/busboy@1.5.4': - dependencies: - '@types/node': 22.7.7 - - '@types/connect@3.4.38': - dependencies: - '@types/node': 20.12.7 - - '@types/cookie@0.4.1': {} - - '@types/cors@2.8.17': - dependencies: - '@types/node': 22.10.1 - - '@types/debug@4.1.12': - dependencies: - '@types/ms': 2.1.0 - - '@types/dompurify@3.0.5': - dependencies: - '@types/trusted-types': 2.0.7 - - '@types/estree@1.0.8': {} - - '@types/express-serve-static-core@4.19.6': - dependencies: - '@types/node': 22.13.8 - '@types/qs': 6.9.18 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - - '@types/express-serve-static-core@5.0.7': - dependencies: - '@types/node': 24.1.0 - '@types/qs': 6.14.0 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.5 - optional: true - - '@types/express@4.17.23': - dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 4.19.6 - '@types/qs': 6.14.0 - '@types/serve-static': 1.15.8 - - '@types/express@5.0.0': - dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.0.7 - '@types/qs': 6.14.0 - '@types/serve-static': 1.15.8 - optional: true - - '@types/http-errors@2.0.5': {} - - '@types/json-schema@7.0.15': {} - - '@types/json5@0.0.29': {} - - '@types/ldapjs@2.2.5': - dependencies: - '@types/node': 20.8.3 - - '@types/linkify-it@5.0.0': {} - - '@types/long@4.0.2': {} - - '@types/markdown-it@14.1.2': - dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 - - '@types/mdurl@2.0.0': {} - - '@types/mime@1.3.5': {} - - '@types/ms@2.1.0': {} - - '@types/node@20.12.7': - dependencies: - undici-types: 5.26.5 - - '@types/node@20.8.3': {} - - '@types/node@22.10.1': - dependencies: - undici-types: 6.20.0 - - '@types/node@22.13.8': - dependencies: - undici-types: 6.20.0 - - '@types/node@22.7.7': - dependencies: - undici-types: 6.19.8 - - '@types/node@24.1.0': - dependencies: - undici-types: 7.8.0 - - '@types/notp@2.0.3': - dependencies: - '@types/node': 20.8.3 - - '@types/object-path@0.11.4': {} - - '@types/passport-strategy@0.2.38': - dependencies: - '@types/express': 4.17.23 - '@types/passport': 1.0.17 - - '@types/passport@1.0.17': - dependencies: - '@types/express': 4.17.23 - - '@types/qs@6.14.0': {} - - '@types/qs@6.9.18': {} - - '@types/range-parser@1.2.7': {} - - '@types/send@0.17.4': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 20.12.7 - - '@types/send@0.17.5': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 24.1.0 - - '@types/serve-static@1.15.8': - dependencies: - '@types/http-errors': 2.0.5 - '@types/node': 24.1.0 - '@types/send': 0.17.5 - - '@types/trusted-types@2.0.7': {} - - '@types/xml-encryption@1.2.4': - dependencies: - '@types/node': 24.1.0 - - '@types/xml2js@0.4.14': - dependencies: - '@types/node': 24.1.0 - - '@types/yauzl@2.10.3': - dependencies: - '@types/node': 24.1.0 - optional: true - - '@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/type-utils': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.38.0 - eslint: 9.32.0(jiti@2.3.3) - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.6.3) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.1(supports-color@5.5.0) - eslint: 9.32.0(jiti@2.3.3) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.38.0(typescript@5.6.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.6.3) - '@typescript-eslint/types': 8.38.0 - debug: 4.4.1(supports-color@5.5.0) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.38.0': - dependencies: - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/visitor-keys': 8.38.0 - - '@typescript-eslint/tsconfig-utils@8.38.0(typescript@5.6.3)': - dependencies: - typescript: 5.6.3 - - '@typescript-eslint/type-utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3)': - dependencies: - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - debug: 4.4.1(supports-color@5.5.0) - eslint: 9.32.0(jiti@2.3.3) - ts-api-utils: 2.1.0(typescript@5.6.3) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.38.0': {} - - '@typescript-eslint/typescript-estree@8.38.0(typescript@5.6.3)': - dependencies: - '@typescript-eslint/project-service': 8.38.0(typescript@5.6.3) - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.6.3) - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.1(supports-color@5.5.0) - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.6.3) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0(jiti@2.3.3)) - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.6.3) - eslint: 9.32.0(jiti@2.3.3) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.38.0': - dependencies: - '@typescript-eslint/types': 8.38.0 - eslint-visitor-keys: 4.2.1 - - '@typespec/ts-http-runtime@0.3.0': - dependencies: - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - optional: true - - '@unrs/resolver-binding-android-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - optional: true - - '@vue-email/cli@0.0.14(typescript@5.6.3)(vue@3.5.18(typescript@5.6.3))': - dependencies: - '@vue-email/compiler': 0.8.14(typescript@5.6.3)(vue@3.5.18(typescript@5.6.3)) - transitivePeerDependencies: - - typescript - - vue - - '@vue-email/compiler@0.8.14(typescript@5.6.3)(vue@3.5.18(typescript@5.6.3))': - dependencies: - import-string: 0.1.2(typescript@5.6.3) - kolorist: 1.8.0 - scule: 1.3.0 - vue: 3.5.18(typescript@5.6.3) - vue-email: 0.8.11(typescript@5.6.3)(vue@3.5.18(typescript@5.6.3)) - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - ts-node - - typescript - - utf-8-validate - - '@vue-email/tailwind@0.0.6': - dependencies: - postcss: 8.4.47 - postcss-css-variables: 0.19.0(postcss@8.4.47) - tailwindcss: 3.4.3 - transitivePeerDependencies: - - ts-node - - '@vue/compiler-core@3.5.18': - dependencies: - '@babel/parser': 7.28.0 - '@vue/shared': 3.5.18 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.18': - dependencies: - '@vue/compiler-core': 3.5.18 - '@vue/shared': 3.5.18 - - '@vue/compiler-sfc@3.5.18': - dependencies: - '@babel/parser': 7.28.0 - '@vue/compiler-core': 3.5.18 - '@vue/compiler-dom': 3.5.18 - '@vue/compiler-ssr': 3.5.18 - '@vue/shared': 3.5.18 - estree-walker: 2.0.2 - magic-string: 0.30.17 - postcss: 8.5.6 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.18': - dependencies: - '@vue/compiler-dom': 3.5.18 - '@vue/shared': 3.5.18 - - '@vue/devtools-api@6.6.1': {} - - '@vue/reactivity@3.5.18': - dependencies: - '@vue/shared': 3.5.18 - - '@vue/runtime-core@3.5.18': - dependencies: - '@vue/reactivity': 3.5.18 - '@vue/shared': 3.5.18 - - '@vue/runtime-dom@3.5.18': - dependencies: - '@vue/reactivity': 3.5.18 - '@vue/runtime-core': 3.5.18 - '@vue/shared': 3.5.18 - csstype: 3.1.3 - - '@vue/server-renderer@3.5.18(vue@3.5.18(typescript@5.6.3))': - dependencies: - '@vue/compiler-ssr': 3.5.18 - '@vue/shared': 3.5.18 - vue: 3.5.18(typescript@5.6.3) - - '@vue/shared@3.5.18': {} - - '@whatwg-node/promise-helpers@1.3.2': - dependencies: - tslib: 2.8.1 - - '@wry/caches@1.0.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@wry/context@0.7.4': - dependencies: - tslib: 2.8.1 - optional: true - - '@wry/equality@0.5.7': - dependencies: - tslib: 2.8.1 - optional: true - - '@wry/trie@0.5.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@xmldom/is-dom-node@1.0.1': {} - - '@xmldom/xmldom@0.8.10': {} - - abbrev@1.1.1: {} - - abstract-logging@2.0.1: {} - - accepts@1.3.8: - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - accepts@2.0.0: - dependencies: - mime-types: 3.0.1 - negotiator: 1.0.0 - - acme@3.0.3: - dependencies: - '@root/acme': 3.1.0 - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - agent-base@7.1.4: {} - - ajv-formats@2.1.1(ajv@8.17.1): - optionalDependencies: - ajv: 8.17.1 - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ajv@8.17.1: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.0.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - akismet-api@6.0.0: - dependencies: - bluebird: 3.7.2 - superagent: 8.1.2 - transitivePeerDependencies: - - supports-color - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - any-promise@1.3.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - apg-conv-api@1.0.1: {} - - apg-lib@3.2.0: - dependencies: - apg-conv-api: 1.0.1 - - append-field@1.0.0: {} - - arg@5.0.2: {} - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - - array-includes@3.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - - array.prototype.findlast@1.2.5: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.tosorted@1.1.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-shim-unscopables: 1.1.0 - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - - asap@2.0.6: {} - - asn1.js@5.4.1: - dependencies: - bn.js: 4.12.0 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - safer-buffer: 2.1.2 - - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - - asn1js@3.0.6: - dependencies: - pvtsutils: 1.3.6 - pvutils: 1.1.3 - tslib: 2.8.1 - - assert-plus@1.0.0: {} - - ast-types@0.13.4: - dependencies: - tslib: 2.8.1 - - async-function@1.0.0: {} - - async-retry@1.3.3: - dependencies: - retry: 0.13.1 - - async@3.2.4: {} - - asynckit@0.4.0: {} - - available-typed-arrays@1.0.6: {} - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.0.0 - - aws-sdk@2.1692.0: - dependencies: - buffer: 4.9.2 - events: 1.1.1 - ieee754: 1.1.13 - jmespath: 0.16.0 - querystring: 0.2.0 - sax: 1.2.1 - url: 0.10.3 - util: 0.12.5 - uuid: 8.0.0 - xml2js: 0.6.2 - - axios@1.6.2: - dependencies: - follow-redirects: 1.15.3 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - b4a@1.6.7: {} - - backoff@2.5.0: - dependencies: - precond: 0.2.3 - - balanced-match@1.0.2: {} - - bare-events@2.6.0: - optional: true - - bare-fs@4.1.6: - dependencies: - bare-events: 2.6.0 - bare-path: 3.0.0 - bare-stream: 2.6.5(bare-events@2.6.0) - optional: true - - bare-os@3.6.1: - optional: true - - bare-path@3.0.0: - dependencies: - bare-os: 3.6.1 - optional: true - - bare-stream@2.6.5(bare-events@2.6.0): - dependencies: - streamx: 2.22.1 - optionalDependencies: - bare-events: 2.6.0 - optional: true - - base64-js@1.5.1: {} - - base64id@2.0.0: {} - - base64url@3.0.1: {} - - basic-ftp@5.0.5: {} - - bcryptjs@2.4.3: {} - - bcryptjs@3.0.2: {} - - before-after-hook@4.0.0: {} - - binary-extensions@2.3.0: {} - - bintrees@1.0.2: {} - - bluebird@3.7.2: {} - - bn.js@4.12.0: {} - - body-parser@2.2.0: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 4.4.1(supports-color@5.5.0) - http-errors: 2.0.0 - iconv-lite: 0.6.3 - on-finished: 2.4.1 - qs: 6.14.0 - raw-body: 3.0.0 - type-is: 2.0.1 - transitivePeerDependencies: - - supports-color - - boolbase@1.0.0: {} - - bottleneck@2.19.5: {} - - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - buffer-crc32@0.2.13: {} - - buffer-equal-constant-time@1.0.1: {} - - buffer-from@1.1.2: {} - - buffer@4.9.2: - dependencies: - base64-js: 1.5.1 - ieee754: 1.1.13 - isarray: 1.0.0 - - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - - bytes@3.1.2: {} - - call-bind-apply-helpers@1.0.0: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.2: - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 - - call-bind@1.0.5: - dependencies: - function-bind: 1.1.2 - get-intrinsic: 1.2.3 - set-function-length: 1.2.0 - - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.0 - es-define-property: 1.0.1 - get-intrinsic: 1.2.5 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - camelcase-css@2.0.1: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@5.4.1: {} - - cheerio-select@2.1.0: - dependencies: - boolbase: 1.0.0 - css-select: 5.2.2 - css-what: 6.2.2 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - - cheerio@1.1.2: - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.2.2 - encoding-sniffer: 0.2.1 - htmlparser2: 10.0.0 - parse5: 7.3.0 - parse5-htmlparser2-tree-adapter: 7.1.0 - parse5-parser-stream: 7.1.2 - undici: 7.12.0 - whatwg-mimetype: 4.0.0 - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - chromium-bidi@7.2.0(devtools-protocol@0.0.1464554): - dependencies: - devtools-protocol: 0.0.1464554 - mitt: 3.0.1 - zod: 3.25.76 - - chromium-pickle-js@0.2.0: {} - - clean-css@5.3.3: - dependencies: - source-map: 0.6.1 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone@2.1.2: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - - colorette@2.0.19: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - command-exists@1.2.9: {} - - commander@10.0.1: {} - - commander@2.20.3: {} - - commander@4.1.1: {} - - commander@8.3.0: {} - - comment-parser@1.4.1: {} - - component-emitter@1.3.0: {} - - compressible@2.0.18: - dependencies: - mime-db: 1.54.0 - - compression@1.8.1: - dependencies: - bytes: 3.1.2 - compressible: 2.0.18 - debug: 2.6.9 - negotiator: 0.6.4 - on-headers: 1.1.0 - safe-buffer: 5.2.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - concat-map@0.0.1: {} - - concat-stream@2.0.0: - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 3.6.2 - typedarray: 0.0.6 - - connect-session-knex@5.0.0(pg@8.16.3): - dependencies: - knex: 3.1.0(pg@8.16.3) - transitivePeerDependencies: - - better-sqlite3 - - mysql - - mysql2 - - pg - - pg-native - - sqlite3 - - supports-color - - tedious - - content-disposition@1.0.0: - dependencies: - safe-buffer: 5.2.1 - - content-type@1.0.5: {} - - cookie-parser@1.4.7: - dependencies: - cookie: 0.7.2 - cookie-signature: 1.0.6 - - cookie-signature@1.0.6: {} - - cookie-signature@1.0.7: {} - - cookie-signature@1.2.2: {} - - cookie@0.7.2: {} - - cookiejar@2.1.4: {} - - core-util-is@1.0.2: {} - - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - cron-parser@5.3.0: - dependencies: - luxon: 3.7.1 - - cross-inspect@1.0.1: - dependencies: - tslib: 2.8.1 - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - css-select@5.2.2: - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 5.0.3 - domutils: 3.2.2 - nth-check: 2.1.1 - - css-what@6.2.2: {} - - cssesc@3.0.0: {} - - cssfilter@0.0.10: {} - - cssstyle@4.6.0: - dependencies: - '@asamuzakjp/css-color': 3.2.0 - rrweb-cssom: 0.8.0 - - csstype@3.1.3: {} - - cuint@0.2.2: {} - - custom-error-instance@2.1.2: {} - - data-uri-to-buffer@6.0.2: {} - - data-urls@5.0.0: - dependencies: - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - db-errors@0.2.3: {} - - debug@2.6.9: - dependencies: - ms: 2.0.0 - - debug@3.2.7: - dependencies: - ms: 2.1.3 - - debug@4.3.4: - dependencies: - ms: 2.1.2 - - debug@4.3.7: - dependencies: - ms: 2.1.3 - - debug@4.4.1(supports-color@5.5.0): - dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 5.5.0 - - decimal.js@10.6.0: {} - - deep-is@0.1.4: {} - - define-data-property@1.1.1: - dependencies: - get-intrinsic: 1.2.3 - gopd: 1.0.1 - has-property-descriptors: 1.0.1 - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - gopd: 1.0.1 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - degenerator@5.0.1: - dependencies: - ast-types: 0.13.4 - escodegen: 2.1.0 - esprima: 4.0.1 - - delayed-stream@1.0.0: {} - - depd@2.0.0: {} - - dependency-graph@1.0.0: {} - - detect-libc@2.0.4: {} - - devtools-protocol@0.0.1464554: {} - - dezalgo@1.0.4: - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - - didyoumean@1.2.2: {} - - diff2html@3.4.52: - dependencies: - diff: 7.0.0 - hogan.js: 3.0.2 - optionalDependencies: - highlight.js: 11.9.0 - - diff@7.0.0: {} - - diff@8.0.2: {} - - dlv@1.1.3: {} - - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - - domelementtype@2.3.0: {} - - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 - - dompurify@3.2.6: - optionalDependencies: - '@types/trusted-types': 2.0.7 - - domutils@3.2.2: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - - dotize@0.6.0: {} - - dset@3.1.4: {} - - dunder-proto@1.0.0: - dependencies: - call-bind-apply-helpers: 1.0.0 - es-errors: 1.3.0 - gopd: 1.2.0 - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - eastasianwidth@0.2.0: {} - - ecdsa-sig-formatter@1.0.11: - dependencies: - safe-buffer: 5.2.1 - - ee-first@1.1.1: {} - - emoji-regex@10.4.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - encodeurl@2.0.0: {} - - encoding-sniffer@0.2.1: - dependencies: - iconv-lite: 0.6.3 - whatwg-encoding: 3.1.1 - - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - - engine.io-parser@5.2.3: {} - - engine.io@6.6.2: - dependencies: - '@types/cookie': 0.4.1 - '@types/cors': 2.8.17 - '@types/node': 22.10.1 - accepts: 1.3.8 - base64id: 2.0.0 - cookie: 0.7.2 - cors: 2.8.5 - debug: 4.3.7 - engine.io-parser: 5.2.3 - ws: 8.17.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - enhanced-resolve@5.18.2: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.2 - - entities@4.5.0: {} - - entities@6.0.1: {} - - es-abstract@1.24.0: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 - - es-define-property@1.0.0: - dependencies: - get-intrinsic: 1.2.4 - - es-define-property@1.0.1: {} - - es-errors@1.0.0: {} - - es-errors@1.3.0: {} - - es-iterator-helpers@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-set-tostringtag: 2.1.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - - esbuild-android-64@0.15.18: - optional: true - - esbuild-android-arm64@0.15.18: - optional: true - - esbuild-darwin-64@0.15.18: - optional: true - - esbuild-darwin-arm64@0.15.18: - optional: true - - esbuild-freebsd-64@0.15.18: - optional: true - - esbuild-freebsd-arm64@0.15.18: - optional: true - - esbuild-linux-32@0.15.18: - optional: true - - esbuild-linux-64@0.15.18: - optional: true - - esbuild-linux-arm64@0.15.18: - optional: true - - esbuild-linux-arm@0.15.18: - optional: true - - esbuild-linux-mips64le@0.15.18: - optional: true - - esbuild-linux-ppc64le@0.15.18: - optional: true - - esbuild-linux-riscv64@0.15.18: - optional: true - - esbuild-linux-s390x@0.15.18: - optional: true - - esbuild-netbsd-64@0.15.18: - optional: true - - esbuild-openbsd-64@0.15.18: - optional: true - - esbuild-sunos-64@0.15.18: - optional: true - - esbuild-windows-32@0.15.18: - optional: true - - esbuild-windows-64@0.15.18: - optional: true - - esbuild-windows-arm64@0.15.18: - optional: true - - esbuild@0.15.18: - optionalDependencies: - '@esbuild/android-arm': 0.15.18 - '@esbuild/linux-loong64': 0.15.18 - esbuild-android-64: 0.15.18 - esbuild-android-arm64: 0.15.18 - esbuild-darwin-64: 0.15.18 - esbuild-darwin-arm64: 0.15.18 - esbuild-freebsd-64: 0.15.18 - esbuild-freebsd-arm64: 0.15.18 - esbuild-linux-32: 0.15.18 - esbuild-linux-64: 0.15.18 - esbuild-linux-arm: 0.15.18 - esbuild-linux-arm64: 0.15.18 - esbuild-linux-mips64le: 0.15.18 - esbuild-linux-ppc64le: 0.15.18 - esbuild-linux-riscv64: 0.15.18 - esbuild-linux-s390x: 0.15.18 - esbuild-netbsd-64: 0.15.18 - esbuild-openbsd-64: 0.15.18 - esbuild-sunos-64: 0.15.18 - esbuild-windows-32: 0.15.18 - esbuild-windows-64: 0.15.18 - esbuild-windows-arm64: 0.15.18 - - escalade@3.1.1: {} - - escape-html@1.0.3: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@4.0.0: {} - - escodegen@2.1.0: - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - - eslint-compat-utils@0.5.1(eslint@9.32.0(jiti@2.3.3)): - dependencies: - eslint: 9.32.0(jiti@2.3.3) - semver: 7.7.2 - - eslint-import-context@0.1.9(unrs-resolver@1.11.1): - dependencies: - get-tsconfig: 4.10.1 - stable-hash-x: 0.2.0 - optionalDependencies: - unrs-resolver: 1.11.1 - - eslint-import-resolver-node@0.3.9: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 1.22.10 - transitivePeerDependencies: - - supports-color - - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0(jiti@2.3.3)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3)))(eslint@9.32.0(jiti@2.3.3)): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1(supports-color@5.5.0) - eslint: 9.32.0(jiti@2.3.3) - get-tsconfig: 4.10.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.14 - unrs-resolver: 1.11.1 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0(jiti@2.3.3)) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0(jiti@2.3.3)): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - eslint: 9.32.0(jiti@2.3.3) - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-plugin-es-x@7.8.0(eslint@9.32.0(jiti@2.3.3)): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0(jiti@2.3.3)) - '@eslint-community/regexpp': 4.12.1 - eslint: 9.32.0(jiti@2.3.3) - eslint-compat-utils: 0.5.1(eslint@9.32.0(jiti@2.3.3)) - - eslint-plugin-es@3.0.1(eslint@9.32.0(jiti@2.3.3)): - dependencies: - eslint: 9.32.0(jiti@2.3.3) - eslint-utils: 2.1.0 - regexpp: 3.2.0 - - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0(jiti@2.3.3)): - dependencies: - '@typescript-eslint/types': 8.38.0 - comment-parser: 1.4.1 - debug: 4.4.1(supports-color@5.5.0) - eslint: 9.32.0(jiti@2.3.3) - eslint-import-context: 0.1.9(unrs-resolver@1.11.1) - is-glob: 4.0.3 - minimatch: 10.0.3 - semver: 7.7.2 - stable-hash-x: 0.2.0 - unrs-resolver: 1.11.1 - optionalDependencies: - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3)): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.32.0(jiti@2.3.3) - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0(jiti@2.3.3)) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-n@17.21.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0(jiti@2.3.3)) - enhanced-resolve: 5.18.2 - eslint: 9.32.0(jiti@2.3.3) - eslint-plugin-es-x: 7.8.0(eslint@9.32.0(jiti@2.3.3)) - get-tsconfig: 4.10.1 - globals: 15.15.0 - ignore: 5.3.2 - minimatch: 9.0.5 - semver: 7.7.2 - ts-declaration-location: 1.0.7(typescript@5.6.3) - transitivePeerDependencies: - - typescript - - eslint-plugin-node@11.1.0(eslint@9.32.0(jiti@2.3.3)): - dependencies: - eslint: 9.32.0(jiti@2.3.3) - eslint-plugin-es: 3.0.1(eslint@9.32.0(jiti@2.3.3)) - eslint-utils: 2.1.0 - ignore: 5.2.4 - minimatch: 3.1.2 - resolve: 1.22.6 - semver: 6.3.1 - - eslint-plugin-promise@7.2.1(eslint@9.32.0(jiti@2.3.3)): - dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.32.0(jiti@2.3.3)) - eslint: 9.32.0(jiti@2.3.3) - - eslint-plugin-react@7.37.5(eslint@9.32.0(jiti@2.3.3)): - dependencies: - array-includes: 3.1.9 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 9.32.0(jiti@2.3.3) - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.9 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.12 - string.prototype.repeat: 1.0.0 - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-utils@2.1.0: - dependencies: - eslint-visitor-keys: 1.3.0 - - eslint-visitor-keys@1.3.0: {} - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.32.0(jiti@2.3.3): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0(jiti@2.3.3)) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.0 - '@eslint/core': 0.15.1 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.32.0 - '@eslint/plugin-kit': 0.3.4 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.1(supports-color@5.5.0) - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - optionalDependencies: - jiti: 2.3.3 - transitivePeerDependencies: - - supports-color - - esm@3.2.25: {} - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - esprima@4.0.1: {} - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@2.0.2: {} - - esutils@2.0.3: {} - - etag@1.8.1: {} - - eventemitter2@6.4.9: {} - - events@1.1.1: {} - - events@3.3.0: {} - - express-brute@1.0.1(express@5.1.0): - dependencies: - express: 5.1.0 - long-timeout: 0.1.1 - underscore: 1.8.3 - - express-session@1.18.2: - dependencies: - cookie: 0.7.2 - cookie-signature: 1.0.7 - debug: 2.6.9 - depd: 2.0.0 - on-headers: 1.1.0 - parseurl: 1.3.3 - safe-buffer: 5.2.1 - uid-safe: 2.1.5 - transitivePeerDependencies: - - supports-color - - express@5.1.0: - dependencies: - accepts: 2.0.0 - body-parser: 2.2.0 - content-disposition: 1.0.0 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.2.2 - debug: 4.4.1(supports-color@5.5.0) - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.0 - fresh: 2.0.0 - http-errors: 2.0.0 - merge-descriptors: 2.0.0 - mime-types: 3.0.1 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.14.0 - range-parser: 1.2.1 - router: 2.2.0 - send: 1.2.0 - serve-static: 2.2.0 - statuses: 2.0.2 - type-is: 2.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - extend-shallow@2.0.1: - dependencies: - is-extendable: 0.1.1 - - extend@3.0.2: {} - - extract-zip@2.0.1: - dependencies: - debug: 4.4.1(supports-color@5.5.0) - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - - extsprintf@1.3.0: {} - - extsprintf@1.4.1: {} - - fast-content-type-parse@3.0.0: {} - - fast-deep-equal@3.1.3: {} - - fast-fifo@1.3.2: {} - - fast-glob@3.3.2: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fast-safe-stringify@2.1.1: {} - - fast-uri@3.0.3: {} - - fast-xml-parser@5.2.5: - dependencies: - strnum: 2.1.1 - - fastq@1.17.1: - dependencies: - reusify: 1.0.4 - - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - - fdir@6.4.6(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - fflate@0.8.2: {} - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - file-type@21.0.0: - dependencies: - '@tokenizer/inflate': 0.2.7 - strtok3: 10.3.4 - token-types: 6.0.4 - uint8array-extras: 1.4.0 - transitivePeerDependencies: - - supports-color - - filesize@11.0.2: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - finalhandler@2.1.0: - dependencies: - debug: 4.4.1(supports-color@5.5.0) - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flatted@3.3.3: {} - - follow-redirects@1.15.3: {} - - for-each@0.3.3: - dependencies: - is-callable: 1.2.7 - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - - foreground-child@3.1.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - form-data@4.0.2: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - mime-types: 2.1.35 - - formidable@2.1.2: - dependencies: - dezalgo: 1.0.4 - hexoid: 1.0.0 - once: 1.4.0 - qs: 6.11.2 - - forwarded@0.2.0: {} - - fresh@0.5.2: {} - - fresh@2.0.0: {} - - fs-capacitor@8.0.0: {} - - fs-extra@11.3.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - - fs-extra@8.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.1: {} - - function-bind@1.1.2: {} - - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - - get-caller-file@2.0.5: {} - - get-intrinsic@1.2.1: - dependencies: - function-bind: 1.1.1 - has: 1.0.4 - has-proto: 1.0.1 - has-symbols: 1.0.3 - - get-intrinsic@1.2.3: - dependencies: - es-errors: 1.0.0 - function-bind: 1.1.2 - has-proto: 1.0.1 - has-symbols: 1.0.3 - hasown: 2.0.0 - - get-intrinsic@1.2.4: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 - hasown: 2.0.2 - - get-intrinsic@1.2.5: - dependencies: - call-bind-apply-helpers: 1.0.0 - dunder-proto: 1.0.0 - es-define-property: 1.0.1 - es-errors: 1.3.0 - function-bind: 1.1.2 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-package-type@0.1.0: {} - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stream@5.2.0: - dependencies: - pump: 3.0.3 - - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - - get-tsconfig@4.10.1: - dependencies: - resolve-pkg-maps: 1.0.0 - - get-uri@6.0.5: - dependencies: - basic-ftp: 5.0.5 - data-uri-to-buffer: 6.0.2 - debug: 4.4.1(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - getopts@2.3.0: {} - - getos@3.2.1: - dependencies: - async: 3.2.4 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@10.3.12: - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.5 - minipass: 7.0.4 - path-scurry: 1.10.2 - - globals@14.0.0: {} - - globals@15.15.0: {} - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - - gopd@1.0.1: - dependencies: - get-intrinsic: 1.2.3 - - gopd@1.2.0: {} - - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - graphql-list-fields@2.0.4: {} - - graphql-rate-limit-directive@2.0.6(@graphql-tools/utils@10.9.1(graphql@16.11.0))(graphql@16.11.0)(rate-limiter-flexible@5.0.4): - dependencies: - '@graphql-tools/utils': 10.9.1(graphql@16.11.0) - graphql: 16.11.0 - rate-limiter-flexible: 5.0.4 - - graphql-tag@2.12.6(graphql@16.11.0): - dependencies: - graphql: 16.11.0 - tslib: 2.8.1 - optional: true - - graphql-tools@9.0.20(graphql@16.11.0): - dependencies: - '@graphql-tools/schema': 10.0.25(graphql@16.11.0) - graphql: 16.11.0 - tslib: 2.8.1 - optionalDependencies: - '@apollo/client': 3.13.8(graphql@16.11.0) - transitivePeerDependencies: - - '@types/react' - - graphql-ws - - react - - react-dom - - subscriptions-transport-ws - - graphql-upload@17.0.0(@types/express@5.0.0)(graphql@16.11.0): - dependencies: - '@types/busboy': 1.5.4 - '@types/node': 22.7.7 - '@types/object-path': 0.11.4 - busboy: 1.6.0 - fs-capacitor: 8.0.0 - graphql: 16.11.0 - http-errors: 2.0.0 - object-path: 0.11.8 - optionalDependencies: - '@types/express': 5.0.0 - - graphql@16.11.0: {} - - gray-matter@4.0.3: - dependencies: - js-yaml: 3.14.1 - kind-of: 6.0.3 - section-matter: 1.0.0 - strip-bom-string: 1.0.0 - - has-bigints@1.1.0: {} - - has-flag@3.0.0: {} - - has-flag@4.0.0: {} - - has-property-descriptors@1.0.1: - dependencies: - get-intrinsic: 1.2.3 - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.0 - - has-proto@1.0.1: {} - - has-proto@1.0.3: {} - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.0.3: {} - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.0.3 - - has@1.0.4: {} - - hasown@2.0.0: - dependencies: - function-bind: 1.1.2 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - he@1.2.0: {} - - hexoid@1.0.0: {} - - highlight.js@11.11.1: {} - - highlight.js@11.9.0: - optional: true - - hogan.js@3.0.2: - dependencies: - mkdirp: 0.3.0 - nopt: 1.0.10 - - hoist-non-react-statics@3.3.2: - dependencies: - react-is: 16.13.1 - optional: true - - html-encoding-sniffer@4.0.0: - dependencies: - whatwg-encoding: 3.1.1 - - htmlparser2@10.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - entities: 6.0.1 - - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - http-proxy-agent@7.0.2: - dependencies: - agent-base: 7.1.4 - debug: 4.4.1(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.4 - debug: 4.4.1(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.1.13: {} - - ieee754@1.2.1: {} - - ignore-by-default@1.0.1: {} - - ignore@5.2.4: {} - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - image-size@2.0.2: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - import-string@0.1.2(typescript@5.6.3): - dependencies: - '@swc/wasm': 1.4.16 - module-from-string: 3.3.0 - typescript: 5.6.3 - - imurmurhash@0.1.4: {} - - inherits@2.0.4: {} - - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - - interpret@2.2.0: {} - - ip-address@9.0.5: - dependencies: - jsbn: 1.1.0 - sprintf-js: 1.1.3 - - ipaddr.js@1.9.1: {} - - is-arguments@1.1.1: - dependencies: - call-bind: 1.0.8 - has-tostringtag: 1.0.2 - - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-arrayish@0.3.2: {} - - is-async-function@2.1.1: - dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-bun-module@2.0.0: - dependencies: - semver: 7.7.2 - - is-callable@1.2.7: {} - - is-core-module@2.13.1: - dependencies: - hasown: 2.0.0 - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 - - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-extendable@0.1.1: {} - - is-extglob@2.1.1: {} - - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-fullwidth-code-point@3.0.0: {} - - is-generator-function@1.0.10: - dependencies: - has-tostringtag: 1.0.2 - - is-generator-function@1.1.0: - dependencies: - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-map@2.0.3: {} - - is-negative-zero@2.0.3: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-number@7.0.0: {} - - is-potential-custom-element-name@1.0.1: {} - - is-promise@4.0.0: {} - - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 - - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-typed-array@1.1.13: - dependencies: - which-typed-array: 1.1.14 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.19 - - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - isarray@1.0.0: {} - - isarray@2.0.5: {} - - isexe@2.0.0: {} - - isomorphic-dompurify@2.7.0: - dependencies: - '@types/dompurify': 3.0.5 - dompurify: 3.2.6 - jsdom: 24.1.3 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - utf-8-validate - - iterator.prototype@1.1.5: - dependencies: - define-data-property: 1.1.4 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - has-symbols: 1.1.0 - set-function-name: 2.0.2 - - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jiti@1.21.0: {} - - jiti@2.3.3: - optional: true - - jmespath@0.16.0: {} - - js-base64@3.7.7: {} - - js-binary@1.2.0: {} - - js-tokens@4.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsbn@1.1.0: {} - - jsdom@24.1.3: - dependencies: - cssstyle: 4.6.0 - data-urls: 5.0.0 - decimal.js: 10.6.0 - form-data: 4.0.2 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.21 - parse5: 7.3.0 - rrweb-cssom: 0.7.1 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 4.1.4 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - ws: 8.18.3 - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - jsdom@26.1.0: - dependencies: - cssstyle: 4.6.0 - data-urls: 5.0.0 - decimal.js: 10.6.0 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.21 - parse5: 7.3.0 - rrweb-cssom: 0.8.0 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 5.1.2 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - ws: 8.18.3 - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-schema-traverse@1.0.0: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@1.0.2: - dependencies: - minimist: 1.2.8 - - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - - jsonfile@5.0.0: - dependencies: - universalify: 0.1.2 - optionalDependencies: - graceful-fs: 4.2.11 - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - jsonwebtoken@9.0.2: - dependencies: - jws: 3.2.2 - lodash.includes: 4.3.0 - lodash.isboolean: 3.0.3 - lodash.isinteger: 4.0.4 - lodash.isnumber: 3.0.3 - lodash.isplainobject: 4.0.6 - lodash.isstring: 4.0.1 - lodash.once: 4.1.1 - ms: 2.1.3 - semver: 7.7.2 - - jsx-ast-utils@3.3.5: - dependencies: - array-includes: 3.1.9 - array.prototype.flat: 1.3.3 - object.assign: 4.1.7 - object.values: 1.2.1 - - jwa@1.4.1: - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - - jws@3.2.2: - dependencies: - jwa: 1.4.1 - safe-buffer: 5.2.1 - - katex@0.16.22: - dependencies: - commander: 8.3.0 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kind-of@6.0.3: {} - - klaw@4.1.0: {} - - knex@3.1.0(pg@8.16.3): - dependencies: - colorette: 2.0.19 - commander: 10.0.1 - debug: 4.3.4 - escalade: 3.1.1 - esm: 3.2.25 - get-package-type: 0.1.0 - getopts: 2.3.0 - interpret: 2.2.0 - lodash: 4.17.21 - pg-connection-string: 2.6.2 - rechoir: 0.8.0 - resolve-from: 5.0.0 - tarn: 3.0.2 - tildify: 2.0.0 - optionalDependencies: - pg: 8.16.3 - transitivePeerDependencies: - - supports-color - - kolorist@1.8.0: {} - - ldap-filter@0.3.3: - dependencies: - assert-plus: 1.0.0 - - ldapauth-fork@5.0.5: - dependencies: - '@types/ldapjs': 2.2.5 - bcryptjs: 2.4.3 - ldapjs: 2.3.3 - lru-cache: 7.18.3 - - ldapjs@2.3.3: - dependencies: - abstract-logging: 2.0.1 - asn1: 0.2.6 - assert-plus: 1.0.0 - backoff: 2.5.0 - ldap-filter: 0.3.3 - once: 1.4.0 - vasync: 2.2.1 - verror: 1.10.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - lilconfig@2.1.0: {} - - lilconfig@3.1.1: {} - - lines-and-columns@1.2.4: {} - - linkify-it@5.0.0: - dependencies: - uc.micro: 2.1.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash-es@4.17.21: {} - - lodash.includes@4.3.0: {} - - lodash.isboolean@3.0.3: {} - - lodash.isinteger@4.0.4: {} - - lodash.isnumber@3.0.3: {} - - lodash.isplainobject@4.0.6: {} - - lodash.isstring@4.0.1: {} - - lodash.merge@4.6.2: {} - - lodash.once@4.1.1: {} - - lodash.repeat@4.1.0: {} - - lodash.sortby@4.7.0: {} - - lodash@4.17.21: {} - - loglevel@1.9.2: {} - - long-timeout@0.1.1: {} - - long@4.0.0: {} - - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - - lru-cache@10.4.3: {} - - lru-cache@11.1.0: {} - - lru-cache@7.18.3: {} - - luxon@3.7.1: {} - - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - - markdown-it-abbr@2.0.0: {} - - markdown-it-attrs@4.3.1(markdown-it@14.1.0): - dependencies: - markdown-it: 14.1.0 - - markdown-it-decorate@1.2.2: {} - - markdown-it-emoji@3.0.0: {} - - markdown-it-expand-tabs@1.0.13: - dependencies: - lodash.repeat: 4.1.0 - - markdown-it-footnote@4.0.0: {} - - markdown-it-imsize@2.0.1: {} - - markdown-it-mark@4.0.0: {} - - markdown-it-mdc@0.2.6(@types/markdown-it@14.1.2)(markdown-it@14.1.0): - dependencies: - '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 - yaml: 2.8.0 - - markdown-it-multimd-table@4.2.3: {} - - markdown-it-sub@2.0.0: {} - - markdown-it-sup@2.0.0: {} - - markdown-it-task-lists@2.1.1: {} - - markdown-it@14.1.0: - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - - math-intrinsics@1.1.0: {} - - mathjax@3.2.2: {} - - mdurl@2.0.0: {} - - media-typer@0.3.0: {} - - media-typer@1.1.0: {} - - merge-descriptors@2.0.0: {} - - merge2@1.4.1: {} - - methods@1.1.2: {} - - micromatch@4.0.5: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mime-db@1.52.0: {} - - mime-db@1.54.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mime-types@3.0.1: - dependencies: - mime-db: 1.54.0 - - mime@2.6.0: {} - - minimalistic-assert@1.0.1: {} - - minimatch@10.0.3: - dependencies: - '@isaacs/brace-expansion': 5.0.0 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist@1.2.8: {} - - minipass@7.0.4: {} - - mitt@3.0.1: {} - - mkdirp@0.3.0: {} - - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 - - module-from-string@3.3.0: - dependencies: - esbuild: 0.15.18 - nanoid: 3.3.11 - - ms@2.0.0: {} - - ms@2.1.2: {} - - ms@2.1.3: {} - - multer@2.0.2: - dependencies: - append-field: 1.0.0 - busboy: 1.6.0 - concat-stream: 2.0.0 - mkdirp: 0.5.6 - object-assign: 4.1.1 - type-is: 1.6.18 - xtend: 4.0.2 - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - nanoid@3.3.11: {} - - nanoid@5.1.5: {} - - napi-postinstall@0.3.2: {} - - natural-compare@1.4.0: {} - - negotiator@0.6.3: {} - - negotiator@0.6.4: {} - - negotiator@1.0.0: {} - - neostandard@0.12.2(@typescript-eslint/utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3)))(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3): - dependencies: - '@humanwhocodes/gitignore-to-minimatch': 1.0.2 - '@stylistic/eslint-plugin': 2.11.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - eslint: 9.32.0(jiti@2.3.3) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0(jiti@2.3.3)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3)))(eslint@9.32.0(jiti@2.3.3)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0(jiti@2.3.3)) - eslint-plugin-n: 17.21.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - eslint-plugin-promise: 7.2.1(eslint@9.32.0(jiti@2.3.3)) - eslint-plugin-react: 7.37.5(eslint@9.32.0(jiti@2.3.3)) - find-up: 5.0.0 - globals: 15.15.0 - peowly: 1.3.2 - typescript-eslint: 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - transitivePeerDependencies: - - '@typescript-eslint/utils' - - eslint-import-resolver-node - - eslint-plugin-import - - supports-color - - typescript - - netmask@2.0.2: {} - - node-2fa@2.0.3: - dependencies: - '@types/notp': 2.0.3 - notp: 2.0.3 - thirty-two: 1.0.2 - tslib: 2.6.2 - - node-cache@5.1.2: - dependencies: - clone: 2.1.2 - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-uuid@1.4.1: {} - - nodemailer@7.0.5: {} - - nodemon@3.1.10: - dependencies: - chokidar: 3.6.0 - debug: 4.4.1(supports-color@5.5.0) - ignore-by-default: 1.0.1 - minimatch: 3.1.2 - pstree.remy: 1.1.8 - semver: 7.7.2 - simple-update-notifier: 2.0.0 - supports-color: 5.5.0 - touch: 3.1.1 - undefsafe: 2.0.5 - - nopt@1.0.10: - dependencies: - abbrev: 1.1.1 - - normalize-path@3.0.0: {} - - notp@2.0.3: {} - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - nwsapi@2.2.21: {} - - oauth@0.10.0: {} - - oauth@0.9.15: {} - - object-assign@4.1.1: {} - - object-hash@3.0.0: {} - - object-inspect@1.12.3: {} - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object-path@0.11.8: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.entries@1.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - objection@3.1.5(knex@3.1.0(pg@8.16.3)): - dependencies: - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - db-errors: 0.2.3 - knex: 3.1.0(pg@8.16.3) - - octokit@5.0.3: - dependencies: - '@octokit/app': 16.0.1 - '@octokit/core': 7.0.3 - '@octokit/oauth-app': 8.0.1 - '@octokit/plugin-paginate-graphql': 6.0.0(@octokit/core@7.0.3) - '@octokit/plugin-paginate-rest': 13.1.1(@octokit/core@7.0.3) - '@octokit/plugin-rest-endpoint-methods': 16.0.0(@octokit/core@7.0.3) - '@octokit/plugin-retry': 8.0.1(@octokit/core@7.0.3) - '@octokit/plugin-throttling': 11.0.1(@octokit/core@7.0.3) - '@octokit/request-error': 7.0.0 - '@octokit/types': 14.1.0 - '@octokit/webhooks': 14.1.1 - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - - on-headers@1.1.0: {} - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - optimism@0.18.1: - dependencies: - '@wry/caches': 1.0.1 - '@wry/context': 0.7.4 - '@wry/trie': 0.5.0 - tslib: 2.8.1 - optional: true - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - pac-proxy-agent@7.2.0: - dependencies: - '@tootallnate/quickjs-emscripten': 0.23.0 - agent-base: 7.1.4 - debug: 4.4.1(supports-color@5.5.0) - get-uri: 6.0.5 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - pac-resolver@7.0.1: - dependencies: - degenerator: 5.0.1 - netmask: 2.0.2 - - pako@2.1.0: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse5-htmlparser2-tree-adapter@7.1.0: - dependencies: - domhandler: 5.0.3 - parse5: 7.3.0 - - parse5-parser-stream@7.1.2: - dependencies: - parse5: 7.3.0 - - parse5@7.3.0: - dependencies: - entities: 6.0.1 - - parseurl@1.3.3: {} - - passport-auth0@1.4.4: - dependencies: - axios: 1.6.2 - passport-oauth: 1.0.0 - passport-oauth2: 1.8.0 - transitivePeerDependencies: - - debug - - passport-cas@0.1.1: - dependencies: - node-uuid: 1.4.1 - underscore: 1.6.0 - xml2js: 0.4.4 - - passport-discord@0.1.4: - dependencies: - passport-oauth2: 1.8.0 - - passport-dropbox-oauth2@1.1.0: - dependencies: - passport-oauth: 1.0.0 - pkginfo: 0.2.3 - - passport-facebook@3.0.0: - dependencies: - passport-oauth2: 1.8.0 - - passport-github2@0.1.12: - dependencies: - passport-oauth2: 1.8.0 - - passport-gitlab2@5.0.0: - dependencies: - passport-oauth2: 1.8.0 - - passport-google-oauth20@2.0.0: - dependencies: - passport-oauth2: 1.8.0 - - passport-jwt@4.0.1: - dependencies: - jsonwebtoken: 9.0.2 - passport-strategy: 1.0.0 - - passport-ldapauth@3.0.1: - dependencies: - ldapauth-fork: 5.0.5 - passport-strategy: 1.0.0 - - passport-local@1.0.0: - dependencies: - passport-strategy: 1.0.0 - - passport-microsoft@2.1.0: - dependencies: - passport-oauth2: 1.8.0 - - passport-oauth1@1.3.0: - dependencies: - oauth: 0.9.15 - passport-strategy: 1.0.0 - utils-merge: 1.0.1 - - passport-oauth2@1.8.0: - dependencies: - base64url: 3.0.1 - oauth: 0.10.0 - passport-strategy: 1.0.0 - uid2: 0.0.4 - utils-merge: 1.0.1 - - passport-oauth@1.0.0: - dependencies: - passport-oauth1: 1.3.0 - passport-oauth2: 1.8.0 - - passport-okta-oauth@0.0.1: - dependencies: - passport-oauth: 1.0.0 - pkginfo: 0.2.3 - uid2: 0.0.3 - - passport-openidconnect@0.1.2: - dependencies: - oauth: 0.10.0 - passport-strategy: 1.0.0 - - passport-slack-oauth2@1.2.0: - dependencies: - passport-oauth2: 1.8.0 - - passport-strategy@1.0.0: {} - - passport-twitch-strategy@2.2.0: - dependencies: - node-fetch: 2.7.0 - passport-oauth2: 1.8.0 - transitivePeerDependencies: - - encoding - - passport@0.7.0: - dependencies: - passport-strategy: 1.0.0 - pause: 0.0.1 - utils-merge: 1.0.1 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-scurry@1.10.2: - dependencies: - lru-cache: 10.4.3 - minipass: 7.0.4 - - path-to-regexp@8.2.0: {} - - pause@0.0.1: {} - - pem-jwk@2.0.0: - dependencies: - asn1.js: 5.4.1 - - pend@1.2.0: {} - - peowly@1.3.2: {} - - pg-cloudflare@1.2.7: - optional: true - - pg-connection-string@2.6.2: {} - - pg-connection-string@2.9.1: {} - - pg-cursor@2.15.3(pg@8.16.3): - dependencies: - pg: 8.16.3 - - pg-format@1.0.4: {} - - pg-hstore@2.3.4: - dependencies: - underscore: 1.13.6 - - pg-int8@1.0.1: {} - - pg-pool@3.10.1(pg@8.16.3): - dependencies: - pg: 8.16.3 - - pg-protocol@1.10.3: {} - - pg-pubsub@0.8.1: - dependencies: - pg: 8.16.3 - pg-format: 1.0.4 - pony-cause: 2.1.10 - promised-retry: 0.5.0 - transitivePeerDependencies: - - pg-native - - pg-query-stream@4.10.3(pg@8.16.3): - dependencies: - pg: 8.16.3 - pg-cursor: 2.15.3(pg@8.16.3) - - pg-tsquery@8.4.2: {} - - pg-types@2.2.0: - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.0 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 - - pg@8.16.3: - dependencies: - pg-connection-string: 2.9.1 - pg-pool: 3.10.1(pg@8.16.3) - pg-protocol: 1.10.3 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.2.7 - - pgpass@1.0.5: - dependencies: - split2: 4.2.0 - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - pify@2.3.0: {} - - pirates@4.0.6: {} - - pkginfo@0.2.3: {} - - pony-cause@1.1.1: {} - - pony-cause@2.1.10: {} - - poolifier@5.1.0: {} - - possible-typed-array-names@1.0.0: {} - - possible-typed-array-names@1.1.0: {} - - postcss-css-variables@0.19.0(postcss@8.4.47): - dependencies: - balanced-match: 1.0.2 - escape-string-regexp: 1.0.5 - extend: 3.0.2 - postcss: 8.4.47 - - postcss-import@15.1.0(postcss@8.4.47): - dependencies: - postcss: 8.4.47 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.10 - - postcss-js@4.0.1(postcss@8.4.47): - dependencies: - camelcase-css: 2.0.1 - postcss: 8.4.47 - - postcss-load-config@4.0.2(postcss@8.4.47): - dependencies: - lilconfig: 3.1.1 - yaml: 2.8.0 - optionalDependencies: - postcss: 8.4.47 - - postcss-nested@6.0.1(postcss@8.4.47): - dependencies: - postcss: 8.4.47 - postcss-selector-parser: 6.0.16 - - postcss-selector-parser@6.0.16: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-value-parser@4.2.0: {} - - postcss@8.4.47: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postgres-array@2.0.0: {} - - postgres-bytea@1.0.0: {} - - postgres-date@1.0.7: {} - - postgres-interval@1.2.0: - dependencies: - xtend: 4.0.2 - - precond@0.2.3: {} - - prelude-ls@1.2.1: {} - - progress@2.0.3: {} - - prom-client@15.1.3: - dependencies: - '@opentelemetry/api': 1.9.0 - tdigest: 0.1.2 - - promised-retry@0.5.0: - dependencies: - pony-cause: 1.1.1 - - prop-types@15.8.1: - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - proxy-agent@6.5.0: - dependencies: - agent-base: 7.1.4 - debug: 4.4.1(supports-color@5.5.0) - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - lru-cache: 7.18.3 - pac-proxy-agent: 7.2.0 - proxy-from-env: 1.1.0 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - proxy-from-env@1.1.0: {} - - psl@1.9.0: {} - - pstree.remy@1.1.8: {} - - pump@3.0.3: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - - punycode.js@2.3.1: {} - - punycode@1.3.2: {} - - punycode@2.3.1: {} - - puppeteer-core@24.15.0: - dependencies: - '@puppeteer/browsers': 2.10.6 - chromium-bidi: 7.2.0(devtools-protocol@0.0.1464554) - debug: 4.4.1(supports-color@5.5.0) - devtools-protocol: 0.0.1464554 - typed-query-selector: 2.12.0 - ws: 8.18.3 - transitivePeerDependencies: - - bare-buffer - - bufferutil - - supports-color - - utf-8-validate - - pvtsutils@1.3.6: - dependencies: - tslib: 2.8.1 - - pvutils@1.1.3: {} - - qr-image@3.2.0: {} - - qs@6.11.2: - dependencies: - side-channel: 1.0.4 - - qs@6.14.0: - dependencies: - side-channel: 1.1.0 - - querystring@0.2.0: {} - - querystringify@2.2.0: {} - - queue-microtask@1.2.3: {} - - random-bytes@1.0.0: {} - - range-parser@1.2.1: {} - - rate-limiter-flexible@5.0.4: {} - - raw-body@3.0.0: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.6.3 - unpipe: 1.0.0 - - react-is@16.13.1: {} - - read-cache@1.0.0: - dependencies: - pify: 2.3.0 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - readdirp@4.1.2: {} - - rechoir@0.8.0: - dependencies: - resolve: 1.22.8 - - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - - regexp-tree@0.1.27: {} - - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 - - regexpp@3.2.0: {} - - rehackt@0.1.0: - optional: true - - remove-markdown@0.6.2: {} - - require-directory@2.1.1: {} - - require-from-string@2.0.2: {} - - requires-port@1.0.0: {} - - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - resolve@1.22.10: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - resolve@1.22.6: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - resolve@1.22.8: - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - resolve@2.0.0-next.5: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - retry@0.13.1: {} - - reusify@1.0.4: {} - - router@2.2.0: - dependencies: - debug: 4.4.1(supports-color@5.5.0) - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.2.0 - transitivePeerDependencies: - - supports-color - - rrweb-cssom@0.7.1: {} - - rrweb-cssom@0.8.0: {} - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-array-concat@1.1.3: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - - safe-buffer@5.2.1: {} - - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - - safe-regex@2.1.1: - dependencies: - regexp-tree: 0.1.27 - - safer-buffer@2.1.2: {} - - sanitize-filename@1.6.3: - dependencies: - truncate-utf8-bytes: 1.0.2 - - sax@0.6.1: {} - - sax@1.2.1: {} - - saxes@6.0.0: - dependencies: - xmlchars: 2.2.0 - - scim-query-filter-parser@2.0.4: - dependencies: - apg-lib: 3.2.0 - - scule@1.3.0: {} - - section-matter@1.0.0: - dependencies: - extend-shallow: 2.0.1 - kind-of: 6.0.3 - - semver@6.3.1: {} - - semver@7.7.2: {} - - send@1.2.0: - dependencies: - debug: 4.4.1(supports-color@5.5.0) - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.0 - mime-types: 3.0.1 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - serve-favicon@2.5.1: - dependencies: - etag: 1.8.1 - fresh: 0.5.2 - ms: 2.1.3 - parseurl: 1.3.3 - safe-buffer: 5.2.1 - - serve-static@2.2.0: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.0 - transitivePeerDependencies: - - supports-color - - set-function-length@1.2.0: - dependencies: - define-data-property: 1.1.1 - function-bind: 1.1.2 - get-intrinsic: 1.2.3 - gopd: 1.0.1 - has-property-descriptors: 1.0.1 - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - - setprototypeof@1.2.0: {} - - sha.js@2.4.12: - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - to-buffer: 1.2.1 - - sharp@0.34.3: - dependencies: - color: 4.2.3 - detect-libc: 2.0.4 - semver: 7.7.2 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.3 - '@img/sharp-darwin-x64': 0.34.3 - '@img/sharp-libvips-darwin-arm64': 1.2.0 - '@img/sharp-libvips-darwin-x64': 1.2.0 - '@img/sharp-libvips-linux-arm': 1.2.0 - '@img/sharp-libvips-linux-arm64': 1.2.0 - '@img/sharp-libvips-linux-ppc64': 1.2.0 - '@img/sharp-libvips-linux-s390x': 1.2.0 - '@img/sharp-libvips-linux-x64': 1.2.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 - '@img/sharp-libvips-linuxmusl-x64': 1.2.0 - '@img/sharp-linux-arm': 0.34.3 - '@img/sharp-linux-arm64': 0.34.3 - '@img/sharp-linux-ppc64': 0.34.3 - '@img/sharp-linux-s390x': 0.34.3 - '@img/sharp-linux-x64': 0.34.3 - '@img/sharp-linuxmusl-arm64': 0.34.3 - '@img/sharp-linuxmusl-x64': 0.34.3 - '@img/sharp-wasm32': 0.34.3 - '@img/sharp-win32-arm64': 0.34.3 - '@img/sharp-win32-ia32': 0.34.3 - '@img/sharp-win32-x64': 0.34.3 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - shiki@1.0.0: - dependencies: - '@shikijs/core': 1.0.0 - - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.0.4: - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - signal-exit@4.1.0: {} - - simple-git@3.28.0: - dependencies: - '@kwsites/file-exists': 1.1.1 - '@kwsites/promise-deferred': 1.1.1 - debug: 4.4.1(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - - simple-update-notifier@2.0.0: - dependencies: - semver: 7.7.2 - - smart-buffer@4.2.0: {} - - socket.io-adapter@2.5.5: - dependencies: - debug: 4.3.7 - ws: 8.17.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-parser@4.2.4: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - transitivePeerDependencies: - - supports-color - - socket.io@4.8.1: - dependencies: - accepts: 1.3.8 - base64id: 2.0.0 - cors: 2.8.5 - debug: 4.3.7 - engine.io: 6.6.2 - socket.io-adapter: 2.5.5 - socket.io-parser: 4.2.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socks-proxy-agent@8.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.1(supports-color@5.5.0) - socks: 2.8.6 - transitivePeerDependencies: - - supports-color - - socks@2.8.6: - dependencies: - ip-address: 9.0.5 - smart-buffer: 4.2.0 - - source-map-js@1.2.1: {} - - source-map@0.6.1: {} - - split2@4.2.0: {} - - sprintf-js@1.0.3: {} - - sprintf-js@1.1.3: {} - - stable-hash-x@0.2.0: {} - - stable-hash@0.0.5: {} - - statuses@2.0.1: {} - - statuses@2.0.2: {} - - stop-iteration-iterator@1.1.0: - dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 - - streamsearch@1.1.0: {} - - streamx@2.22.1: - dependencies: - fast-fifo: 1.3.2 - text-decoder: 1.2.3 - optionalDependencies: - bare-events: 2.6.0 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string.prototype.matchall@4.0.12: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - regexp.prototype.flags: 1.5.4 - set-function-name: 2.0.2 - side-channel: 1.1.0 - - string.prototype.repeat@1.0.0: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.24.0 - - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - strip-bom-string@1.0.0: {} - - strip-bom@3.0.0: {} - - strip-json-comments@3.1.1: {} - - striptags@3.2.0: {} - - strnum@2.1.1: {} - - strtok3@10.3.4: - dependencies: - '@tokenizer/token': 0.3.0 - - sucrase@3.35.0: - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - commander: 4.1.1 - glob: 10.3.12 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.6 - ts-interface-checker: 0.1.13 - - superagent@8.1.2: - dependencies: - component-emitter: 1.3.0 - cookiejar: 2.1.4 - debug: 4.3.4 - fast-safe-stringify: 2.1.1 - form-data: 4.0.0 - formidable: 2.1.2 - methods: 1.1.2 - mime: 2.6.0 - qs: 6.11.2 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - supports-color@5.5.0: - dependencies: - has-flag: 3.0.0 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - symbol-observable@4.0.0: - optional: true - - symbol-tree@3.2.4: {} - - tailwindcss@3.4.3: - dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.2 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.0 - lilconfig: 2.1.0 - micromatch: 4.0.5 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.1.1 - postcss: 8.4.47 - postcss-import: 15.1.0(postcss@8.4.47) - postcss-js: 4.0.1(postcss@8.4.47) - postcss-load-config: 4.0.2(postcss@8.4.47) - postcss-nested: 6.0.1(postcss@8.4.47) - postcss-selector-parser: 6.0.16 - resolve: 1.22.10 - sucrase: 3.35.0 - transitivePeerDependencies: - - ts-node - - tapable@2.2.2: {} - - tar-fs@3.1.0: - dependencies: - pump: 3.0.3 - tar-stream: 3.1.7 - optionalDependencies: - bare-fs: 4.1.6 - bare-path: 3.0.0 - transitivePeerDependencies: - - bare-buffer - - tar-stream@3.1.7: - dependencies: - b4a: 1.6.7 - fast-fifo: 1.3.2 - streamx: 2.22.1 - - tarn@3.0.2: {} - - tdigest@0.1.2: - dependencies: - bintrees: 1.0.2 - - text-decoder@1.2.3: - dependencies: - b4a: 1.6.7 - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - thirty-two@1.0.2: {} - - tildify@2.0.0: {} - - tinyglobby@0.2.14: - dependencies: - fdir: 6.4.6(picomatch@4.0.3) - picomatch: 4.0.3 - - tldts-core@6.1.86: {} - - tldts@6.1.86: - dependencies: - tldts-core: 6.1.86 - - to-buffer@1.2.1: - dependencies: - isarray: 2.0.5 - safe-buffer: 5.2.1 - typed-array-buffer: 1.0.3 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - toad-cache@3.7.0: {} - - toidentifier@1.0.1: {} - - token-types@6.0.4: - dependencies: - '@tokenizer/token': 0.3.0 - ieee754: 1.2.1 - - touch@3.1.1: {} - - tough-cookie@4.1.4: - dependencies: - psl: 1.9.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - - tough-cookie@5.1.2: - dependencies: - tldts: 6.1.86 - - tr46@0.0.3: {} - - tr46@5.1.1: - dependencies: - punycode: 2.3.1 - - truncate-utf8-bytes@1.0.2: - dependencies: - utf8-byte-length: 1.0.4 - - ts-api-utils@2.1.0(typescript@5.6.3): - dependencies: - typescript: 5.6.3 - - ts-declaration-location@1.0.7(typescript@5.6.3): - dependencies: - picomatch: 4.0.3 - typescript: 5.6.3 - - ts-interface-checker@0.1.13: {} - - ts-invariant@0.10.3: - dependencies: - tslib: 2.8.1 - optional: true - - tsconfig-paths@3.15.0: - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - - tslib@2.6.2: {} - - tslib@2.8.1: {} - - turndown@7.2.0: - dependencies: - '@mixmark-io/domino': 2.2.0 - - twemoji-parser@14.0.0: {} - - twemoji@14.0.2: - dependencies: - fs-extra: 8.1.0 - jsonfile: 5.0.0 - twemoji-parser: 14.0.0 - universalify: 0.1.2 - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - type-is@2.0.1: - dependencies: - content-type: 1.0.5 - media-typer: 1.1.0 - mime-types: 3.0.1 - - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 - - typed-query-selector@2.12.0: {} - - typedarray@0.0.6: {} - - typescript-eslint@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3): - dependencies: - '@typescript-eslint/eslint-plugin': 8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3))(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0(jiti@2.3.3))(typescript@5.6.3) - eslint: 9.32.0(jiti@2.3.3) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - typescript@5.6.3: {} - - uc.micro@2.1.0: {} - - ufo@1.6.1: {} - - uid-safe@2.1.5: - dependencies: - random-bytes: 1.0.0 - - uid2@0.0.3: {} - - uid2@0.0.4: {} - - uint8array-extras@1.4.0: {} - - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - - undefsafe@2.0.5: {} - - underscore@1.13.6: {} - - underscore@1.6.0: {} - - underscore@1.8.3: {} - - undici-types@5.26.5: {} - - undici-types@6.19.8: {} - - undici-types@6.20.0: {} - - undici-types@7.8.0: {} - - undici@7.12.0: {} - - universal-github-app-jwt@2.2.2: {} - - universal-user-agent@7.0.3: {} - - universalify@0.1.2: {} - - universalify@0.2.0: {} - - universalify@2.0.1: {} - - unorm@1.6.0: {} - - unpipe@1.0.0: {} - - unrs-resolver@1.11.1: - dependencies: - napi-postinstall: 0.3.2 - optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - - url@0.10.3: - dependencies: - punycode: 1.3.2 - querystring: 0.2.0 - - uslug@1.0.4: - dependencies: - unorm: 1.6.0 - - utf8-byte-length@1.0.4: {} - - util-deprecate@1.0.2: {} - - util@0.12.5: - dependencies: - inherits: 2.0.4 - is-arguments: 1.1.1 - is-generator-function: 1.0.10 - is-typed-array: 1.1.13 - which-typed-array: 1.1.16 - - utils-merge@1.0.1: {} - - uuid@11.1.0: {} - - uuid@8.0.0: {} - - validate.js@0.13.1: {} - - vary@1.1.2: {} - - vasync@2.2.1: - dependencies: - verror: 1.10.0 - - verror@1.10.0: - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - - verror@1.10.1: - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.4.1 - - vue-email@0.8.11(typescript@5.6.3)(vue@3.5.18(typescript@5.6.3)): - dependencies: - '@vue-email/cli': 0.0.14(typescript@5.6.3)(vue@3.5.18(typescript@5.6.3)) - '@vue-email/tailwind': 0.0.6 - isomorphic-dompurify: 2.7.0 - shiki: 1.0.0 - ufo: 1.6.1 - vue: 3.5.18(typescript@5.6.3) - vue-i18n: 9.13.1(vue@3.5.18(typescript@5.6.3)) - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - ts-node - - typescript - - utf-8-validate - - vue-i18n@9.13.1(vue@3.5.18(typescript@5.6.3)): - dependencies: - '@intlify/core-base': 9.13.1 - '@intlify/shared': 9.13.1 - '@vue/devtools-api': 6.6.1 - vue: 3.5.18(typescript@5.6.3) - - vue@3.5.18(typescript@5.6.3): - dependencies: - '@vue/compiler-dom': 3.5.18 - '@vue/compiler-sfc': 3.5.18 - '@vue/runtime-dom': 3.5.18 - '@vue/server-renderer': 3.5.18(vue@3.5.18(typescript@5.6.3)) - '@vue/shared': 3.5.18 - optionalDependencies: - typescript: 5.6.3 - - w3c-xmlserializer@5.0.0: - dependencies: - xml-name-validator: 5.0.0 - - webidl-conversions@3.0.1: {} - - webidl-conversions@7.0.0: {} - - whatwg-encoding@3.1.1: - dependencies: - iconv-lite: 0.6.3 - - whatwg-mimetype@4.0.0: {} - - whatwg-url@14.2.0: - dependencies: - tr46: 5.1.1 - webidl-conversions: 7.0.0 - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.19 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-typed-array@1.1.14: - dependencies: - available-typed-arrays: 1.0.6 - call-bind: 1.0.5 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.2 - - which-typed-array@1.1.16: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.3 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - - which-typed-array@1.1.19: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - word-wrap@1.2.5: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrappy@1.0.2: {} - - ws@8.17.1: {} - - ws@8.18.3: {} - - xml-crypto@6.1.2: - dependencies: - '@xmldom/is-dom-node': 1.0.1 - '@xmldom/xmldom': 0.8.10 - xpath: 0.0.33 - - xml-encryption@3.1.0: - dependencies: - '@xmldom/xmldom': 0.8.10 - escape-html: 1.0.3 - xpath: 0.0.32 - - xml-name-validator@5.0.0: {} - - xml2js@0.4.4: - dependencies: - sax: 0.6.1 - xmlbuilder: 15.1.1 - - xml2js@0.6.2: - dependencies: - sax: 1.2.1 - xmlbuilder: 11.0.1 - - xmlbuilder@11.0.1: {} - - xmlbuilder@15.1.1: {} - - xmlchars@2.2.0: {} - - xpath@0.0.32: {} - - xpath@0.0.33: {} - - xpath@0.0.34: {} - - xss@1.0.15: - dependencies: - commander: 2.20.3 - cssfilter: 0.0.10 - - xtend@4.0.2: {} - - y18n@5.0.8: {} - - yaml@2.8.0: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - - yocto-queue@0.1.0: {} - - zen-observable-ts@1.2.5: - dependencies: - zen-observable: 0.8.15 - optional: true - - zen-observable@0.8.15: - optional: true - - zod@3.25.76: {} diff --git a/server/renderers/markdown.mjs b/server/renderers/markdown.mjs deleted file mode 100644 index 9fd8c141b..000000000 --- a/server/renderers/markdown.mjs +++ /dev/null @@ -1,159 +0,0 @@ -import MarkdownIt from 'markdown-it' -import mdAttrs from 'markdown-it-attrs' -import mdDecorate from 'markdown-it-decorate' -import { full as mdEmoji } from 'markdown-it-emoji' -import mdTaskLists from 'markdown-it-task-lists' -import mdExpandTabs from 'markdown-it-expand-tabs' -import mdAbbr from 'markdown-it-abbr' -import mdSup from 'markdown-it-sup' -import mdSub from 'markdown-it-sub' -import mdMark from 'markdown-it-mark' -import mdMultiTable from 'markdown-it-multimd-table' -import mdFootnote from 'markdown-it-footnote' -import mdMdc from 'markdown-it-mdc' -import katex from 'katex' -import mdImsize from './modules/markdown-it-imsize.mjs' -import mdUnderline from './modules/markdown-it-underline.mjs' -// import 'katex/dist/contrib/mhchem' -import twemoji from 'twemoji' -import plantuml from './modules/plantuml.mjs' -import kroki from './modules/kroki.mjs' -import katexHelper from './modules/katex.mjs' - -import hljs from 'highlight.js' - -import { escape, times } from 'lodash-es' - -const quoteStyles = { - chinese: '””‘’', - english: '“”‘’', - french: ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'], - german: '„“‚‘', - greek: '«»‘’', - japanese: '「」「」', - hungarian: '„”’’', - polish: '„”‚‘', - portuguese: '«»‘’', - russian: '«»„“', - spanish: '«»‘’', - swedish: '””’’' -} - -export async function render (input, config) { - const md = new MarkdownIt({ - html: config.allowHTML, - breaks: config.lineBreaks, - linkify: config.linkify, - typography: config.typographer, - quotes: quoteStyles[config.quotes] ?? quoteStyles.english, - highlight (str, lang) { - if (lang === 'diagram') { - return `
    ${Buffer.from(str, 'base64').toString()}
    ` - } else if (['mermaid', 'plantuml'].includes(lang)) { - return `
    ${escape(str)}
    ` - } else { - const highlighted = lang ? hljs.highlight(str, { language: lang, ignoreIllegals: true }) : { value: str } - const lineCount = highlighted.value.match(/\n/g).length - const lineNums = lineCount > 1 ? `` : '' - return `
    ${highlighted.value}${lineNums}
    ` - } - } - }) - .use(mdAttrs, { - allowedAttributes: ['id', 'class', 'target'] - }) - .use(mdDecorate) - .use(mdEmoji) - .use(mdTaskLists, { label: false, labelAfter: false }) - .use(mdExpandTabs, { tabWidth: config.tabWidth }) - .use(mdAbbr) - .use(mdSup) - .use(mdSub) - .use(mdMark) - .use(mdFootnote) - .use(mdImsize) - .use(mdMdc) - - if (config.underline) { - md.use(mdUnderline) - } - - if (config.mdmultiTable) { - md.use(mdMultiTable, { multiline: true, rowspan: true, headerless: true }) - } - - // -------------------------------- - // PLANTUML - // -------------------------------- - - if (config.plantuml) { - plantuml.init(md, { server: config.plantumlServerUrl }) - } - - // -------------------------------- - // KROKI - // -------------------------------- - - if (config.kroki) { - kroki.init(md, { server: config.krokiServerUrl }) - } - - // -------------------------------- - // KATEX - // -------------------------------- - - const macros = {} - - // TODO: Add mhchem (needs esm conversion) - // Add \ce, \pu, and \tripledash to the KaTeX macros. - // katex.__defineMacro('\\ce', function (context) { - // return chemParse(context.consumeArgs(1)[0], 'ce') - // }) - // katex.__defineMacro('\\pu', function (context) { - // return chemParse(context.consumeArgs(1)[0], 'pu') - // }) - - // Needed for \bond for the ~ forms - // Raise by 2.56mu, not 2mu. We're raising a hyphen-minus, U+002D, not - // a mathematical minus, U+2212. So we need that extra 0.56. - katex.__defineMacro('\\tripledash', '{\\vphantom{-}\\raisebox{2.56mu}{$\\mkern2mu' + '\\tiny\\text{-}\\mkern1mu\\text{-}\\mkern1mu\\text{-}\\mkern2mu$}}') - - md.inline.ruler.after('escape', 'katex_inline', katexHelper.katexInline) - md.renderer.rules.katex_inline = (tokens, idx) => { - try { - return katex.renderToString(tokens[idx].content, { - displayMode: false, macros - }) - } catch (err) { - console.warn(err) - return tokens[idx].content - } - } - md.block.ruler.after('blockquote', 'katex_block', katexHelper.katexBlock, { - alt: ['paragraph', 'reference', 'blockquote', 'list'] - }) - md.renderer.rules.katex_block = (tokens, idx) => { - try { - return '

    ' + katex.renderToString(tokens[idx].content, { - displayMode: true, macros - }) + '

    ' - } catch (err) { - console.warn(err) - return tokens[idx].content - } - } - - // -------------------------------- - // TWEMOJI - // -------------------------------- - - md.renderer.rules.emoji = (token, idx) => { - return twemoji.parse(token[idx].content, { - callback (icon, opts) { - return `/_assets/svg/twemoji/${icon}.svg` - } - }) - } - - return md.render(input) -} diff --git a/server/renderers/modules/katex.mjs b/server/renderers/modules/katex.mjs deleted file mode 100644 index 74a096dbc..000000000 --- a/server/renderers/modules/katex.mjs +++ /dev/null @@ -1,145 +0,0 @@ -// Test if potential opening or closing delimieter -// Assumes that there is a "$" at state.src[pos] -function isValidDelim (state, pos) { - const max = state.posMax - let canOpen = true - let canClose = true - - const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1 - const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1 - - // Check non-whitespace conditions for opening and closing, and - // check that closing delimeter isn't followed by a number - if (prevChar === 0x20/* " " */ || prevChar === 0x09/* \t */ || - (nextChar >= 0x30/* "0" */ && nextChar <= 0x39/* "9" */)) { - canClose = false - } - if (nextChar === 0x20/* " " */ || nextChar === 0x09/* \t */) { - canOpen = false - } - - return { - canOpen, - canClose - } -} - -export default { - katexInline (state, silent) { - let match, token, res, pos - - if (state.src[state.pos] !== '$') { return false } - - res = isValidDelim(state, state.pos) - if (!res.canOpen) { - if (!silent) { state.pending += '$' } - state.pos += 1 - return true - } - - // First check for and bypass all properly escaped delimieters - // This loop will assume that the first leading backtick can not - // be the first character in state.src, which is known since - // we have found an opening delimieter already. - const start = state.pos + 1 - match = start - while ((match = state.src.indexOf('$', match)) !== -1) { - // Found potential $, look for escapes, pos will point to - // first non escape when complete - pos = match - 1 - while (state.src[pos] === '\\') { pos -= 1 } - - // Even number of escapes, potential closing delimiter found - if (((match - pos) % 2) === 1) { break } - match += 1 - } - - // No closing delimter found. Consume $ and continue. - if (match === -1) { - if (!silent) { state.pending += '$' } - state.pos = start - return true - } - - // Check if we have empty content, ie: $$. Do not parse. - if (match - start === 0) { - if (!silent) { state.pending += '$$' } - state.pos = start + 1 - return true - } - - // Check for valid closing delimiter - res = isValidDelim(state, match) - if (!res.canClose) { - if (!silent) { state.pending += '$' } - state.pos = start - return true - } - - if (!silent) { - token = state.push('katex_inline', 'math', 0) - token.markup = '$' - token.content = state.src - // Extract the math part without the $ - .slice(start, match) - // Escape the curly braces since they will be interpreted as - // attributes by markdown-it-attrs (the "curly_attributes" - // core rule) - .replaceAll('{', '{{') - .replaceAll('}', '}}') - } - - state.pos = match + 1 - return true - }, - - katexBlock (state, start, end, silent) { - let firstLine; let lastLine; let next; let lastPos; let found = false - let pos = state.bMarks[start] + state.tShift[start] - let max = state.eMarks[start] - - if (pos + 2 > max) { return false } - if (state.src.slice(pos, pos + 2) !== '$$') { return false } - - pos += 2 - firstLine = state.src.slice(pos, max) - - if (silent) { return true } - if (firstLine.trim().slice(-2) === '$$') { - // Single line expression - firstLine = firstLine.trim().slice(0, -2) - found = true - } - - for (next = start; !found;) { - next++ - - if (next >= end) { break } - - pos = state.bMarks[next] + state.tShift[next] - max = state.eMarks[next] - - if (pos < max && state.tShift[next] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - break - } - - if (state.src.slice(pos, max).trim().slice(-2) === '$$') { - lastPos = state.src.slice(0, max).lastIndexOf('$$') - lastLine = state.src.slice(pos, lastPos) - found = true - } - } - - state.line = next + 1 - - const token = state.push('katex_block', 'math', 0) - token.block = true - token.content = (firstLine && firstLine.trim() ? firstLine + '\n' : '') + - state.getLines(start + 1, next, state.tShift[start], true) + - (lastLine && lastLine.trim() ? lastLine : '') - token.map = [start, state.line] - token.markup = '$$' - return true - } -} diff --git a/server/renderers/modules/kroki.mjs b/server/renderers/modules/kroki.mjs deleted file mode 100644 index 43e102bc7..000000000 --- a/server/renderers/modules/kroki.mjs +++ /dev/null @@ -1,143 +0,0 @@ -import pako from 'pako' - -// ------------------------------------ -// Markdown - PlantUML Preprocessor -// ------------------------------------ - -export default { - init (mdinst, conf) { - mdinst.use((md, opts) => { - const openMarker = opts.openMarker || '```kroki' - const openChar = openMarker.charCodeAt(0) - const closeMarker = opts.closeMarker || '```' - const closeChar = closeMarker.charCodeAt(0) - const server = opts.server || 'https://kroki.io' - - md.block.ruler.before('fence', 'kroki', (state, startLine, endLine, silent) => { - let nextLine - let markup - let params - let token - let i - let autoClosed = false - let start = state.bMarks[startLine] + state.tShift[startLine] - let max = state.eMarks[startLine] - - // Check out the first character quickly, - // this should filter out most of non-uml blocks - // - if (openChar !== state.src.charCodeAt(start)) { return false } - - // Check out the rest of the marker string - // - for (i = 0; i < openMarker.length; ++i) { - if (openMarker[i] !== state.src[start + i]) { return false } - } - - markup = state.src.slice(start, start + i) - params = state.src.slice(start + i, max) - - // Since start is found, we can report success here in validation mode - // - if (silent) { return true } - - // Search for the end of the block - // - nextLine = startLine - - for (;;) { - nextLine++ - if (nextLine >= endLine) { - // unclosed block should be autoclosed by end of document. - // also block seems to be autoclosed by end of parent - break - } - - start = state.bMarks[nextLine] + state.tShift[nextLine] - max = state.eMarks[nextLine] - - if (start < max && state.sCount[nextLine] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - // - ``` - // test - break - } - - if (closeChar !== state.src.charCodeAt(start)) { - // didn't find the closing fence - continue - } - - if (state.sCount[nextLine] > state.sCount[startLine]) { - // closing fence should not be indented with respect of opening fence - continue - } - - let closeMarkerMatched = true - for (i = 0; i < closeMarker.length; ++i) { - if (closeMarker[i] !== state.src[start + i]) { - closeMarkerMatched = false - break - } - } - - if (!closeMarkerMatched) { - continue - } - - // make sure tail has spaces only - if (state.skipSpaces(start + i) < max) { - continue - } - - // found! - autoClosed = true - break - } - - let contents = state.src - .split('\n') - .slice(startLine + 1, nextLine) - .join('\n') - - // We generate a token list for the alt property, to mimic what the image parser does. - let altToken = [] - // Remove leading space if any. - let alt = params ? params.slice(1) : 'uml diagram' - state.md.inline.parse( - alt, - state.md, - state.env, - altToken - ) - - let firstlf = contents.indexOf('\n') - if (firstlf === -1) firstlf = undefined - let diagramType = contents.substring(0, firstlf) - contents = contents.substring(firstlf + 1) - - const result = pako.deflate(contents).toString('base64').replace(/\+/g, '-').replace(/\//g, '_') - - token = state.push('kroki', 'img', 0) - // alt is constructed from children. No point in populating it here. - token.attrs = [ [ 'src', `${server}/${diagramType}/svg/${result}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ] - token.block = true - token.children = altToken - token.info = params - token.map = [ startLine, nextLine ] - token.markup = markup - - state.line = nextLine + (autoClosed ? 1 : 0) - - return true - }, { - alt: [ 'paragraph', 'reference', 'blockquote', 'list' ] - }) - md.renderer.rules.kroki = md.renderer.rules.image - }, { - openMarker: conf.openMarker, - closeMarker: conf.closeMarker, - server: conf.server - }) - } -} diff --git a/server/renderers/modules/markdown-it-imsize.mjs b/server/renderers/modules/markdown-it-imsize.mjs deleted file mode 100644 index 6b6b30e6c..000000000 --- a/server/renderers/modules/markdown-it-imsize.mjs +++ /dev/null @@ -1,259 +0,0 @@ -// Adapted from markdown-it-imsize plugin by @tatsy -// Original source https://github.com/tatsy/markdown-it-imsize/blob/master/lib/index.js - -function renderImSize (state, silent) { - let attrs - let code - let label - let pos - let ref - let res - let title - let width = '' - let height = '' - let token - let tokens - let start - let href = '' - const oldPos = state.pos - const max = state.posMax - - if (state.src.charCodeAt(state.pos) !== 0x21/* ! */) { return false } - if (state.src.charCodeAt(state.pos + 1) !== 0x5B/* [ */) { return false } - - const labelStart = state.pos + 2 - const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false) - - // parser failed to find ']', so it's not a valid link - if (labelEnd < 0) { return false } - - pos = labelEnd + 1 - if (pos < max && state.src.charCodeAt(pos) === 0x28/* ( */) { - // - // Inline link - // - - // [link]( "title" ) - // ^^ skipping these spaces - pos++ - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - if (pos >= max) { return false } - - // [link]( "title" ) - // ^^^^^^ parsing link destination - start = pos - res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax) - if (res.ok) { - href = state.md.normalizeLink(res.str) - if (state.md.validateLink(href)) { - pos = res.pos - } else { - href = '' - } - } - - // [link]( "title" ) - // ^^ skipping these spaces - start = pos - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - - // [link]( "title" ) - // ^^^^^^^ parsing link title - res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax) - if (pos < max && start !== pos && res.ok) { - title = res.str - pos = res.pos - - // [link]( "title" ) - // ^^ skipping these spaces - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - } else { - title = '' - } - - // [link]( "title" =WxH ) - // ^^^^ parsing image size - if (pos - 1 >= 0) { - code = state.src.charCodeAt(pos - 1) - - // there must be at least one white spaces - // between previous field and the size - if (code === 0x20) { - res = parseImageSize(state.src, pos, state.posMax) - if (res.ok) { - width = res.width - height = res.height - pos = res.pos - - // [link]( "title" =WxH ) - // ^^ skipping these spaces - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - } - } - } - - if (pos >= max || state.src.charCodeAt(pos) !== 0x29/* ) */) { - state.pos = oldPos - return false - } - pos++ - } else { - // - // Link reference - // - if (typeof state.env.references === 'undefined') { return false } - - // [foo] [bar] - // ^^ optional whitespace (can include newlines) - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - - if (pos < max && state.src.charCodeAt(pos) === 0x5B/* [ */) { - start = pos + 1 - pos = state.md.helpers.parseLinkLabel(state, pos) - if (pos >= 0) { - label = state.src.slice(start, pos++) - } else { - pos = labelEnd + 1 - } - } else { - pos = labelEnd + 1 - } - - // covers label === '' and label === undefined - // (collapsed reference link and shortcut reference link respectively) - if (!label) { label = state.src.slice(labelStart, labelEnd) } - - ref = state.env.references[state.md.utils.normalizeReference(label)] - if (!ref) { - state.pos = oldPos - return false - } - href = ref.href - title = ref.title - } - - // - // We found the end of the link, and know for a fact it's a valid link; - // so all that's left to do is to call tokenizer. - // - if (!silent) { - state.pos = labelStart - state.posMax = labelEnd - - const newState = new state.md.inline.State( - state.src.slice(labelStart, labelEnd), - state.md, - state.env, - tokens = [] - ) - newState.md.inline.tokenize(newState) - - token = state.push('image', 'img', 0) - token.attrs = attrs = [['src', href], - ['alt', '']] - token.children = tokens - if (title) { - attrs.push(['title', title]) - } - - if (width !== '') { - attrs.push(['width', width]) - } - - if (height !== '') { - attrs.push(['height', height]) - } - } - - state.pos = pos - state.posMax = max - return true -} - -function parseNextNumber (str, pos, max) { - let code - const start = pos - const result = { - ok: false, - pos, - value: '' - } - - code = str.charCodeAt(pos) - - while ((pos < max && (code >= 0x30 /* 0 */ && code <= 0x39 /* 9 */)) || code === 0x25 /* % */) { - code = str.charCodeAt(++pos) - } - - result.ok = true - result.pos = pos - result.value = str.slice(start, pos) - - return result -} - -function parseImageSize (str, pos, max) { - let code - const result = { - ok: false, - pos: 0, - width: '', - height: '' - } - - if (pos >= max) { return result } - - code = str.charCodeAt(pos) - - if (code !== 0x3d /* = */) { return result } - - pos++ - - // size must follow = without any white spaces as follows - // (1) =300x200 - // (2) =300x - // (3) =x200 - code = str.charCodeAt(pos) - if (code !== 0x78 /* x */ && (code < 0x30 || code > 0x39) /* [0-9] */) { - return result - } - - // parse width - const resultW = parseNextNumber(str, pos, max) - pos = resultW.pos - - // next charactor must be 'x' - code = str.charCodeAt(pos) - if (code !== 0x78 /* x */) { return result } - - pos++ - - // parse height - const resultH = parseNextNumber(str, pos, max) - pos = resultH.pos - - result.width = resultW.value - result.height = resultH.value - result.pos = pos - result.ok = true - return result -} - -export default (md) => { - md.inline.ruler.before('emphasis', 'image', renderImSize) -} diff --git a/server/renderers/modules/markdown-it-underline.mjs b/server/renderers/modules/markdown-it-underline.mjs deleted file mode 100644 index b898d1ce0..000000000 --- a/server/renderers/modules/markdown-it-underline.mjs +++ /dev/null @@ -1,12 +0,0 @@ -function renderEm (tokens, idx, opts, env, slf) { - const token = tokens[idx] - if (token.markup === '_') { - token.tag = 'u' - } - return slf.renderToken(tokens, idx, opts) -} - -export default (md) => { - md.renderer.rules.em_open = renderEm - md.renderer.rules.em_close = renderEm -} diff --git a/server/renderers/modules/plantuml.mjs b/server/renderers/modules/plantuml.mjs deleted file mode 100644 index 9d5e3ea58..000000000 --- a/server/renderers/modules/plantuml.mjs +++ /dev/null @@ -1,187 +0,0 @@ -import pako from 'pako' - -// ------------------------------------ -// Markdown - PlantUML Preprocessor -// ------------------------------------ - -export default { - init (mdinst, conf) { - mdinst.use((md, opts) => { - const openMarker = opts.openMarker || '```plantuml' - const openChar = openMarker.charCodeAt(0) - const closeMarker = opts.closeMarker || '```' - const closeChar = closeMarker.charCodeAt(0) - const imageFormat = opts.imageFormat || 'svg' - const server = opts.server || 'https://plantuml.requarks.io' - - md.block.ruler.before('fence', 'uml_diagram', (state, startLine, endLine, silent) => { - let nextLine - let i - let autoClosed = false - let start = state.bMarks[startLine] + state.tShift[startLine] - let max = state.eMarks[startLine] - - // Check out the first character quickly, - // this should filter out most of non-uml blocks - // - if (openChar !== state.src.charCodeAt(start)) { return false } - - // Check out the rest of the marker string - // - for (i = 0; i < openMarker.length; ++i) { - if (openMarker[i] !== state.src[start + i]) { return false } - } - - const markup = state.src.slice(start, start + i) - const params = state.src.slice(start + i, max) - - // Since start is found, we can report success here in validation mode - // - if (silent) { return true } - - // Search for the end of the block - // - nextLine = startLine - - for (;;) { - nextLine++ - if (nextLine >= endLine) { - // unclosed block should be autoclosed by end of document. - // also block seems to be autoclosed by end of parent - break - } - - start = state.bMarks[nextLine] + state.tShift[nextLine] - max = state.eMarks[nextLine] - - if (start < max && state.sCount[nextLine] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - // - ``` - // test - break - } - - if (closeChar !== state.src.charCodeAt(start)) { - // didn't find the closing fence - continue - } - - if (state.sCount[nextLine] > state.sCount[startLine]) { - // closing fence should not be indented with respect of opening fence - continue - } - - let closeMarkerMatched = true - for (i = 0; i < closeMarker.length; ++i) { - if (closeMarker[i] !== state.src[start + i]) { - closeMarkerMatched = false - break - } - } - - if (!closeMarkerMatched) { - continue - } - - // make sure tail has spaces only - if (state.skipSpaces(start + i) < max) { - continue - } - - // found! - autoClosed = true - break - } - - const contents = state.src - .split('\n') - .slice(startLine + 1, nextLine) - .join('\n') - - // We generate a token list for the alt property, to mimic what the image parser does. - const altToken = [] - // Remove leading space if any. - const alt = params ? params.slice(1) : 'uml diagram' - state.md.inline.parse( - alt, - state.md, - state.env, - altToken - ) - - const zippedCode = encode64(pako.deflate('@startuml\n' + contents + '\n@enduml', { to: 'string' })) - - const token = state.push('uml_diagram', 'img', 0) - // alt is constructed from children. No point in populating it here. - token.attrs = [['src', `${server}/${imageFormat}/${zippedCode}`], ['alt', ''], ['class', 'uml-diagram']] - token.block = true - token.children = altToken - token.info = params - token.map = [startLine, nextLine] - token.markup = markup - - state.line = nextLine + (autoClosed ? 1 : 0) - - return true - }, { - alt: ['paragraph', 'reference', 'blockquote', 'list'] - }) - md.renderer.rules.uml_diagram = md.renderer.rules.image - }, { - openMarker: conf.openMarker, - closeMarker: conf.closeMarker, - imageFormat: conf.imageFormat, - server: conf.server - }) - } -} - -function encode64 (data) { - let r = '' - for (let i = 0; i < data.length; i += 3) { - if (i + 2 === data.length) { - r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), 0) - } else if (i + 1 === data.length) { - r += append3bytes(data.charCodeAt(i), 0, 0) - } else { - r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), data.charCodeAt(i + 2)) - } - } - return r -} - -function append3bytes (b1, b2, b3) { - const c1 = b1 >> 2 - const c2 = ((b1 & 0x3) << 4) | (b2 >> 4) - const c3 = ((b2 & 0xF) << 2) | (b3 >> 6) - const c4 = b3 & 0x3F - let r = '' - r += encode6bit(c1 & 0x3F) - r += encode6bit(c2 & 0x3F) - r += encode6bit(c3 & 0x3F) - r += encode6bit(c4 & 0x3F) - return r -} - -function encode6bit (raw) { - let b = raw - if (b < 10) { - return String.fromCharCode(48 + b) - } - b -= 10 - if (b < 26) { - return String.fromCharCode(65 + b) - } - b -= 26 - if (b < 26) { - return String.fromCharCode(97 + b) - } - b -= 26 - if (b === 0) { - return '-' - } - if (b === 1) { - return '_' - } - return '?' -} diff --git a/server/tasks/simple/check-version.mjs b/server/tasks/simple/check-version.mjs deleted file mode 100644 index 6db0f92aa..000000000 --- a/server/tasks/simple/check-version.mjs +++ /dev/null @@ -1,21 +0,0 @@ -export async function task (payload) { - WIKI.logger.info('Checking for latest version...') - - try { - const resp = await fetch('https://api.github.com/repos/requarks/wiki/releases/latest').then(r => r.json()) - const strictVersion = resp.tag_name.indexOf('v') === 0 ? resp.tag_name.substring(1) : resp.tag_name - WIKI.logger.info(`Latest version is ${resp.tag_name}.`) - WIKI.config.update = { - lastCheckedAt: (new Date).toISOString(), - version: strictVersion, - versionDate: resp.published_at - } - await WIKI.configSvc.saveToDb(['update']) - - WIKI.logger.info('Checked for latest version: [ COMPLETED ]') - } catch (err) { - WIKI.logger.error('Checking for latest version: [ FAILED ]') - WIKI.logger.error(err.message) - throw err - } -} diff --git a/server/tasks/simple/clean-job-history.mjs b/server/tasks/simple/clean-job-history.mjs deleted file mode 100644 index 112efa6e2..000000000 --- a/server/tasks/simple/clean-job-history.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import { DateTime } from 'luxon' - -export async function task (payload) { - WIKI.logger.info('Cleaning scheduler job history...') - - try { - await WIKI.db.knex('jobHistory') - .whereNot('state', 'active') - .andWhere('startedAt', '<=', DateTime.utc().minus({ seconds: WIKI.config.scheduler.historyExpiration }).toISO()) - .del() - - WIKI.logger.info('Cleaned scheduler job history: [ COMPLETED ]') - } catch (err) { - WIKI.logger.error('Cleaning scheduler job history: [ FAILED ]') - WIKI.logger.error(err.message) - throw err - } -} diff --git a/server/tasks/simple/refresh-autocomplete.mjs b/server/tasks/simple/refresh-autocomplete.mjs deleted file mode 100644 index 332550e94..000000000 --- a/server/tasks/simple/refresh-autocomplete.mjs +++ /dev/null @@ -1,13 +0,0 @@ -export async function task (payload) { - WIKI.logger.info('Refreshing autocomplete word index...') - - try { - await WIKI.db.pages.refreshAutocompleteIndex() - - WIKI.logger.info('Refreshed autocomplete word index: [ COMPLETED ]') - } catch (err) { - WIKI.logger.error('Refreshing autocomplete word index: [ FAILED ]') - WIKI.logger.error(err.message) - throw err - } -} diff --git a/server/tasks/simple/update-locales.mjs b/server/tasks/simple/update-locales.mjs deleted file mode 100644 index b2425069e..000000000 --- a/server/tasks/simple/update-locales.mjs +++ /dev/null @@ -1,53 +0,0 @@ -import { setTimeout } from 'node:timers/promises' - -export async function task (payload) { - if (WIKI.config.update?.locales === false) { - return - } - - WIKI.logger.info('Fetching latest localization data...') - - try { - const metadata = await fetch('https://github.com/requarks/wiki-locales/raw/main/locales/metadata.json').then(r => r.json()) - for (const lang of metadata.languages) { - // -> Build filename - const langFilenameParts = [lang.language] - if (lang.region) { - langFilenameParts.push(lang.region) - } - if (lang.script) { - langFilenameParts.push(lang.script) - } - const langFilename = langFilenameParts.join('-') - - WIKI.logger.debug(`Fetching updates for language ${langFilename}...`) - - const strings = await fetch(`https://github.com/requarks/wiki-locales/raw/main/locales/${langFilename}.json`).then(r => r.json()) - if (strings) { - await WIKI.db.knex('locales').insert({ - code: langFilename, - name: lang.name, - nativeName: lang.localizedName, - language: lang.language, - region: lang.region, - script: lang.script, - isRTL: lang.isRtl, - strings - }).onConflict('code').merge({ - strings, - updatedAt: new Date() - }) - } - - WIKI.logger.debug(`Updated strings for language ${langFilename}.`) - - await setTimeout(100) - } - - WIKI.logger.info('Fetched latest localization data: [ COMPLETED ]') - } catch (err) { - WIKI.logger.error('Fetching latest localization data: [ FAILED ]') - WIKI.logger.error(err.message) - throw err - } -} diff --git a/server/tasks/workers/purge-uploads.mjs b/server/tasks/workers/purge-uploads.mjs deleted file mode 100644 index 2541e74db..000000000 --- a/server/tasks/workers/purge-uploads.mjs +++ /dev/null @@ -1,27 +0,0 @@ -import path from 'node:path' -import fse from 'fs-extra' -import { DateTime } from 'luxon' - -export async function task ({ payload }) { - WIKI.logger.info('Purging orphaned upload files...') - - try { - const uplTempPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'uploads') - await fse.ensureDir(uplTempPath) - const ls = await fse.readdir(uplTempPath) - const fifteenAgo = DateTime.now().minus({ minutes: 15 }) - - for (const f of ls) { - const stat = fse.stat(path.join(uplTempPath, f)) - if ((await stat).isFile && stat.ctime < fifteenAgo) { - await fse.unlink(path.join(uplTempPath, f)) - } - } - - WIKI.logger.info('Purging orphaned upload files: [ COMPLETED ]') - } catch (err) { - WIKI.logger.error('Purging orphaned upload files: [ FAILED ]') - WIKI.logger.error(err.message) - throw err - } -} diff --git a/server/tasks/workers/rebuild-search-index.mjs b/server/tasks/workers/rebuild-search-index.mjs deleted file mode 100644 index 7b642d55c..000000000 --- a/server/tasks/workers/rebuild-search-index.mjs +++ /dev/null @@ -1,35 +0,0 @@ -import { pipeline } from 'node:stream/promises' -import { Transform } from 'node:stream' - -export async function task ({ payload }) { - WIKI.logger.info('Rebuilding search index...') - - try { - await WIKI.ensureDb() - - let idx = 0 - await pipeline( - WIKI.db.knex.select('id', 'title', 'description', 'locale', 'render', 'password').from('pages').stream(), - new Transform({ - objectMode: true, - transform: async (page, enc, cb) => { - idx++ - await WIKI.db.pages.updatePageSearchVector({ page }) - if (idx % 50 === 0) { - WIKI.logger.info(`Rebuilding search index... (${idx} processed)`) - } - cb() - } - }) - ) - - WIKI.logger.info('Refreshing autocomplete index...') - await WIKI.db.pages.refreshAutocompleteIndex() - - WIKI.logger.info('Rebuilt search index: [ COMPLETED ]') - } catch (err) { - WIKI.logger.error('Rebuilding search index: [ FAILED ]') - WIKI.logger.error(err.message) - throw err - } -} diff --git a/server/tasks/workers/render-page.mjs b/server/tasks/workers/render-page.mjs deleted file mode 100644 index b80141643..000000000 --- a/server/tasks/workers/render-page.mjs +++ /dev/null @@ -1,108 +0,0 @@ -import { get, has, isEmpty, reduce, times, toSafeInteger } from 'lodash-es' -import * as cheerio from 'cheerio' - -export async function task ({ payload }) { - WIKI.logger.info(`Rendering page ${payload.id}...`) - - try { - await WIKI.ensureDb() - - const page = await WIKI.db.pages.getPageFromDb(payload.id) - if (!page) { - throw new Error('Invalid Page Id') - } - - const site = await WIKI.db.sites.query().findById(page.siteId) - - let output = page.content - - // Empty content? - if (isEmpty(output)) { - WIKI.logger.warn(`Failed to render page ID ${payload.id} because content was empty: [ FAILED ]`) - throw new Error(`Failed to render page ID ${payload.id} because content was empty.`) - } - - // Parse to HTML - switch (page.contentType) { - case 'asciidoc': { - const { render } = await import('../../renderers/asciidoc.mjs') - output = await render(output, site.config?.editors?.asciidoc?.config ?? {}) - break - } - case 'markdown': { - const { render } = await import('../../renderers/markdown.mjs') - output = await render(output, site.config?.editors?.markdown?.config ?? {}) - break - } - } - - // Render HTML - await WIKI.db.renderers.fetchDefinitions() - const pipeline = await WIKI.db.renderers.getRenderingPipeline(page.contentType) - - for (const core of pipeline) { - const { render } = (await import(`../../modules/rendering/${core.key}/renderer.mjs`)) - output = await render.call({ - config: core.config, - children: core.children, - page, - site, - input: output - }) - } - - // Parse TOC - // const $ = cheerio.load(output) - // let isStrict = $('h1').length > 0 // <- Allows for documents using H2 as top level - let toc = { root: [] } - - // $('h1,h2,h3,h4,h5,h6').each((idx, el) => { - // const depth = toSafeInteger(el.name.substring(1)) - (isStrict ? 1 : 2) - // let leafPathError = false - - // const leafPath = reduce(times(depth), (curPath, curIdx) => { - // if (has(toc, curPath)) { - // const lastLeafIdx = get(toc, curPath).length - 1 - // if (lastLeafIdx >= 0) { - // curPath = `${curPath}[${lastLeafIdx}].children` - // } else { - // leafPathError = true - // } - // } - // return curPath - // }, 'root') - - // if (leafPathError) { return } - - // const leafSlug = $('.toc-anchor', el).first().attr('href') - // $('.toc-anchor', el).remove() - - // get(toc, leafPath).push({ - // label: $(el).text().trim(), - // key: leafSlug.substring(1), - // children: [] - // }) - // }) - - // Save to DB - await WIKI.db.pages.query() - .patch({ - render: output, - toc: JSON.stringify(toc.root) - }) - .where('id', payload.id) - - // Save to cache - // await WIKI.db.pages.savePageToCache({ - // ...page, - // render: output, - // toc: JSON.stringify(toc.root) - // }) - - WIKI.logger.info(`Rendered page ${payload.id}: [ COMPLETED ]`) - } catch (err) { - WIKI.logger.error(`Rendering page ${payload.id}: [ FAILED ]`) - WIKI.logger.error(err.message) - throw err - } -} diff --git a/server/templates/demo/home.md b/server/templates/demo/home.md deleted file mode 100644 index 86e2f4ea8..000000000 --- a/server/templates/demo/home.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Home -description: Welcome to your wiki! -published: true ---- - -Feel free to modify this page (or delete it!). - -## Next Steps - -- Configure your wiki in the [Administration Area](/_admin). -- [Modify your profile](/_profile) to set preferences or change your password. -- Create new pages by clicking the + button in the upper right corner. -- Edit the navigation by clicking the Edit Nav button in the lower left corner. - -## Read the documentation - -How do permissions work? How can I make my wiki publicly accessible? - -It's all [in the docs](https://beta.js.wiki/docs/admin/groups)! - -## Example Blocks - -Did you know that you can insert dynamic [blocks](https://beta.js.wiki/docs/editor/blocks)? - -For example, here are the 5 most recently updated pages on your wiki: - -::block-index{orderBy="updatedAt" orderByDirection="desc" limit="5"} -:: - -This list will automatically update as you create / edit pages. diff --git a/server/templates/mail/Test.vue b/server/templates/mail/Test.vue deleted file mode 100644 index 0dad6cf1e..000000000 --- a/server/templates/mail/Test.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - diff --git a/server/templates/mail/UserWelcome.vue b/server/templates/mail/UserWelcome.vue deleted file mode 100644 index 4497cf682..000000000 --- a/server/templates/mail/UserWelcome.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - diff --git a/server/web.mjs b/server/web.mjs deleted file mode 100644 index 5b5aefa41..000000000 --- a/server/web.mjs +++ /dev/null @@ -1,272 +0,0 @@ -import compression from 'compression' -import cookieParser from 'cookie-parser' -import cors from 'cors' -import express from 'express' -import session from 'express-session' -import { ConnectSessionKnexStore } from 'connect-session-knex' -import favicon from 'serve-favicon' -import path from 'node:path' -import { set } from 'lodash-es' - -import auth from './core/auth.mjs' -import mail from './core/mail.mjs' -import system from './core/system.mjs' - -import ctrlAuth from './controllers/auth.mjs' -import ctrlCommon from './controllers/common.mjs' -import ctrlSsl from './controllers/ssl.mjs' -import ctrlWs from './controllers/ws.mjs' - -export async function init () { - // ---------------------------------------- - // Load core modules - // ---------------------------------------- - - WIKI.auth = auth.init() - WIKI.mail = mail.init() - WIKI.system = system.init() - - // ---------------------------------------- - // Define Express App - // ---------------------------------------- - - const app = express() - WIKI.app = app - app.use(compression()) - - // ---------------------------------------- - // Initialize HTTP/HTTPS Server - // ---------------------------------------- - - const useHTTPS = WIKI.config.ssl.enabled === true || WIKI.config.ssl.enabled === 'true' || WIKI.config.ssl.enabled === 1 || WIKI.config.ssl.enabled === '1' - - await WIKI.servers.initHTTP() - if (useHTTPS) { - await WIKI.servers.initHTTPS() - } - await WIKI.servers.initWebSocket() - - // ---------------------------------------- - // Attach WebSocket Server - // ---------------------------------------- - - ctrlWs() - - // ---------------------------------------- - // Security - // ---------------------------------------- - - app.use((req, res, next) => { - // -> Disable X-Powered-By - req.app.disable('x-powered-by') - - // -> Disable Frame Embedding - if (WIKI.config.security.securityIframe) { - res.set('X-Frame-Options', 'deny') - } - - // -> Re-enable XSS Fitler if disabled - res.set('X-XSS-Protection', '1; mode=block') - - // -> Disable MIME-sniffing - res.set('X-Content-Type-Options', 'nosniff') - - // -> Disable IE Compatibility Mode - res.set('X-UA-Compatible', 'IE=edge') - - // -> Disables referrer header when navigating to a different origin - if (WIKI.config.security.securityReferrerPolicy) { - res.set('Referrer-Policy', 'same-origin') - } - - // -> Enforce HSTS - if (WIKI.config.security.securityHSTS) { - res.set('Strict-Transport-Security', `max-age=${WIKI.config.security.securityHSTSDuration}; includeSubDomains`) - } - - // -> Prevent Open Redirect from user provided URL - if (WIKI.config.security.securityOpenRedirect) { - // Strips out all repeating / character in the provided URL - req.url = req.url.replace(/(\/)(?=\/*\1)/g, '') - } - - next() - }) - app.use(cors({ origin: false })) - app.options('/{*splat}', cors({ origin: false })) - if (WIKI.config.security.securityTrustProxy) { - app.enable('trust proxy') - } - - // ---------------------------------------- - // Public Assets - // ---------------------------------------- - - app.use(favicon(path.join(WIKI.ROOTPATH, 'assets', 'favicon.ico'))) - app.use('/_assets', express.static(path.join(WIKI.ROOTPATH, 'assets/_assets'), { - index: false, - maxAge: '7d' - })) - app.use('/_assets/svg/twemoji', async (req, res, next) => { - try { - WIKI.asar.serve('twemoji', req, res, next) - } catch (err) { - res.sendStatus(404) - } - }) - - // ---------------------------------------- - // Blocks - // ---------------------------------------- - - app.use('/_blocks', express.static(path.join(WIKI.ROOTPATH, 'blocks/compiled'), { - index: false, - maxAge: '7d' - })) - - // ---------------------------------------- - // SSL Handlers - // ---------------------------------------- - - app.use('/', ctrlSsl()) - - // ---------------------------------------- - // Passport Authentication - // ---------------------------------------- - - app.use(cookieParser()) - app.use(session({ - secret: WIKI.config.auth.secret, - resave: false, - saveUninitialized: false, - store: new ConnectSessionKnexStore({ - knex: WIKI.db.knex - }) - })) - app.use(WIKI.auth.passport.initialize()) - app.use(WIKI.auth.authenticate) - - // ---------------------------------------- - // GraphQL Server - // ---------------------------------------- - - app.use(express.json({ limit: WIKI.config.bodyParserLimit || '5mb' })) - await WIKI.servers.startGraphQL() - - // ---------------------------------------- - // SEO - // ---------------------------------------- - - app.use((req, res, next) => { - if (req.path.length > 1 && req.path.endsWith('/')) { - const query = req.url.slice(req.path.length) || '' - res.redirect(301, req.path.slice(0, -1) + query) - } else { - set(res.locals, 'pageMeta.url', `${WIKI.config.host}${req.path}`) - next() - } - }) - - // ---------------------------------------- - // View Engine Setup - // ---------------------------------------- - - app.set('views', path.join(WIKI.SERVERPATH, 'views')) - - app.use(express.urlencoded({ extended: false, limit: '1mb' })) - - // ---------------------------------------- - // View accessible data - // ---------------------------------------- - - app.locals.analyticsCode = {} - app.locals.basedir = WIKI.ROOTPATH - app.locals.config = WIKI.config - app.locals.pageMeta = { - title: '', - description: WIKI.config.description, - image: '', - url: '/' - } - app.locals.devMode = WIKI.devMode - - // ---------------------------------------- - // HMR (Dev Mode Only) - // ---------------------------------------- - - if (global.DEV) { - app.use(global.WP_DEV.devMiddleware) - app.use(global.WP_DEV.hotMiddleware) - } - - // ---------------------------------------- - // Routing - // ---------------------------------------- - - app.use(async (req, res, next) => { - const currentSite = await WIKI.db.sites.getSiteByHostname({ hostname: req.hostname }) - if (!currentSite) { - return res.status(404).send('Site Not Found') - } - - res.locals.siteConfig = { - id: currentSite.id, - title: currentSite.config.title, - darkMode: currentSite.config.theme.dark, - lang: currentSite.config.locales.primary, - rtl: false, // TODO: handle RTL - company: currentSite.config.company, - contentLicense: currentSite.config.contentLicense - } - res.locals.theming = { - - } - res.locals.langs = await WIKI.db.locales.getNavLocales({ cache: true }) - res.locals.analyticsCode = await WIKI.db.analytics.getCode({ cache: true }) - next() - }) - - app.use('/', ctrlAuth()) - app.use('/', ctrlCommon()) - - // ---------------------------------------- - // Error handling - // ---------------------------------------- - - app.use((req, res, next) => { - const err = new Error('Not Found') - err.status = 404 - next(err) - }) - - app.use((err, req, res, next) => { - if (req.path === '/_graphql') { - res.status(err.status || 500).json({ - data: {}, - errors: [{ - message: err.message, - path: [] - }] - }) - } else { - res.status(err.status || 500) - set(res.locals, 'pageMeta.title', 'Error') - res.render('error', { - message: err.message, - error: WIKI.IS_DEBUG ? err : {} - }) - } - }) - - // ---------------------------------------- - // Start HTTP Server(s) - // ---------------------------------------- - - await WIKI.servers.startHTTP() - - if (useHTTPS) { - await WIKI.servers.startHTTPS() - } - - return true -} diff --git a/server/worker.mjs b/server/worker.mjs deleted file mode 100644 index 42efd918e..000000000 --- a/server/worker.mjs +++ /dev/null @@ -1,54 +0,0 @@ -import { ThreadWorker } from 'poolifier' -import { kebabCase } from 'lodash-es' -import path from 'node:path' -import configSvc from './core/config.mjs' -import logger from './core/logger.mjs' -import db from './core/db.mjs' - -// ---------------------------------------- -// Init Minimal Core -// ---------------------------------------- - -const WIKI = { - IS_DEBUG: process.env.NODE_ENV === 'development', - ROOTPATH: process.cwd(), - INSTANCE_ID: 'worker', - SERVERPATH: path.join(process.cwd(), 'server'), - configSvc, - ensureDb: async () => { - if (WIKI.db) { return true } - - WIKI.db = await db.init(true) - - try { - await WIKI.configSvc.loadFromDb() - await WIKI.configSvc.applyFlags() - } catch (err) { - WIKI.logger.error('Database Initialization Error: ' + err.message) - if (WIKI.IS_DEBUG) { - WIKI.logger.error(err) - } - process.exit(1) - } - } -} -global.WIKI = WIKI - -await WIKI.configSvc.init(true) - -// ---------------------------------------- -// Init Logger -// ---------------------------------------- - -WIKI.logger = logger.init() - -// ---------------------------------------- -// Execute Task -// ---------------------------------------- - -export default new ThreadWorker(async (job) => { - WIKI.INSTANCE_ID = job.INSTANCE_ID - const task = (await import(`./tasks/workers/${kebabCase(job.task)}.mjs`)).task - await task(job) - return true -}) diff --git a/ux/.editorconfig b/ux/.editorconfig deleted file mode 100644 index 9d08a1a82..000000000 --- a/ux/.editorconfig +++ /dev/null @@ -1,9 +0,0 @@ -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true diff --git a/ux/.gitignore b/ux/.gitignore deleted file mode 100644 index a37d7e077..000000000 --- a/ux/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -.DS_Store -.thumbs.db -node_modules - -# Quasar core related directories -.quasar -/dist -/quasar.config.*.temporary.compiled* - -# local .env files -.env.local* - -# Cordova related directories and files -/src-cordova/node_modules -/src-cordova/platforms -/src-cordova/plugins -/src-cordova/www - -# Capacitor related directories and files -/src-capacitor/www -/src-capacitor/node_modules - -# Log files -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Editor directories and files -.idea -*.suo -*.ntvs* -*.njsproj -*.sln - -# Yarn -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions diff --git a/ux/.npmrc b/ux/.npmrc deleted file mode 100644 index 34629cc4e..000000000 --- a/ux/.npmrc +++ /dev/null @@ -1,5 +0,0 @@ -audit = false -fund = false -save-exact = true -save-prefix = "" -shamefully-hoist = true diff --git a/ux/.vscode/extensions.json b/ux/.vscode/extensions.json deleted file mode 100644 index df0976dc9..000000000 --- a/ux/.vscode/extensions.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "recommendations": [ - "dbaeumer.vscode-eslint", - "editorconfig.editorconfig", - "johnsoncodehk.volar", - "wayou.vscode-todo-highlight" - ], - "unwantedRecommendations": [ - "octref.vetur", - "hookyqr.beautify", - "dbaeumer.jshint", - "ms-vscode.vscode-typescript-tslint-plugin" - ] -} \ No newline at end of file diff --git a/ux/.vscode/settings.json b/ux/.vscode/settings.json deleted file mode 100644 index f39da49b9..000000000 --- a/ux/.vscode/settings.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "editor.bracketPairColorization.enabled": true, - "editor.guides.bracketPairs": true, - "editor.formatOnSave": true, - "editor.defaultFormatter": "dbaeumer.vscode-eslint", - "editor.codeActionsOnSave": [ - "source.fixAll.eslint" - ], - "eslint.validate": [ - "javascript", - "javascriptreact", - "typescript", - "vue" - ], - "i18n-ally.localesPaths": "src/i18n/locales" -} diff --git a/ux/apollo.config.js b/ux/apollo.config.js deleted file mode 100644 index 4a3ed47f6..000000000 --- a/ux/apollo.config.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - client: { - service: { - name: 'wiki-core', - // URL to the GraphQL API - url: 'http://localhost:11511' - }, - // Files processed by the extension - includes: [ - 'src/**/*.vue', - 'src/**/*.js' - ] - } -} diff --git a/ux/eslint.config.mjs b/ux/eslint.config.mjs deleted file mode 100644 index 196e2d69a..000000000 --- a/ux/eslint.config.mjs +++ /dev/null @@ -1,73 +0,0 @@ -import js from '@eslint/js' -import neostandard from 'neostandard' -import pluginVue from 'eslint-plugin-vue' -import pluginVuePug from 'eslint-plugin-vue-pug' -import vueParser from 'vue-eslint-parser' -import { FlatCompat } from '@eslint/eslintrc' - -const compat = new FlatCompat() - -export default [ - js.configs.recommended, - ...pluginVue.configs['flat/essential'], - ...pluginVuePug.configs['flat/recommended'], - ...neostandard(), - { - ignores: [ - '/dist', - '/.quasar', - '/node_modules' - ], - languageOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - parser: vueParser, - globals: { - __statics: 'readonly', - __QUASAR_SSR__: 'readonly', - __QUASAR_SSR_SERVER__: 'readonly', - __QUASAR_SSR_CLIENT__: 'readonly', - __QUASAR_SSR_PWA__: 'readonly', - process: 'readonly', - Capacitor: 'readonly', - chrome: 'readonly', - APOLLO_CLIENT: 'readonly', - EVENT_BUS: 'readonly' - } - }, - rules: { - // allow async-await - 'generator-star-spacing': 'off', - // allow paren-less arrow functions - 'arrow-parens': 'off', - 'one-var': 'off', - 'no-void': 'off', - 'multiline-ternary': 'off', - - 'import/first': 'off', - 'import/named': 'error', - 'import/namespace': 'error', - 'import/default': 'error', - 'import/export': 'error', - 'import/extensions': 'off', - 'import/no-unresolved': 'off', - 'import/no-extraneous-dependencies': 'off', - - 'prefer-promise-reject-errors': 'off', - - 'no-unused-vars': 'off', - 'vue/multi-word-component-names': 'off', - - // allow debugger during development only - 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', - - // disable bogus rules - 'vue/valid-template-root': 'off', - 'vue/no-parsing-error': 'off', - 'vue-pug/no-parsing-error': 'off', - 'vue/valid-v-for': 'off', - 'vue/html-quotes': ['warn', 'single'], - 'vue/max-attributes-per-line': 'off' - } - } -] diff --git a/ux/index.html b/ux/index.html deleted file mode 100644 index dcba3bf0b..000000000 --- a/ux/index.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - Wiki.js - - - - - - - -
    -
    - - - diff --git a/ux/jsconfig.json b/ux/jsconfig.json deleted file mode 100644 index 940c19739..000000000 --- a/ux/jsconfig.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "jsx": "preserve", - "paths": { - "src/*": [ - "src/*" - ], - "app/*": [ - "*" - ], - "components/*": [ - "src/components/*" - ], - "layouts/*": [ - "src/layouts/*" - ], - "pages/*": [ - "src/pages/*" - ], - "assets/*": [ - "src/assets/*" - ], - "boot/*": [ - "src/boot/*" - ], - "stores/*": [ - "src/stores/*" - ], - "vue$": [ - "node_modules/vue/dist/vue.runtime.esm-bundler.js" - ] - } - }, - "exclude": [ - "dist", - ".quasar", - "node_modules" - ], - "vueCompilerOptions": { - "target": 3, - "plugins": [ - "@vue/language-plugin-pug" - ] - } -} diff --git a/ux/package.json b/ux/package.json deleted file mode 100644 index 291ac4d70..000000000 --- a/ux/package.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "name": "wiki-ux", - "version": "3.0.0", - "description": "The most powerful and extensible open source Wiki software", - "productName": "Wiki.js", - "author": "Nicolas Giard ", - "private": true, - "type": "module", - "scripts": { - "dev": "vite --force", - "build": "NODE_OPTIONS=--max-old-space-size=8192 vite build --emptyOutDir" - }, - "dependencies": { - "@apollo/client": "3.13.8", - "@lezer/common": "1.2.3", - "@mdi/font": "7.4.47", - "@quasar/extras": "1.17.0", - "@simplewebauthn/browser": "13.1.2", - "@tiptap/core": "2.11.5", - "@tiptap/extension-code-block": "2.11.5", - "@tiptap/extension-code-block-lowlight": "2.11.5", - "@tiptap/extension-color": "2.11.5", - "@tiptap/extension-dropcursor": "2.11.5", - "@tiptap/extension-font-family": "2.11.5", - "@tiptap/extension-gapcursor": "2.11.5", - "@tiptap/extension-hard-break": "2.11.5", - "@tiptap/extension-highlight": "2.11.5", - "@tiptap/extension-history": "2.11.5", - "@tiptap/extension-image": "2.11.5", - "@tiptap/extension-mention": "2.11.5", - "@tiptap/extension-placeholder": "2.11.5", - "@tiptap/extension-table": "2.11.5", - "@tiptap/extension-table-cell": "2.11.5", - "@tiptap/extension-table-header": "2.11.5", - "@tiptap/extension-table-row": "2.11.5", - "@tiptap/extension-task-item": "2.11.5", - "@tiptap/extension-task-list": "2.11.5", - "@tiptap/extension-text-align": "2.11.5", - "@tiptap/extension-text-style": "2.11.5", - "@tiptap/extension-typography": "2.11.5", - "@tiptap/pm": "2.11.5", - "@tiptap/starter-kit": "2.11.5", - "@tiptap/vue-3": "2.11.5", - "@vue/repl": "3.4.0", - "@xterm/xterm": "5.5.0", - "apollo-upload-client": "18.0.1", - "browser-fs-access": "0.38.0", - "clipboard": "2.0.11", - "codemirror": "5.65.11", - "codemirror-asciidoc": "1.0.4", - "dependency-graph": "1.0.0", - "filesize": "11.0.2", - "filesize-parser": "1.5.1", - "fuse.js": "7.1.0", - "graphql": "16.11.0", - "graphql-tag": "2.12.6", - "highlight.js": "11.11.1", - "js-cookie": "3.0.5", - "jwt-decode": "4.0.0", - "katex": "0.16.22", - "lodash-es": "4.17.21", - "lowlight": "3.3.0", - "luxon": "3.7.1", - "markdown-it": "14.1.0", - "markdown-it-abbr": "2.0.0", - "markdown-it-attrs": "4.3.1", - "markdown-it-decorate": "1.2.2", - "markdown-it-emoji": "3.0.0", - "markdown-it-expand-tabs": "1.0.13", - "markdown-it-footnote": "4.0.0", - "markdown-it-imsize": "2.0.1", - "markdown-it-mark": "4.0.0", - "markdown-it-mdc": "0.2.6", - "markdown-it-multimd-table": "4.2.3", - "markdown-it-sub": "2.0.0", - "markdown-it-sup": "2.0.0", - "markdown-it-task-lists": "2.1.1", - "mitt": "3.0.1", - "monaco-editor": "0.52.2", - "pako": "2.1.0", - "pinia": "3.0.3", - "prosemirror-commands": "1.7.1", - "prosemirror-history": "1.4.1", - "prosemirror-keymap": "1.2.3", - "prosemirror-model": "1.25.2", - "prosemirror-schema-list": "1.5.1", - "prosemirror-state": "1.4.3", - "prosemirror-transform": "1.10.4", - "prosemirror-view": "1.40.1", - "pug": "3.0.3", - "quasar": "2.18.2", - "slugify": "1.6.6", - "socket.io-client": "4.8.1", - "sortablejs": "1.15.6", - "sortablejs-vue3": "1.2.11", - "tabulator-tables": "6.3.1", - "tippy.js": "6.3.7", - "twemoji": "14.0.2", - "typescript": "5.8.3", - "uuid": "11.1.0", - "v-network-graph": "0.9.21", - "vue": "3.5.18", - "vue-i18n": "11.1.11", - "vue-router": "4.5.1", - "vue3-otp-input": "0.5.40", - "vuedraggable": "4.1.0", - "zxcvbn": "4.4.2" - }, - "devDependencies": { - "@eslint/js": "9.32.0", - "@intlify/unplugin-vue-i18n": "6.0.8", - "@quasar/app-vite": "2.3.0", - "@quasar/vite-plugin": "1.10.0", - "@types/lodash": "4.17.20", - "@vue/language-plugin-pug": "3.0.4", - "autoprefixer": "10.4.21", - "browserlist": "latest", - "eslint": "9.32.0", - "eslint-plugin-import": "2.32.0", - "eslint-plugin-n": "17.21.2", - "eslint-plugin-promise": "7.2.1", - "eslint-plugin-vue": "10.3.0", - "eslint-plugin-vue-pug": "1.0.0-alpha.3", - "neostandard": "0.12.2", - "sass": "1.89.2", - "vite-plugin-vue-devtools": "8.0.0" - }, - "engines": { - "node": ">= 18.0", - "npm": ">= 6.13.4" - }, - "overrides": { - "typescript": "5.8.2" - }, - "packageManager": "pnpm@9.12.2+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228" -} diff --git a/ux/pnpm-lock.yaml b/ux/pnpm-lock.yaml deleted file mode 100644 index 1dab0f3ae..000000000 --- a/ux/pnpm-lock.yaml +++ /dev/null @@ -1,9439 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@apollo/client': - specifier: 3.13.8 - version: 3.13.8(graphql@16.11.0) - '@lezer/common': - specifier: 1.2.3 - version: 1.2.3 - '@mdi/font': - specifier: 7.4.47 - version: 7.4.47 - '@quasar/extras': - specifier: 1.17.0 - version: 1.17.0 - '@simplewebauthn/browser': - specifier: 13.1.2 - version: 13.1.2 - '@tiptap/core': - specifier: 2.11.5 - version: 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/extension-code-block': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-code-block-lowlight': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/extension-code-block@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)(highlight.js@11.11.1)(lowlight@3.3.0) - '@tiptap/extension-color': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/extension-text-style@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))) - '@tiptap/extension-dropcursor': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-font-family': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/extension-text-style@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))) - '@tiptap/extension-gapcursor': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-hard-break': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-highlight': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-history': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-image': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-mention': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)(@tiptap/suggestion@2.8.0(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)) - '@tiptap/extension-placeholder': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-table': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-table-cell': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-table-header': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-table-row': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-task-item': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-task-list': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-text-align': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-text-style': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-typography': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/pm': - specifier: 2.11.5 - version: 2.11.5 - '@tiptap/starter-kit': - specifier: 2.11.5 - version: 2.11.5 - '@tiptap/vue-3': - specifier: 2.11.5 - version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)(vue@3.5.18(typescript@5.8.3)) - '@vue/repl': - specifier: 3.4.0 - version: 3.4.0 - '@xterm/xterm': - specifier: 5.5.0 - version: 5.5.0 - apollo-upload-client: - specifier: 18.0.1 - version: 18.0.1(@apollo/client@3.13.8(graphql@16.11.0))(graphql@16.11.0) - browser-fs-access: - specifier: 0.38.0 - version: 0.38.0 - clipboard: - specifier: 2.0.11 - version: 2.0.11 - codemirror: - specifier: 5.65.11 - version: 5.65.11 - codemirror-asciidoc: - specifier: 1.0.4 - version: 1.0.4 - dependency-graph: - specifier: 1.0.0 - version: 1.0.0 - filesize: - specifier: 11.0.2 - version: 11.0.2 - filesize-parser: - specifier: 1.5.1 - version: 1.5.1 - fuse.js: - specifier: 7.1.0 - version: 7.1.0 - graphql: - specifier: 16.11.0 - version: 16.11.0 - graphql-tag: - specifier: 2.12.6 - version: 2.12.6(graphql@16.11.0) - highlight.js: - specifier: 11.11.1 - version: 11.11.1 - js-cookie: - specifier: 3.0.5 - version: 3.0.5 - jwt-decode: - specifier: 4.0.0 - version: 4.0.0 - katex: - specifier: 0.16.22 - version: 0.16.22 - lodash-es: - specifier: 4.17.21 - version: 4.17.21 - lowlight: - specifier: 3.3.0 - version: 3.3.0 - luxon: - specifier: 3.7.1 - version: 3.7.1 - markdown-it: - specifier: 14.1.0 - version: 14.1.0 - markdown-it-abbr: - specifier: 2.0.0 - version: 2.0.0 - markdown-it-attrs: - specifier: 4.3.1 - version: 4.3.1(markdown-it@14.1.0) - markdown-it-decorate: - specifier: 1.2.2 - version: 1.2.2 - markdown-it-emoji: - specifier: 3.0.0 - version: 3.0.0 - markdown-it-expand-tabs: - specifier: 1.0.13 - version: 1.0.13 - markdown-it-footnote: - specifier: 4.0.0 - version: 4.0.0 - markdown-it-imsize: - specifier: 2.0.1 - version: 2.0.1 - markdown-it-mark: - specifier: 4.0.0 - version: 4.0.0 - markdown-it-mdc: - specifier: 0.2.6 - version: 0.2.6(@types/markdown-it@14.1.2)(markdown-it@14.1.0) - markdown-it-multimd-table: - specifier: 4.2.3 - version: 4.2.3 - markdown-it-sub: - specifier: 2.0.0 - version: 2.0.0 - markdown-it-sup: - specifier: 2.0.0 - version: 2.0.0 - markdown-it-task-lists: - specifier: 2.1.1 - version: 2.1.1 - mitt: - specifier: 3.0.1 - version: 3.0.1 - monaco-editor: - specifier: 0.52.2 - version: 0.52.2 - pako: - specifier: 2.1.0 - version: 2.1.0 - pinia: - specifier: 3.0.3 - version: 3.0.3(typescript@5.8.3)(vue@3.5.18(typescript@5.8.3)) - prosemirror-commands: - specifier: 1.7.1 - version: 1.7.1 - prosemirror-history: - specifier: 1.4.1 - version: 1.4.1 - prosemirror-keymap: - specifier: 1.2.3 - version: 1.2.3 - prosemirror-model: - specifier: 1.25.2 - version: 1.25.2 - prosemirror-schema-list: - specifier: 1.5.1 - version: 1.5.1 - prosemirror-state: - specifier: 1.4.3 - version: 1.4.3 - prosemirror-transform: - specifier: 1.10.4 - version: 1.10.4 - prosemirror-view: - specifier: 1.40.1 - version: 1.40.1 - pug: - specifier: 3.0.3 - version: 3.0.3 - quasar: - specifier: 2.18.2 - version: 2.18.2 - slugify: - specifier: 1.6.6 - version: 1.6.6 - socket.io-client: - specifier: 4.8.1 - version: 4.8.1 - sortablejs: - specifier: 1.15.6 - version: 1.15.6 - sortablejs-vue3: - specifier: 1.2.11 - version: 1.2.11(sortablejs@1.15.6)(vue@3.5.18(typescript@5.8.3)) - tabulator-tables: - specifier: 6.3.1 - version: 6.3.1 - tippy.js: - specifier: 6.3.7 - version: 6.3.7 - twemoji: - specifier: 14.0.2 - version: 14.0.2 - typescript: - specifier: 5.8.3 - version: 5.8.3 - uuid: - specifier: 11.1.0 - version: 11.1.0 - v-network-graph: - specifier: 0.9.21 - version: 0.9.21(vue@3.5.18(typescript@5.8.3)) - vue: - specifier: 3.5.18 - version: 3.5.18(typescript@5.8.3) - vue-i18n: - specifier: 11.1.11 - version: 11.1.11(vue@3.5.18(typescript@5.8.3)) - vue-router: - specifier: 4.5.1 - version: 4.5.1(vue@3.5.18(typescript@5.8.3)) - vue3-otp-input: - specifier: 0.5.40 - version: 0.5.40(vue@3.5.18(typescript@5.8.3)) - vuedraggable: - specifier: 4.1.0 - version: 4.1.0(vue@3.5.18(typescript@5.8.3)) - zxcvbn: - specifier: 4.4.2 - version: 4.4.2 - devDependencies: - '@eslint/js': - specifier: 9.32.0 - version: 9.32.0 - '@intlify/unplugin-vue-i18n': - specifier: 6.0.8 - version: 6.0.8(@vue/compiler-dom@3.5.18)(eslint@9.32.0)(rollup@4.45.3)(typescript@5.8.3)(vue-i18n@11.1.11(vue@3.5.18(typescript@5.8.3)))(vue@3.5.18(typescript@5.8.3)) - '@quasar/app-vite': - specifier: 2.3.0 - version: 2.3.0(@types/node@24.1.0)(eslint@9.32.0)(pinia@3.0.3(typescript@5.8.3)(vue@3.5.18(typescript@5.8.3)))(quasar@2.18.2)(rollup@4.45.3)(sass@1.89.2)(terser@5.43.1)(typescript@5.8.3)(vue-router@4.5.1(vue@3.5.18(typescript@5.8.3)))(vue@3.5.18(typescript@5.8.3))(yaml@2.8.0) - '@quasar/vite-plugin': - specifier: 1.10.0 - version: 1.10.0(@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)))(quasar@2.18.2)(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)) - '@types/lodash': - specifier: 4.17.20 - version: 4.17.20 - '@vue/language-plugin-pug': - specifier: 3.0.4 - version: 3.0.4 - autoprefixer: - specifier: 10.4.21 - version: 10.4.21(postcss@8.5.6) - browserlist: - specifier: latest - version: 1.0.1 - eslint: - specifier: 9.32.0 - version: 9.32.0 - eslint-plugin-import: - specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0) - eslint-plugin-n: - specifier: 17.21.2 - version: 17.21.2(eslint@9.32.0)(typescript@5.8.3) - eslint-plugin-promise: - specifier: 7.2.1 - version: 7.2.1(eslint@9.32.0) - eslint-plugin-vue: - specifier: 10.3.0 - version: 10.3.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(vue-eslint-parser@10.1.1(eslint@9.32.0)) - eslint-plugin-vue-pug: - specifier: 1.0.0-alpha.3 - version: 1.0.0-alpha.3(eslint-plugin-vue@10.3.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(vue-eslint-parser@10.1.1(eslint@9.32.0)))(vue-eslint-parser@10.1.1(eslint@9.32.0)) - neostandard: - specifier: 0.12.2 - version: 0.12.2(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0))(eslint@9.32.0)(typescript@5.8.3) - sass: - specifier: 1.89.2 - version: 1.89.2 - vite-plugin-vue-devtools: - specifier: 8.0.0 - version: 8.0.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)) - -packages: - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@apollo/client@3.13.8': - resolution: {integrity: sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg==} - peerDependencies: - graphql: ^15.0.0 || ^16.0.0 - graphql-ws: ^5.5.5 || ^6.0.3 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc - subscriptions-transport-ws: ^0.9.0 || ^0.11.0 - peerDependenciesMeta: - graphql-ws: - optional: true - react: - optional: true - react-dom: - optional: true - subscriptions-transport-ws: - optional: true - - '@babel/code-frame@7.27.1': - resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.28.0': - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.28.0': - resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.28.0': - resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-annotate-as-pure@7.27.3': - resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.27.1': - resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-member-expression-to-functions@7.27.1': - resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.27.3': - resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-optimise-call-expression@7.27.1': - resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-replace-supers@7.27.1': - resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.24.8': - resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.24.7': - resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.28.2': - resolution: {integrity: sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.24.8': - resolution: {integrity: sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/parser@7.28.0': - resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-proposal-decorators@7.28.0': - resolution: {integrity: sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-decorators@7.27.1': - resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.27.1': - resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.27.1': - resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.27.1': - resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typescript@7.28.0': - resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.27.2': - resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.28.0': - resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.24.8': - resolution: {integrity: sha512-SkSBEHwwJRU52QEVZBmMBnE5Ux2/6WU1grdYyOhpbCNxbmJrDuDCphBzKZSO3taf0zztp+qkWlymE5tVL5l0TA==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} - engines: {node: '>=6.9.0'} - - '@bufbuild/protobuf@2.6.2': - resolution: {integrity: sha512-vLu7SRY84CV/Dd+NUdgtidn2hS5hSMUC1vDBY0VcviTdgRYkU43vIz3vIFbmx14cX1r+mM7WjzE5Fl1fGEM0RQ==} - - '@dash14/svg-pan-zoom@3.6.9': - resolution: {integrity: sha512-6u+KTQec+9+3bRdk2mReix8AGsp2mB40cw0iYfQQzo22QBkeCNpXl2amnfwQzK7xB9oH/62Wvf2z7l6l2w+csA==} - - '@emnapi/core@1.4.5': - resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} - - '@emnapi/runtime@1.4.5': - resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} - - '@emnapi/wasi-threads@1.0.4': - resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} - - '@esbuild/aix-ppc64@0.25.8': - resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.25.8': - resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.25.8': - resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.25.8': - resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.25.8': - resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.8': - resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.25.8': - resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.8': - resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.25.8': - resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.25.8': - resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.25.8': - resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.25.8': - resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.25.8': - resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.25.8': - resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.8': - resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.25.8': - resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.25.8': - resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.25.8': - resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.8': - resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.8': - resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.8': - resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.25.8': - resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.25.8': - resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.25.8': - resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.25.8': - resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.25.8': - resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.4.1': - resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.3.0': - resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.15.1': - resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.32.0': - resolution: {integrity: sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.3.4': - resolution: {integrity: sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@graphql-typed-document-node/core@3.2.0': - resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/gitignore-to-minimatch@1.0.2': - resolution: {integrity: sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@inquirer/figures@1.0.13': - resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} - engines: {node: '>=18'} - - '@intlify/bundle-utils@10.0.1': - resolution: {integrity: sha512-WkaXfSevtpgtUR4t8K2M6lbR7g03mtOxFeh+vXp5KExvPqS12ppaRj1QxzwRuRI5VUto54A22BjKoBMLyHILWQ==} - engines: {node: '>= 18'} - peerDependencies: - petite-vue-i18n: '*' - vue-i18n: '*' - peerDependenciesMeta: - petite-vue-i18n: - optional: true - vue-i18n: - optional: true - - '@intlify/core-base@11.1.11': - resolution: {integrity: sha512-1Z0N8jTfkcD2Luq9HNZt+GmjpFe4/4PpZF3AOzoO1u5PTtSuXZcfhwBatywbfE2ieB/B5QHIoOFmCXY2jqVKEQ==} - engines: {node: '>= 16'} - - '@intlify/message-compiler@11.1.11': - resolution: {integrity: sha512-7PC6neomoc/z7a8JRjPBbu0T2TzR2MQuY5kn2e049MP7+o32Ve7O8husylkA7K9fQRe4iNXZWTPnDJ6vZdtS1Q==} - engines: {node: '>= 16'} - - '@intlify/shared@11.1.11': - resolution: {integrity: sha512-RIBFTIqxZSsxUqlcyoR7iiC632bq7kkOwYvZlvcVObHfrF4NhuKc4FKvu8iPCrEO+e3XsY7/UVpfgzg+M7ETzA==} - engines: {node: '>= 16'} - - '@intlify/unplugin-vue-i18n@6.0.8': - resolution: {integrity: sha512-Vvm3KhjE6TIBVUQAk37rBiaYy2M5OcWH0ZcI1XKEsOTeN1o0bErk+zeuXmcrcMc/73YggfI8RoxOUz9EB/69JQ==} - engines: {node: '>= 18'} - peerDependencies: - petite-vue-i18n: '*' - vue: ^3.2.25 - vue-i18n: '*' - peerDependenciesMeta: - petite-vue-i18n: - optional: true - vue-i18n: - optional: true - - '@intlify/vue-i18n-extensions@8.0.0': - resolution: {integrity: sha512-w0+70CvTmuqbskWfzeYhn0IXxllr6mU+IeM2MU0M+j9OW64jkrvqY+pYFWrUnIIC9bEdij3NICruicwd5EgUuQ==} - engines: {node: '>= 18'} - peerDependencies: - '@intlify/shared': ^9.0.0 || ^10.0.0 || ^11.0.0 - '@vue/compiler-dom': ^3.0.0 - vue: ^3.0.0 - vue-i18n: ^9.0.0 || ^10.0.0 || ^11.0.0 - peerDependenciesMeta: - '@intlify/shared': - optional: true - '@vue/compiler-dom': - optional: true - vue: - optional: true - vue-i18n: - optional: true - - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@jridgewell/gen-mapping@0.3.12': - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/source-map@0.3.10': - resolution: {integrity: sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==} - - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - - '@jridgewell/trace-mapping@0.3.29': - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} - - '@lezer/common@1.2.3': - resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==} - - '@mdi/font@7.4.47': - resolution: {integrity: sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==} - - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@nolyfill/is-core-module@1.0.39': - resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} - engines: {node: '>=12.4.0'} - - '@parcel/watcher-android-arm64@2.5.1': - resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [android] - - '@parcel/watcher-darwin-arm64@2.5.1': - resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [darwin] - - '@parcel/watcher-darwin-x64@2.5.1': - resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [darwin] - - '@parcel/watcher-freebsd-x64@2.5.1': - resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [freebsd] - - '@parcel/watcher-linux-arm-glibc@2.5.1': - resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - - '@parcel/watcher-linux-arm-musl@2.5.1': - resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - - '@parcel/watcher-linux-arm64-glibc@2.5.1': - resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - - '@parcel/watcher-linux-arm64-musl@2.5.1': - resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - - '@parcel/watcher-linux-x64-glibc@2.5.1': - resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - - '@parcel/watcher-linux-x64-musl@2.5.1': - resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - - '@parcel/watcher-win32-arm64@2.5.1': - resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [win32] - - '@parcel/watcher-win32-ia32@2.5.1': - resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} - engines: {node: '>= 10.0.0'} - cpu: [ia32] - os: [win32] - - '@parcel/watcher-win32-x64@2.5.1': - resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [win32] - - '@parcel/watcher@2.5.1': - resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} - engines: {node: '>= 10.0.0'} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@polka/url@1.0.0-next.29': - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - - '@popperjs/core@2.11.8': - resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - - '@quasar/app-vite@2.3.0': - resolution: {integrity: sha512-AHMRa5cdZ/TmV9mJ0jg/fbTMaMtFDfxvOjuPHL75AH6cZHECkXZ7ndTdVM0mU3i6lYwWf8Rx5OEi/PCwAMYJng==} - engines: {node: ^30 || ^28 || ^26 || ^24 || ^22 || ^20 || ^18, npm: '>= 6.14.12', yarn: '>= 1.17.3'} - hasBin: true - peerDependencies: - '@electron/packager': '>= 18' - electron-builder: '>= 22' - eslint: '*' - pinia: ^2.0.0 || ^3.0.0 - quasar: ^2.16.0 - typescript: '>= 5.4' - vue: ^3.2.29 - vue-router: ^4.0.12 - workbox-build: '>= 6' - peerDependenciesMeta: - '@electron/packager': - optional: true - electron-builder: - optional: true - eslint: - optional: true - pinia: - optional: true - typescript: - optional: true - workbox-build: - optional: true - - '@quasar/extras@1.17.0': - resolution: {integrity: sha512-KqAHdSJfIDauiR1nJ8rqHWT0diqD0QradZKoVIZJAilHAvgwyPIY7MbyR2z4RIMkUIMUSqBZcbshMpEw+9A30w==} - - '@quasar/render-ssr-error@1.0.3': - resolution: {integrity: sha512-A8RF99q6/sOSe1Ighnh5syEIbliD3qUYEJd2HyfFyBPSMF+WYGXon5dmzg4nUoK662NgOggInevkDyBDJcZugg==} - engines: {node: '>= 16'} - - '@quasar/ssl-certificate@1.0.0': - resolution: {integrity: sha512-RhZF7rO76T7Ywer1/5lCe7xl3CIiXxSAH1xgwOj0wcHTityDxJqIN/5YIj6BxMvlFw8XkJDoB1udEQafoVFA4g==} - engines: {node: '>= 16'} - - '@quasar/vite-plugin@1.10.0': - resolution: {integrity: sha512-4PJoTclz4ZjAfyqe0+hlkKcFJt0e2NX3Ac3hy8ILqUPdtZ24nCo5/xEHvTxZGBQMKRPwwePbO8CVs4n9EKJEug==} - engines: {node: '>=20'} - peerDependencies: - '@vitejs/plugin-vue': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - quasar: ^2.16.0 - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - vue: ^3.0.0 - - '@remirror/core-constants@3.0.0': - resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} - - '@rollup/pluginutils@5.2.0': - resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.45.3': - resolution: {integrity: sha512-8oQkCTve4H4B4JpmD2FV7fV2ZPTxJHN//bRhCqPUU8v6c5APlxteAXyc7BFaEb4aGpUzrPLU4PoAcGhwmRzZTA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.45.3': - resolution: {integrity: sha512-StOsmdXHU2hx3UFTTs6yYxCSwSIgLsfjUBICXyWj625M32OOjakXlaZuGKL+jA3Nvv35+hMxrm/64eCoT07SYQ==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.45.3': - resolution: {integrity: sha512-6CfLF3eqKhCdhK0GUnR5ZS99OFz+dtOeB/uePznLKxjCsk5QjT/V0eSEBb4vj+o/ri3i35MseSEQHCLLAgClVw==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.45.3': - resolution: {integrity: sha512-QLWyWmAJG9elNTNLdcSXUT/M+J7DhEmvs1XPHYcgYkse3UHf9iWTJ+yTPlKMIetiQnNi+cNp+gY4gvjDpREfKw==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.45.3': - resolution: {integrity: sha512-ZOvBq+5nL0yrZIEo1eq6r7MPvkJ8kC1XATS/yHvcq3WbDNKNKBQ1uIF4hicyzDMoJt72G+sn1nKsFXpifZyRDA==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.45.3': - resolution: {integrity: sha512-AYvGR07wecEnyYSovyJ71pTOulbNvsrpRpK6i/IM1b0UGX1vFx51afYuPYPxnvE9aCl5xPnhQicEvdIMxClRgQ==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.45.3': - resolution: {integrity: sha512-Yx8Cp38tfRRToVLuIWzBHV25/QPzpUreOPIiUuNV7KahNPurYg2pYQ4l7aYnvpvklO1riX4643bXLvDsYSBIrA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.45.3': - resolution: {integrity: sha512-4dIYRNxlXGDKnO6qgcda6LxnObPO6r1OBU9HG8F9pAnHHLtfbiOqCzDvkeHknx+5mfFVH4tWOl+h+cHylwsPWA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.45.3': - resolution: {integrity: sha512-M6uVlWKmhLN7LguLDu6396K1W5IBlAaRonjlHQgc3s4dOGceu0FeBuvbXiUPYvup/6b5Ln7IEX7XNm68DN4vrg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.45.3': - resolution: {integrity: sha512-emaYiOTQJUd6fC9a6jcw9zIWtzaUiuBC+vomggaM4In2iOra/lA6IMHlqZqQZr08NYXrOPMVigreLMeSAwv3Uw==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loongarch64-gnu@4.45.3': - resolution: {integrity: sha512-3P77T5AQ4UfVRJSrTKLiUZDJ6XsxeP80027bp6mOFh8sevSD038mYuIYFiUtrSJxxgFb+NgRJFF9oIa0rlUsmg==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.45.3': - resolution: {integrity: sha512-/VPH3ZVeSlmCBPhZdx/+4dMXDjaGMhDsWOBo9EwSkGbw2+OAqaslL53Ao2OqCxR0GgYjmmssJ+OoG+qYGE7IBg==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.45.3': - resolution: {integrity: sha512-Hs5if0PjROl1MGMmZX3xMAIfqcGxQE2SJWUr/CpDQsOQn43Wq4IvXXxUMWtiY/BrzdqCCJlRgJ5DKxzS3qWkCw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.45.3': - resolution: {integrity: sha512-Qm0WOwh3Lk388+HJFl1ILGbd2iOoQf6yl4fdGqOjBzEA+5JYbLcwd+sGsZjs5pkt8Cr/1G42EiXmlRp9ZeTvFA==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.45.3': - resolution: {integrity: sha512-VJdknTaYw+TqXzlh9c7vaVMh/fV2sU8Khfk4a9vAdYXJawpjf6z3U1k7vDWx2IQ9ZOPoOPxgVpDfYOYhxD7QUA==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.45.3': - resolution: {integrity: sha512-SUDXU5YabLAMl86FpupSQQEWzVG8X0HM+Q/famnJusbPiUgQnTGuSxtxg4UAYgv1ZmRV1nioYYXsgtSokU/7+Q==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.45.3': - resolution: {integrity: sha512-ezmqknOUFgZMN6wW+Avlo4sXF3Frswd+ncrwMz4duyZ5Eqd+dAYgJ+A1MY+12LNZ7XDhCiijJceueYvtnzdviw==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.45.3': - resolution: {integrity: sha512-1YfXoUEE++gIW66zNB9Twd0Ua5xCXpfYppFUxVT/Io5ZT3fO6Se+C/Jvmh3usaIHHyi53t3kpfjydO2GAy5eBA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.45.3': - resolution: {integrity: sha512-Iok2YA3PvC163rVZf2Zy81A0g88IUcSPeU5pOilcbICXre2EP1mxn1Db/l09Z/SK1vdSLtpJXAnwGuMOyf5O9g==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.45.3': - resolution: {integrity: sha512-HwHCH5GQTOeGYP5wBEBXFVhfQecwRl24Rugoqhh8YwGarsU09bHhOKuqlyW4ZolZCan3eTUax7UJbGSmKSM51A==} - cpu: [x64] - os: [win32] - - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - - '@simplewebauthn/browser@13.1.2': - resolution: {integrity: sha512-aZnW0KawAM83fSBUgglP5WofbrLbLyr7CoPqYr66Eppm7zO86YX6rrCjRB3hQKPrL7ATvY4FVXlykZ6w6FwYYw==} - - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} - - '@socket.io/component-emitter@3.1.2': - resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - - '@stylistic/eslint-plugin@2.11.0': - resolution: {integrity: sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=8.40.0' - - '@tiptap/core@2.11.5': - resolution: {integrity: sha512-jb0KTdUJaJY53JaN7ooY3XAxHQNoMYti/H6ANo707PsLXVeEqJ9o8+eBup1JU5CuwzrgnDc2dECt2WIGX9f8Jw==} - peerDependencies: - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-blockquote@2.11.5': - resolution: {integrity: sha512-MZfcRIzKRD8/J1hkt/eYv49060GTL6qGR3NY/oTDuw2wYzbQXXLEbjk8hxAtjwNn7G+pWQv3L+PKFzZDxibLuA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-bold@2.11.5': - resolution: {integrity: sha512-OAq03MHEbl7MtYCUzGuwb0VpOPnM0k5ekMbEaRILFU5ZC7cEAQ36XmPIw1dQayrcuE8GZL35BKub2qtRxyC9iA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-bubble-menu@2.11.5': - resolution: {integrity: sha512-rx+rMd7EEdht5EHLWldpkzJ56SWYA9799b33ustePqhXd6linnokJCzBqY13AfZ9+xp3RsR6C0ZHI9GGea0tIA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-bullet-list@2.11.5': - resolution: {integrity: sha512-VXwHlX6A/T6FAspnyjbKDO0TQ+oetXuat6RY1/JxbXphH42nLuBaGWJ6pgy6xMl6XY8/9oPkTNrfJw/8/eeRwA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-code-block-lowlight@2.11.5': - resolution: {integrity: sha512-EIE+mAGsp8C69dI0Yyg+VH1x36rgyPJc93SfA7h4xFF6Oth18z4YhJtiLaZcwCMyOOVs2efApZ0R3/Fnz2VlqA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/extension-code-block': ^2.7.0 - '@tiptap/pm': ^2.7.0 - highlight.js: ^11 - lowlight: ^2 || ^3 - - '@tiptap/extension-code-block@2.11.5': - resolution: {integrity: sha512-ksxMMvqLDlC+ftcQLynqZMdlJT1iHYZorXsXw/n+wuRd7YElkRkd6YWUX/Pq/njFY6lDjKiqFLEXBJB8nrzzBA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-code@2.11.5': - resolution: {integrity: sha512-xOvHevNIQIcCCVn9tpvXa1wBp0wHN/2umbAZGTVzS+AQtM7BTo0tz8IyzwxkcZJaImONcUVYLOLzt2AgW1LltA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-color@2.11.5': - resolution: {integrity: sha512-9gZF6EIpfOJYUt1TtFY37e8iqwKcOmBl8CkFaxq+4mWVvYd2D7KbA0r4tYTxSO0fOBJ5fA/1qJrpvgRlyocp/A==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/extension-text-style': ^2.7.0 - - '@tiptap/extension-document@2.11.5': - resolution: {integrity: sha512-7I4BRTpIux2a0O2qS3BDmyZ5LGp3pszKbix32CmeVh7lN9dV7W5reDqtJJ9FCZEEF+pZ6e1/DQA362dflwZw2g==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-dropcursor@2.11.5': - resolution: {integrity: sha512-uIN7L3FU0904ec7FFFbndO7RQE/yiON4VzAMhNn587LFMyWO8US139HXIL4O8dpZeYwYL3d1FnDTflZl6CwLlg==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-floating-menu@2.11.5': - resolution: {integrity: sha512-HsMI0hV5Lwzm530Z5tBeyNCBNG38eJ3qjfdV2OHlfSf3+KOEfn6a5AUdoNaZO02LF79/8+7BaYU2drafag9cxQ==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-font-family@2.11.5': - resolution: {integrity: sha512-QIuJNGyVkUjKVuJaTNYXs2ISoHRXszNsOQxwc7HcU9WZoKBbZE8ZsrFXI7CVKEvdpV04NYuBa47TGeW717fVCA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/extension-text-style': ^2.7.0 - - '@tiptap/extension-gapcursor@2.11.5': - resolution: {integrity: sha512-kcWa+Xq9cb6lBdiICvLReuDtz/rLjFKHWpW3jTTF3FiP3wx4H8Rs6bzVtty7uOVTfwupxZRiKICAMEU6iT0xrQ==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-hard-break@2.11.5': - resolution: {integrity: sha512-q9doeN+Yg9F5QNTG8pZGYfNye3tmntOwch683v0CCVCI4ldKaLZ0jG3NbBTq+mosHYdgOH2rNbIORlRRsQ+iYQ==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-heading@2.11.5': - resolution: {integrity: sha512-x/MV53psJ9baRcZ4k4WjnCUBMt8zCX7mPlKVT+9C/o+DEs/j/qxPLs95nHeQv70chZpSwCQCt93xMmuF0kPoAg==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-highlight@2.11.5': - resolution: {integrity: sha512-VBZfT869L9CiTLF8qr+3FBUtJcmlyUTECORNo0ceEiNDg4H6V9uNPwaROMXrWiQCc+DYVCOkx541QrXwNMzxlg==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-history@2.11.5': - resolution: {integrity: sha512-b+wOS33Dz1azw6F1i9LFTEIJ/gUui0Jwz5ZvmVDpL2ZHBhq1Ui0/spTT+tuZOXq7Y/uCbKL8Liu4WoedIvhboQ==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-horizontal-rule@2.11.5': - resolution: {integrity: sha512-3up2r1Du8/5/4ZYzTC0DjTwhgPI3dn8jhOCLu73m5F3OGvK/9whcXoeWoX103hYMnGDxBlfOje71yQuN35FL4A==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-image@2.11.5': - resolution: {integrity: sha512-HbUq9AL8gb8eSuQfY/QKkvMc66ZFN/b6jvQAILGArNOgalUfGizoC6baKTJShaExMSPjBZlaAHtJiQKPaGRHaA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-italic@2.11.5': - resolution: {integrity: sha512-9VGfb2/LfPhQ6TjzDwuYLRvw0A6VGbaIp3F+5Mql8XVdTBHb2+rhELbyhNGiGVR78CaB/EiKb6dO9xu/tBWSYA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-list-item@2.11.5': - resolution: {integrity: sha512-Mp5RD/pbkfW1vdc6xMVxXYcta73FOwLmblQlFNn/l/E5/X1DUSA4iGhgDDH4EWO3swbs03x2f7Zka/Xoj3+WLg==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-mention@2.11.5': - resolution: {integrity: sha512-xj0/P4WSQWiDHzQLSIqdPUEu8LlC+ptSYA+y9IDChG51j1jVqcmolnS4sxpyrfr/t0ug0smNmJ4PDjQtXaG63A==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - '@tiptap/suggestion': ^2.7.0 - - '@tiptap/extension-ordered-list@2.11.5': - resolution: {integrity: sha512-Cu8KwruBNWAaEfshRQR0yOSaUKAeEwxW7UgbvF9cN/zZuKgK5uZosPCPTehIFCcRe+TBpRtZQh+06f/gNYpYYg==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-paragraph@2.11.5': - resolution: {integrity: sha512-YFBWeg7xu/sBnsDIF/+nh9Arf7R0h07VZMd0id5Ydd2Qe3c1uIZwXxeINVtH0SZozuPIQFAT8ICe9M0RxmE+TA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-placeholder@2.11.5': - resolution: {integrity: sha512-Pr+0Ju/l2ZvXMd9VQxtaoSZbs0BBp1jbBDqwms88ctpyvQFRfLSfSkqudQcSHyw2ROOz2E31p/7I7fpI8Y0CLA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-strike@2.11.5': - resolution: {integrity: sha512-PVfUiCqrjvsLpbIoVlegSY8RlkR64F1Rr2RYmiybQfGbg+AkSZXDeO0eIrc03//4gua7D9DfIozHmAKv1KN3ow==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-table-cell@2.11.5': - resolution: {integrity: sha512-S967Au0pgeULstP3FaasOf/LEh72p61Ooh1PcUMF/az4x8EeGgpcEUARpVUxsGxLFvogv6LmhPHZdtcGgdHcBw==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-table-header@2.11.5': - resolution: {integrity: sha512-O1iBtzZP1XZDi4h1Xmgq1T63il+fpKPvBIMZ0JJH9TyCw5i5rcrMLL2dyy5zaWK3BFRJuYBNSke4c+VWnr/g6w==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-table-row@2.11.5': - resolution: {integrity: sha512-+/VWhCuW24BcM5aaIc/f0bC6ZR1Q5gnuqw13MIo7gyPx7iIY6BXK8roGiZSs8wYAN4uBEf3EKFm0bSZwQuAeyg==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-table@2.11.5': - resolution: {integrity: sha512-NKXLhKWdAdURklm98YkCd2ai4fh8jY8HS/+X2s/2QiQt8Z98CU1keCm35fJEEExM234iB/hCqG5vY4JgTc0Tvw==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-task-item@2.11.5': - resolution: {integrity: sha512-Xvvww8cleM6fcNejP916vzhL31yJnAmuBvABsOV0kHGtAqkqUVCSDcN/1qjI4ihVNeIWEJBHDczjDfZzvLy1xA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/extension-task-list@2.11.5': - resolution: {integrity: sha512-DJpIrBu/bjXYmyYoWQDH2GkpvRmizT9Fvbx5MscFYyfmSsYryD3vRBtCDz08gviwoRII+pFBrG4Ynb0XuQ7DsA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-text-align@2.11.5': - resolution: {integrity: sha512-Ei0zDpH5N9EV59ogydK4HTKa4lCPicCsQllM5n/Nf2tUJPir3aiYxzJ73FzhComD4Hpo1ANYnmssBhy8QeoPZA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-text-style@2.11.5': - resolution: {integrity: sha512-YUmYl0gILSd/u/ZkOmNxjNXVw+mu8fpC2f8G4I4tLODm0zCx09j9DDEJXSrM5XX72nxJQqtSQsCpNKnL0hfeEQ==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-text@2.11.5': - resolution: {integrity: sha512-Gq1WwyhFpCbEDrLPIHt5A8aLSlf8bfz4jm417c8F/JyU0J5dtYdmx0RAxjnLw1i7ZHE7LRyqqAoS0sl7JHDNSQ==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/extension-typography@2.11.5': - resolution: {integrity: sha512-K+mwkyyH3bhnw8f6dKt0AIIh7ipPPVTY5XiWxm1ZMnS6p7TkXeqSJRU6mT1a47YLX4IGBEMlTQdvDVvJ1hwTjA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - - '@tiptap/pm@2.11.5': - resolution: {integrity: sha512-z9JFtqc5ZOsdQLd9vRnXfTCQ8v5ADAfRt9Nm7SqP6FUHII8E1hs38ACzf5xursmth/VonJYb5+73Pqxk1hGIPw==} - - '@tiptap/starter-kit@2.11.5': - resolution: {integrity: sha512-SLI7Aj2ruU1t//6Mk8f+fqW+18uTqpdfLUJYgwu0CkqBckrkRZYZh6GVLk/02k3H2ki7QkFxiFbZrdbZdng0JA==} - - '@tiptap/suggestion@2.8.0': - resolution: {integrity: sha512-ENBgO7a92cZa4gESb0Da5e7PKnHiz77tZr226VLqEdMcp7Lve2jb3Q2uL+cWCJxs7P1l6ZhetUmUiJg+Ee7Wjg==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - - '@tiptap/vue-3@2.11.5': - resolution: {integrity: sha512-etOURQq85MpfkMPeTG0r79s7wmLM7PqLD4aj19m7Fk5rkWuoEZyBinnA+9jfIKEttnhQ1G8PQnHNaqJhfIHQfA==} - peerDependencies: - '@tiptap/core': ^2.7.0 - '@tiptap/pm': ^2.7.0 - vue: ^3.0.0 - - '@tybys/wasm-util@0.10.0': - resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} - - '@types/body-parser@1.19.6': - resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - - '@types/chrome@0.0.262': - resolution: {integrity: sha512-TOoj3dqSYE13PD2fRuMQ6X6pggEvL9rRk/yOYOyWE6sfqRWxsJm4VoVm+wr9pkr4Sht/M5t7FFL4vXato8d1gA==} - - '@types/compression@1.8.1': - resolution: {integrity: sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q==} - - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/cordova@11.0.3': - resolution: {integrity: sha512-kyuRQ40/NWQVhqGIHq78Ehu2Bf9Mlg0LhmSmis6ZFJK7z933FRfYi8tHe/k/0fB+PGfCf95rJC6TO7dopaFvAg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/express-serve-static-core@4.19.6': - resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} - - '@types/express@4.17.23': - resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} - - '@types/filesystem@0.0.36': - resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==} - - '@types/filewriter@0.0.33': - resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} - - '@types/har-format@1.2.16': - resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} - - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - - '@types/http-errors@2.0.5': - resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - - '@types/linkify-it@5.0.0': - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - - '@types/lodash@4.17.20': - resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} - - '@types/markdown-it@14.1.2': - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} - - '@types/mdurl@2.0.0': - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - - '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - - '@types/node-forge@1.3.13': - resolution: {integrity: sha512-zePQJSW5QkwSHKRApqWCVKeKoSOt4xvEnLENZPjyvm9Ezdf/EyDeJM7jqLzOwjVICQQzvLZ63T55MKdJB5H6ww==} - - '@types/node@24.1.0': - resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==} - - '@types/qs@6.14.0': - resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - - '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - - '@types/send@0.17.5': - resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} - - '@types/serve-static@1.15.8': - resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} - - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - - '@typescript-eslint/eslint-plugin@8.38.0': - resolution: {integrity: sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.38.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/parser@8.38.0': - resolution: {integrity: sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/project-service@8.38.0': - resolution: {integrity: sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/scope-manager@8.38.0': - resolution: {integrity: sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.38.0': - resolution: {integrity: sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/type-utils@8.38.0': - resolution: {integrity: sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/types@8.38.0': - resolution: {integrity: sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.38.0': - resolution: {integrity: sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/utils@8.38.0': - resolution: {integrity: sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/visitor-keys@8.38.0': - resolution: {integrity: sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} - cpu: [arm] - os: [android] - - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} - cpu: [arm64] - os: [android] - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} - cpu: [arm64] - os: [darwin] - - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} - cpu: [x64] - os: [darwin] - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} - cpu: [x64] - os: [freebsd] - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} - cpu: [arm] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} - cpu: [arm64] - os: [linux] - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} - cpu: [ppc64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} - cpu: [s390x] - os: [linux] - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} - cpu: [x64] - os: [linux] - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} - cpu: [arm64] - os: [win32] - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} - cpu: [ia32] - os: [win32] - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} - cpu: [x64] - os: [win32] - - '@vitejs/plugin-vue@5.2.4': - resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} - engines: {node: ^18.0.0 || >=20.0.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 - vue: ^3.2.25 - - '@volar/language-core@2.4.20': - resolution: {integrity: sha512-dRDF1G33xaAIDqR6+mXUIjXYdu9vzSxlMGfMEwBxQsfY/JMUEXSpLTR057oTKlUQ2nIvCmP9k94A8h8z2VrNSA==} - - '@volar/language-service@2.4.20': - resolution: {integrity: sha512-LoCD4rEI1Bj5ld6b+2GH1SbDGnoisvJ5skHlrkFEtJWw0T2+bhqGUXwekFudV/bRtp8fPhvD5ZUtjWSW0VRztg==} - - '@volar/source-map@2.4.20': - resolution: {integrity: sha512-mVjmFQH8mC+nUaVwmbxoYUy8cww+abaO8dWzqPUjilsavjxH0jCJ3Mp8HFuHsdewZs2c+SP+EO7hCd8Z92whJg==} - - '@vscode/l10n@0.0.18': - resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} - - '@vue/babel-helper-vue-transform-on@1.4.0': - resolution: {integrity: sha512-mCokbouEQ/ocRce/FpKCRItGo+013tHg7tixg3DUNS+6bmIchPt66012kBMm476vyEIJPafrvOf4E5OYj3shSw==} - - '@vue/babel-plugin-jsx@1.4.0': - resolution: {integrity: sha512-9zAHmwgMWlaN6qRKdrg1uKsBKHvnUU+Py+MOCTuYZBoZsopa90Di10QRjB+YPnVss0BZbG/H5XFwJY1fTxJWhA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - peerDependenciesMeta: - '@babel/core': - optional: true - - '@vue/babel-plugin-resolve-type@1.4.0': - resolution: {integrity: sha512-4xqDRRbQQEWHQyjlYSgZsWj44KfiF6D+ktCuXyZ8EnVDYV3pztmXJDf1HveAjUAXxAnR8daCQT51RneWWxtTyQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@vue/compiler-core@3.5.18': - resolution: {integrity: sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==} - - '@vue/compiler-dom@3.5.18': - resolution: {integrity: sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==} - - '@vue/compiler-sfc@3.5.18': - resolution: {integrity: sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==} - - '@vue/compiler-ssr@3.5.18': - resolution: {integrity: sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==} - - '@vue/devtools-api@6.6.4': - resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - - '@vue/devtools-api@7.7.7': - resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==} - - '@vue/devtools-core@8.0.0': - resolution: {integrity: sha512-5bPtF0jAFnaGs4C/4+3vGRR5U+cf6Y8UWK0nJflutEDGepHxl5L9JRaPdHQYCUgrzUaf4cY4waNBEEGXrfcs3A==} - peerDependencies: - vue: ^3.0.0 - - '@vue/devtools-kit@7.7.7': - resolution: {integrity: sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==} - - '@vue/devtools-kit@8.0.0': - resolution: {integrity: sha512-b11OeQODkE0bctdT0RhL684pEV2DPXJ80bjpywVCbFn1PxuL3bmMPDoJKjbMnnoWbrnUYXYzFfmMWBZAMhORkQ==} - - '@vue/devtools-shared@7.7.7': - resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==} - - '@vue/devtools-shared@8.0.0': - resolution: {integrity: sha512-jrKnbjshQCiOAJanoeJjTU7WaCg0Dz2BUal6SaR6VM/P3hiFdX5Q6Pxl73ZMnrhCxNK9nAg5hvvRGqs+6dtU1g==} - - '@vue/language-plugin-pug@3.0.4': - resolution: {integrity: sha512-TmIHHgUFi0aoen+9OxbMSSUy5HThO6FkIkAv+sgp9lDlWF4g8HnkSDsxtXeEhpaYblCvI+ECPofJeawF9z9xIA==} - - '@vue/reactivity@3.5.18': - resolution: {integrity: sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==} - - '@vue/repl@3.4.0': - resolution: {integrity: sha512-iHhIsmQsp9PJuOwverCRQC2owFb0FSFzk6YWwyirAX6AqH//2FrUV4WB16f9lGX5pDXAHjxlzAE6Lqf9P17HHA==} - - '@vue/runtime-core@3.5.18': - resolution: {integrity: sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==} - - '@vue/runtime-dom@3.5.18': - resolution: {integrity: sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==} - - '@vue/server-renderer@3.5.18': - resolution: {integrity: sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==} - peerDependencies: - vue: 3.5.18 - - '@vue/shared@3.5.18': - resolution: {integrity: sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==} - - '@wry/caches@1.0.1': - resolution: {integrity: sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==} - engines: {node: '>=8'} - - '@wry/context@0.7.4': - resolution: {integrity: sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==} - engines: {node: '>=8'} - - '@wry/equality@0.5.7': - resolution: {integrity: sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==} - engines: {node: '>=8'} - - '@wry/trie@0.5.0': - resolution: {integrity: sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==} - engines: {node: '>=8'} - - '@xterm/xterm@5.5.0': - resolution: {integrity: sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==} - - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - - accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} - - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - ansis@4.1.0: - resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} - engines: {node: '>=14'} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - apollo-upload-client@18.0.1: - resolution: {integrity: sha512-OQvZg1rK05VNI79D658FUmMdoI2oB/KJKb6QGMa2Si25QXOaAvLMBFUEwJct7wf+19U8vk9ILhidBOU1ZWv6QA==} - engines: {node: ^18.15.0 || >=20.4.0} - peerDependencies: - '@apollo/client': ^3.8.0 - graphql: 14 - 16 - - archiver-utils@5.0.2: - resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} - engines: {node: '>= 14'} - - archiver@7.0.1: - resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} - engines: {node: '>= 14'} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - - array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} - - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} - - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - - asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - - assert-never@1.3.0: - resolution: {integrity: sha512-9Z3vxQ+berkL/JJo0dK+EY3Lp0s3NtSnP3VCLsh5HDcZPrh0M+KQRK5sWhUeyPPH+/RCxZqOxLMR+YC6vlviEQ==} - - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - - autoprefixer@10.4.21: - resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - b4a@1.6.7: - resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - - babel-walk@3.0.0-canary-5: - resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} - engines: {node: '>= 10.0.0'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - bare-events@2.6.0: - resolution: {integrity: sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - birpc@2.5.0: - resolution: {integrity: sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - body-parser@1.20.3: - resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - browser-fs-access@0.38.0: - resolution: {integrity: sha512-JveqW2w6pEZqFEEfMgCszXzYpE89dG+nPsmOdcs741mFFAROeL+iqjGEpR07RI+s0YY0EFr+4KnOoACprJTpOw==} - - browserlist@1.0.1: - resolution: {integrity: sha512-nYq9jiWv+qXcgrJxQzivfEc7Wo2GvAKkeRViE5L3cUJpq4SZO6NZR710I/8T+OjE5BPECbzpm8rpUkwslE3nTg==} - hasBin: true - - browserslist@4.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - buffer-builder@0.2.0: - resolution: {integrity: sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==} - - buffer-crc32@1.0.0: - resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} - engines: {node: '>=8.0.0'} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - - bundle-name@4.1.0: - resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} - engines: {node: '>=18'} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - camel-case@4.1.2: - resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} - - caniuse-lite@1.0.30001707: - resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==} - - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - character-parser@2.2.0: - resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} - - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - ci-info@4.3.0: - resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} - engines: {node: '>=8'} - - clean-css@5.3.3: - resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} - engines: {node: '>= 10.0'} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - - clipboard@2.0.11: - resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clone-deep@4.0.1: - resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} - engines: {node: '>=6'} - - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - - codemirror-asciidoc@1.0.4: - resolution: {integrity: sha512-U+G8+ToPONYFGkwTprxpFzV6EV1bCA9zChAA8uT2YAnKFn357JMWL2VkdIPy2yP5N/X13GzslMOGaAk1UNE3rA==} - - codemirror@5.65.11: - resolution: {integrity: sha512-Gp62g2eKSCHYt10axmGhKq3WoJSvVpvhXmowNq7pZdRVowwtvBR/hi2LSP5srtctKkRT33T6/n8Kv1UGp7JW4A==} - - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - colorjs.io@0.5.2: - resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==} - - commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} - - commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} - - comment-parser@1.4.1: - resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} - engines: {node: '>= 12.0.0'} - - compress-commons@6.0.2: - resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} - engines: {node: '>= 14'} - - compressible@2.0.18: - resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} - engines: {node: '>= 0.6'} - - compression@1.8.1: - resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} - engines: {node: '>= 0.8.0'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - constantinople@4.0.1: - resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} - - content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} - engines: {node: '>= 0.6'} - - copy-anything@3.0.5: - resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} - engines: {node: '>=12.13'} - - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - crc-32@1.2.2: - resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} - engines: {node: '>=0.8'} - hasBin: true - - crc32-stream@6.0.0: - resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} - engines: {node: '>= 14'} - - crelt@1.0.6: - resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - default-browser-id@5.0.0: - resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} - engines: {node: '>=18'} - - default-browser@5.2.1: - resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} - engines: {node: '>=18'} - - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} - - define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - delegate@3.2.0: - resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - dependency-graph@1.0.0: - resolution: {integrity: sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==} - engines: {node: '>=4'} - - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - - destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - detect-libc@1.0.3: - resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} - engines: {node: '>=0.10'} - hasBin: true - - devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - - doctypes@1.1.0: - resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} - - dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - - dot-prop@9.0.0: - resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} - engines: {node: '>=18'} - - dotenv-expand@11.0.7: - resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} - engines: {node: '>=12'} - - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} - engines: {node: '>=12'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - electron-to-chromium@1.5.123: - resolution: {integrity: sha512-refir3NlutEZqlKaBLK0tzlVLe5P2wDKS7UQt/3SpibizgsRAPOsqQC3ffw1nlv3ze5gjRQZYHoPymgVZkplFA==} - - elementtree@0.1.7: - resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==} - engines: {node: '>= 0.4.0'} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - engine.io-client@6.6.3: - resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} - - engine.io-parser@5.2.3: - resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} - engines: {node: '>=10.0.0'} - - enhanced-resolve@5.18.2: - resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} - engines: {node: '>=10.13.0'} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - error-stack-parser-es@1.0.5: - resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} - - es-abstract@1.24.0: - resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - - esbuild@0.25.8: - resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - - eslint-compat-utils@0.5.1: - resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} - engines: {node: '>=12'} - peerDependencies: - eslint: '>=6.0.0' - - eslint-import-context@0.1.9: - resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - peerDependencies: - unrs-resolver: ^1.0.0 - peerDependenciesMeta: - unrs-resolver: - optional: true - - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - - eslint-import-resolver-typescript@3.10.1: - resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - eslint-plugin-import-x: '*' - peerDependenciesMeta: - eslint-plugin-import: - optional: true - eslint-plugin-import-x: - optional: true - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-es-x@7.8.0: - resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '>=8' - - eslint-plugin-import-x@4.16.1: - resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/utils': ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - eslint-import-resolver-node: '*' - peerDependenciesMeta: - '@typescript-eslint/utils': - optional: true - eslint-import-resolver-node: - optional: true - - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-n@17.21.2: - resolution: {integrity: sha512-s3ai4Msfk5mbSvOgCkYo6k5+zP3W/OK+AvLmMmx++Ki4a5CPO7luIDwOnjUZm/t+oZYP0YADTxe+u4JqnT8+Dg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=8.23.0' - - eslint-plugin-promise@7.2.1: - resolution: {integrity: sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - - eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - - eslint-plugin-vue-pug@1.0.0-alpha.3: - resolution: {integrity: sha512-PHHCfa/QM0YJgGxdsrO8lThsgrO6ZMq6AxpOIsZr5chWImFRMxC6K/773Jq0GumQljrSp3hGPW7E/upRiBP07w==} - peerDependencies: - eslint-plugin-vue: ^10.0.0 - - eslint-plugin-vue@10.3.0: - resolution: {integrity: sha512-A0u9snqjCfYaPnqqOaH6MBLVWDUIN4trXn8J3x67uDcXvR7X6Ut8p16N+nYhMCQ9Y7edg2BIRGzfyZsY0IdqoQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - vue-eslint-parser: ^10.0.0 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.32.0: - resolution: {integrity: sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - - execa@9.6.0: - resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} - engines: {node: ^18.19.0 || >=20.5.0} - - express@4.21.2: - resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} - engines: {node: '>= 0.10.0'} - - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - - extract-files@13.0.0: - resolution: {integrity: sha512-FXD+2Tsr8Iqtm3QZy1Zmwscca7Jx3mMC5Crr+sEP1I303Jy1CYMuYCm7hRTplFNg3XdUavErkxnTzpaqdSoi6g==} - engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - figures@6.1.0: - resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} - engines: {node: '>=18'} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - filesize-parser@1.5.1: - resolution: {integrity: sha512-wRjdlQ5JM3WHZp6xpakIHQbkcGig8ANglYQDPcQSgZUN5kcDGOgmAwB0396BxzHxcl+kr+GLuusxBnsjdO6x9A==} - - filesize@11.0.2: - resolution: {integrity: sha512-s/iAeeWLk5BschUIpmdrF8RA8lhFZ/xDZgKw1Tan72oGws1/dFGB06nYEiyyssWUfjKNQTNRlrwMVjO9/hvXDw==} - engines: {node: '>= 10.4.0'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} - engines: {node: '>= 0.8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - - fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - - fs-extra@11.3.0: - resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} - engines: {node: '>=14.14'} - - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - - fuse.js@7.1.0: - resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} - engines: {node: '>=10'} - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stream@9.0.1: - resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} - engines: {node: '>=18'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} - - get-tsconfig@4.10.1: - resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} - engines: {node: '>=18'} - - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - - globrex@0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - - good-listener@1.2.2: - resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - graphql-tag@2.12.6: - resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} - engines: {node: '>=10'} - peerDependencies: - graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - - graphql@16.11.0: - resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - has@1.0.4: - resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} - engines: {node: '>= 0.4.0'} - - hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - highlight.js@11.11.1: - resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} - engines: {node: '>=12.0.0'} - - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - - hookable@5.5.3: - resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - - html-minifier-terser@7.2.0: - resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} - engines: {node: ^14.13.1 || >=16.0.0} - hasBin: true - - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - - human-signals@8.0.1: - resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} - engines: {node: '>=18.18.0'} - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - immutable@5.1.3: - resolution: {integrity: sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - inquirer@9.3.7: - resolution: {integrity: sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w==} - engines: {node: '>=18'} - - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - - is-bun-module@2.0.0: - resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - - is-expression@4.0.0: - resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} - engines: {node: '>= 0.4'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - - is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - - is-promise@2.2.2: - resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} - - is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-stream@4.0.1: - resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} - engines: {node: '>=18'} - - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-unicode-supported@2.1.0: - resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} - engines: {node: '>=18'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - - is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} - - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - - is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} - engines: {node: '>=16'} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - - isbinaryfile@5.0.4: - resolution: {integrity: sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==} - engines: {node: '>= 18.0.0'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - - iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - js-cookie@3.0.5: - resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} - engines: {node: '>=14'} - - js-stringify@1.0.2: - resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonc-eslint-parser@2.4.0: - resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - - jsonfile@5.0.0: - resolution: {integrity: sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==} - - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - - jstransformer@1.0.0: - resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} - - jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - - jwt-decode@4.0.0: - resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} - engines: {node: '>=18'} - - katex@0.16.22: - resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} - hasBin: true - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - - lazystream@1.0.1: - resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} - engines: {node: '>= 0.6.3'} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.repeat@4.1.0: - resolution: {integrity: sha512-eWsgQW89IewS95ZOcr15HHCX6FVDxq3f2PNUIng3fyzsPev9imFQxIYdFZ6crl8L56UR6ZlGDLcEb3RZsCSSqw==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - - lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - - lowlight@3.3.0: - resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - luxon@3.7.1: - resolution: {integrity: sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==} - engines: {node: '>=12'} - - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - - markdown-it-abbr@2.0.0: - resolution: {integrity: sha512-of7C8pXSjXjDojW4neNP+jD7inUYH/DO0Ca+K/4FUEccg0oHAEX/nfscw0jfz66PJbYWOAT9U8mjO21X5p6aAw==} - - markdown-it-attrs@4.3.1: - resolution: {integrity: sha512-/ko6cba+H6gdZ0DOw7BbNMZtfuJTRp9g/IrGIuz8lYc/EfnmWRpaR3CFPnNbVz0LDvF8Gf1hFGPqrQqq7De0rg==} - engines: {node: '>=6'} - peerDependencies: - markdown-it: '>= 9.0.0' - - markdown-it-decorate@1.2.2: - resolution: {integrity: sha512-7BFWJ97KBXgkaPVjKHISQnhSW8RWQ7yRNXpr8pPUV2Rw4GHvGrgb6CelKCM+GSijP0uSLCAVfc/knWIz+2v/Sw==} - - markdown-it-emoji@3.0.0: - resolution: {integrity: sha512-+rUD93bXHubA4arpEZO3q80so0qgoFJEKRkRbjKX8RTdca89v2kfyF+xR3i2sQTwql9tpPZPOQN5B+PunspXRg==} - - markdown-it-expand-tabs@1.0.13: - resolution: {integrity: sha512-ODpk98FWkGIq2vkwm2NOLt4G6TRgy3M9eTa9SFm06pUyOd0zjjYAwkhsjiCDU42pzKuz0ChiwBO0utuOj3LNOA==} - - markdown-it-footnote@4.0.0: - resolution: {integrity: sha512-WYJ7urf+khJYl3DqofQpYfEYkZKbmXmwxQV8c8mO/hGIhgZ1wOe7R4HLFNwqx7TjILbnC98fuyeSsin19JdFcQ==} - - markdown-it-imsize@2.0.1: - resolution: {integrity: sha512-5SH90ademqcR8ifQCBXRCfIR4HGfZZOh5pO0j2TglulfSQH+SBXM4Iw/QlTUbSoUwVZArCYgECoMvktDS2kP3w==} - - markdown-it-mark@4.0.0: - resolution: {integrity: sha512-YLhzaOsU9THO/cal0lUjfMjrqSMPjjyjChYM7oyj4DnyaXEzA8gnW6cVJeyCrCVeyesrY2PlEdUYJSPFYL4Nkg==} - - markdown-it-mdc@0.2.6: - resolution: {integrity: sha512-HxbEZoEmftdm/krWzwI3JcCWoeXTkAufme1gQt8MTN6nY7y2w/I0LI8U9TEERNPjBNtMOLaNaQsM1H+5K15UJQ==} - peerDependencies: - '@types/markdown-it': '*' - markdown-it: ^14.0.0 - - markdown-it-multimd-table@4.2.3: - resolution: {integrity: sha512-KepCr2OMJqm7IT6sOIbuqHGe+NERhgy66XMrc5lo6dHW7oaPzMDtYwR1EGwK16/blb6mCSg4jqityOe0o/H7HA==} - - markdown-it-sub@2.0.0: - resolution: {integrity: sha512-iCBKgwCkfQBRg2vApy9vx1C1Tu6D8XYo8NvevI3OlwzBRmiMtsJ2sXupBgEA7PPxiDwNni3qIUkhZ6j5wofDUA==} - - markdown-it-sup@2.0.0: - resolution: {integrity: sha512-5VgmdKlkBd8sgXuoDoxMpiU+BiEt3I49GItBzzw7Mxq9CxvnhE/k09HFli09zgfFDRixDQDfDxi0mgBCXtaTvA==} - - markdown-it-task-lists@2.1.1: - resolution: {integrity: sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==} - - markdown-it@14.1.0: - resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} - hasBin: true - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - merge-descriptors@1.0.3: - resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - minimatch@10.0.3: - resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} - engines: {node: 20 || >=22} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - - mlly@1.7.4: - resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} - - monaco-editor@0.52.2: - resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==} - - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} - - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - - mute-stream@1.0.0: - resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nanoid@5.1.5: - resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} - engines: {node: ^18 || >=20} - hasBin: true - - napi-postinstall@0.3.2: - resolution: {integrity: sha512-tWVJxJHmBWLy69PvO96TZMZDrzmw5KeiZBz3RHmiM2XZ9grBJ2WgMAFVVg25nqp3ZjTFUs2Ftw1JhscL3Teliw==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - - negotiator@0.6.4: - resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} - engines: {node: '>= 0.6'} - - neostandard@0.12.2: - resolution: {integrity: sha512-VZU8EZpSaNadp3rKEwBhVD1Kw8jE3AftQLkCyOaM7bWemL1LwsYRsBnAmXy2LjG9zO8t66qJdqB7ccwwORyrAg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - eslint: ^9.0.0 - - no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - - node-addon-api@7.1.1: - resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - - node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} - - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - - npm-run-path@6.0.0: - resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} - engines: {node: '>=18'} - - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - - ohash@2.0.11: - resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - on-headers@1.1.0: - resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} - engines: {node: '>= 0.8'} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - open@10.2.0: - resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} - engines: {node: '>=18'} - - open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} - - optimism@0.18.1: - resolution: {integrity: sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - - orderedmap@2.1.1: - resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} - - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - - pako@2.1.0: - resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} - - param-case@3.0.4: - resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse-ms@4.0.0: - resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} - engines: {node: '>=18'} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - pascal-case@3.1.2: - resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - path-to-regexp@0.1.12: - resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - peowly@1.3.2: - resolution: {integrity: sha512-BYIrwr8JCXY49jUZscgw311w9oGEKo7ux/s+BxrhKTQbiQ0iYNdZNJ5LgagaeercQdFHwnR7Z5IxxFWVQ+BasQ==} - engines: {node: '>=18.6.0'} - - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pinia@3.0.3: - resolution: {integrity: sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==} - peerDependencies: - typescript: '>=4.4.4' - vue: ^2.7.0 || ^3.5.11 - peerDependenciesMeta: - typescript: - optional: true - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - pretty-ms@9.2.0: - resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} - engines: {node: '>=18'} - - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - - promise@7.3.1: - resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} - - prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - - prosemirror-changeset@2.2.1: - resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==} - - prosemirror-collab@1.3.1: - resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} - - prosemirror-commands@1.7.1: - resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} - - prosemirror-dropcursor@1.8.1: - resolution: {integrity: sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==} - - prosemirror-gapcursor@1.3.2: - resolution: {integrity: sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==} - - prosemirror-history@1.4.1: - resolution: {integrity: sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==} - - prosemirror-inputrules@1.4.0: - resolution: {integrity: sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==} - - prosemirror-keymap@1.2.3: - resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} - - prosemirror-markdown@1.13.1: - resolution: {integrity: sha512-Sl+oMfMtAjWtlcZoj/5L/Q39MpEnVZ840Xo330WJWUvgyhNmLBLN7MsHn07s53nG/KImevWHSE6fEj4q/GihHw==} - - prosemirror-menu@1.2.4: - resolution: {integrity: sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==} - - prosemirror-model@1.25.2: - resolution: {integrity: sha512-BVypCAJ4SL6jOiTsDffP3Wp6wD69lRhI4zg/iT8JXjp3ccZFiq5WyguxvMKmdKFC3prhaig7wSr8dneDToHE1Q==} - - prosemirror-schema-basic@1.2.3: - resolution: {integrity: sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==} - - prosemirror-schema-list@1.5.1: - resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} - - prosemirror-state@1.4.3: - resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==} - - prosemirror-tables@1.6.4: - resolution: {integrity: sha512-TkDY3Gw52gRFRfRn2f4wJv5WOgAOXLJA2CQJYIJ5+kdFbfj3acR4JUW6LX2e1hiEBiUwvEhzH5a3cZ5YSztpIA==} - - prosemirror-trailing-node@3.0.0: - resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==} - peerDependencies: - prosemirror-model: ^1.22.1 - prosemirror-state: ^1.4.2 - prosemirror-view: ^1.33.8 - - prosemirror-transform@1.10.4: - resolution: {integrity: sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==} - - prosemirror-view@1.40.1: - resolution: {integrity: sha512-pbwUjt3G7TlsQQHDiYSupWBhJswpLVB09xXm1YiJPdkjkh9Pe7Y51XdLh5VWIZmROLY8UpUpG03lkdhm9lzIBA==} - - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - pug-attrs@3.0.0: - resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} - - pug-code-gen@3.0.3: - resolution: {integrity: sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==} - - pug-error@2.0.0: - resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==} - - pug-error@2.1.0: - resolution: {integrity: sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==} - - pug-filters@4.0.0: - resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==} - - pug-lexer@5.0.1: - resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==} - - pug-linker@4.0.0: - resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==} - - pug-load@3.0.0: - resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==} - - pug-parser@6.0.0: - resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==} - - pug-runtime@3.0.1: - resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==} - - pug-strip-comments@2.0.0: - resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==} - - pug-walk@2.0.0: - resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==} - - pug@3.0.3: - resolution: {integrity: sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==} - - punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} - engines: {node: '>=0.6'} - - quasar@2.18.2: - resolution: {integrity: sha512-SeSAamH4vgYH9alLTdVL2o1fTTwz7VZnS2+gvIwt6qsH3ndrn/tQW64sWE78VSvrHlWINYbXESVF/cvWEuTYxg==} - engines: {node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - readdir-glob@1.1.3: - resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} - - rehackt@0.1.0: - resolution: {integrity: sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==} - peerDependencies: - '@types/react': '*' - react: '*' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - - relateurl@0.2.7: - resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} - engines: {node: '>= 0.10'} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true - - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - - rollup-plugin-visualizer@5.14.0: - resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - rolldown: 1.x - rollup: 2.x || 3.x || 4.x - peerDependenciesMeta: - rolldown: - optional: true - rollup: - optional: true - - rollup@4.45.3: - resolution: {integrity: sha512-STwyHZF3G+CrmZhB+qDiROq9s8B5PrOCYN6dtmOvwz585XBnyeHk1GTEhHJtUVb355/9uZhOazyVclTt5uahzA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - rope-sequence@1.3.4: - resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} - - run-applescript@7.0.0: - resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} - engines: {node: '>=18'} - - run-async@3.0.0: - resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} - engines: {node: '>=0.12.0'} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - - safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} - - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - sass-embedded-android-arm64@1.89.2: - resolution: {integrity: sha512-+pq7a7AUpItNyPu61sRlP6G2A8pSPpyazASb+8AK2pVlFayCSPAEgpwpCE9A2/Xj86xJZeMizzKUHxM2CBCUxA==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [android] - - sass-embedded-android-arm@1.89.2: - resolution: {integrity: sha512-oHAPTboBHRZlDBhyRB6dvDKh4KvFs+DZibDHXbkSI6dBZxMTT+Yb2ivocHnctVGucKTLQeT7+OM5DjWHyynL/A==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [android] - - sass-embedded-android-riscv64@1.89.2: - resolution: {integrity: sha512-HfJJWp/S6XSYvlGAqNdakeEMPOdhBkj2s2lN6SHnON54rahKem+z9pUbCriUJfM65Z90lakdGuOfidY61R9TYg==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [android] - - sass-embedded-android-x64@1.89.2: - resolution: {integrity: sha512-BGPzq53VH5z5HN8de6jfMqJjnRe1E6sfnCWFd4pK+CAiuM7iw5Fx6BQZu3ikfI1l2GY0y6pRXzsVLdp/j4EKEA==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [android] - - sass-embedded-darwin-arm64@1.89.2: - resolution: {integrity: sha512-UCm3RL/tzMpG7DsubARsvGUNXC5pgfQvP+RRFJo9XPIi6elopY5B6H4m9dRYDpHA+scjVthdiDwkPYr9+S/KGw==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [darwin] - - sass-embedded-darwin-x64@1.89.2: - resolution: {integrity: sha512-D9WxtDY5VYtMApXRuhQK9VkPHB8R79NIIR6xxVlN2MIdEid/TZWi1MHNweieETXhWGrKhRKglwnHxxyKdJYMnA==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [darwin] - - sass-embedded-linux-arm64@1.89.2: - resolution: {integrity: sha512-2N4WW5LLsbtrWUJ7iTpjvhajGIbmDR18ZzYRywHdMLpfdPApuHPMDF5CYzHbS+LLx2UAx7CFKBnj5LLjY6eFgQ==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - - sass-embedded-linux-arm@1.89.2: - resolution: {integrity: sha512-leP0t5U4r95dc90o8TCWfxNXwMAsQhpWxTkdtySDpngoqtTy3miMd7EYNYd1znI0FN1CBaUvbdCMbnbPwygDlA==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [linux] - - sass-embedded-linux-musl-arm64@1.89.2: - resolution: {integrity: sha512-nTyuaBX6U1A/cG7WJh0pKD1gY8hbg1m2SnzsyoFG+exQ0lBX/lwTLHq3nyhF+0atv7YYhYKbmfz+sjPP8CZ9lw==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - - sass-embedded-linux-musl-arm@1.89.2: - resolution: {integrity: sha512-Z6gG2FiVEEdxYHRi2sS5VIYBmp17351bWtOCUZ/thBM66+e70yiN6Eyqjz80DjL8haRUegNQgy9ZJqsLAAmr9g==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [linux] - - sass-embedded-linux-musl-riscv64@1.89.2: - resolution: {integrity: sha512-N6oul+qALO0SwGY8JW7H/Vs0oZIMrRMBM4GqX3AjM/6y8JsJRxkAwnfd0fDyK+aICMFarDqQonQNIx99gdTZqw==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [linux] - - sass-embedded-linux-musl-x64@1.89.2: - resolution: {integrity: sha512-K+FmWcdj/uyP8GiG9foxOCPfb5OAZG0uSVq80DKgVSC0U44AdGjvAvVZkrgFEcZ6cCqlNC2JfYmslB5iqdL7tg==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - - sass-embedded-linux-riscv64@1.89.2: - resolution: {integrity: sha512-g9nTbnD/3yhOaskeqeBQETbtfDQWRgsjHok6bn7DdAuwBsyrR3JlSFyqKc46pn9Xxd9SQQZU8AzM4IR+sY0A0w==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [linux] - - sass-embedded-linux-x64@1.89.2: - resolution: {integrity: sha512-Ax7dKvzncyQzIl4r7012KCMBvJzOz4uwSNoyoM5IV6y5I1f5hEwI25+U4WfuTqdkv42taCMgpjZbh9ERr6JVMQ==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - - sass-embedded-win32-arm64@1.89.2: - resolution: {integrity: sha512-j96iJni50ZUsfD6tRxDQE2QSYQ2WrfHxeiyAXf41Kw0V4w5KYR/Sf6rCZQLMTUOHnD16qTMVpQi20LQSqf4WGg==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [win32] - - sass-embedded-win32-x64@1.89.2: - resolution: {integrity: sha512-cS2j5ljdkQsb4PaORiClaVYynE9OAPZG/XjbOMxpQmjRIf7UroY4PEIH+Waf+y47PfXFX9SyxhYuw2NIKGbEng==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [win32] - - sass-embedded@1.89.2: - resolution: {integrity: sha512-Ack2K8rc57kCFcYlf3HXpZEJFNUX8xd8DILldksREmYXQkRHI879yy8q4mRDJgrojkySMZqmmmW1NxrFxMsYaA==} - engines: {node: '>=16.0.0'} - hasBin: true - - sass@1.89.2: - resolution: {integrity: sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==} - engines: {node: '>=14.0.0'} - hasBin: true - - sax@1.1.4: - resolution: {integrity: sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==} - - select@1.1.2: - resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==} - - selfsigned@2.4.1: - resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} - engines: {node: '>=10'} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - - send@0.19.0: - resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} - engines: {node: '>= 0.8.0'} - - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - - serve-static@1.16.2: - resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} - engines: {node: '>= 0.8.0'} - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - shallow-clone@3.0.1: - resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} - engines: {node: '>=8'} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sirv@3.0.1: - resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} - engines: {node: '>=18'} - - slugify@1.6.6: - resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} - engines: {node: '>=8.0.0'} - - socket.io-client@4.8.1: - resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} - engines: {node: '>=10.0.0'} - - socket.io-parser@4.2.4: - resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} - engines: {node: '>=10.0.0'} - - sortablejs-vue3@1.2.11: - resolution: {integrity: sha512-oKOA6N7yu2ktmqYXPHlPTQWbe9G4v16mn5ewogb+Ybc9Bk1Y+MIURrpbgedEv7f9TS5Bptvh81HGjazh5FEyJw==} - peerDependencies: - sortablejs: ^1.15.0 - vue: ^3.2.25 - - sortablejs@1.14.0: - resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==} - - sortablejs@1.15.6: - resolution: {integrity: sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - - speakingurl@14.0.1: - resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} - engines: {node: '>=0.10.0'} - - stable-hash-x@0.2.0: - resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} - engines: {node: '>=12.0.0'} - - stable-hash@0.0.5: - resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} - - stack-trace@1.0.0-pre2: - resolution: {integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==} - engines: {node: '>=16'} - - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} - - streamx@2.22.1: - resolution: {integrity: sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} - - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} - - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-final-newline@4.0.0: - resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} - engines: {node: '>=18'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - superjson@2.2.2: - resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} - engines: {node: '>=16'} - - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - symbol-observable@4.0.0: - resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} - engines: {node: '>=0.10'} - - sync-child-process@1.0.2: - resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==} - engines: {node: '>=16.0.0'} - - sync-message-port@1.1.3: - resolution: {integrity: sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==} - engines: {node: '>=16.0.0'} - - tabulator-tables@6.3.1: - resolution: {integrity: sha512-qFW7kfadtcaISQIibKAIy0f3eeIXUVi8242Vly1iJfMD79kfEGzfczNuPBN/80hDxHzQJXYbmJ8VipI40hQtfA==} - - tapable@2.2.2: - resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} - engines: {node: '>=6'} - - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} - - terser@5.43.1: - resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} - engines: {node: '>=10'} - hasBin: true - - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - - tiny-emitter@2.1.0: - resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} - - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} - engines: {node: '>=12.0.0'} - - tippy.js@6.3.7: - resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} - - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - token-stream@1.0.0: - resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} - - totalist@3.0.1: - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} - engines: {node: '>=6'} - - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - ts-declaration-location@1.0.7: - resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} - peerDependencies: - typescript: '>=4.0.0' - - ts-essentials@9.4.2: - resolution: {integrity: sha512-mB/cDhOvD7pg3YCLk2rOtejHjjdSi9in/IBYE13S+8WA5FBSraYf4V/ws55uvs0IvQ/l0wBOlXy5yBNZ9Bl8ZQ==} - peerDependencies: - typescript: '>=4.1.0' - peerDependenciesMeta: - typescript: - optional: true - - ts-invariant@0.10.3: - resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==} - engines: {node: '>=8'} - - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - twemoji-parser@14.0.0: - resolution: {integrity: sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==} - - twemoji@14.0.2: - resolution: {integrity: sha512-BzOoXIe1QVdmsUmZ54xbEH+8AgtOKUiG53zO5vVP2iUu6h5u9lN15NcuS6te4OY96qx0H7JK9vjjl9WQbkTRuA==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} - - typescript-eslint@8.38.0: - resolution: {integrity: sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} - hasBin: true - - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - - undici-types@7.8.0: - resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} - - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} - - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - unplugin-utils@0.2.4: - resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==} - engines: {node: '>=18.12.0'} - - unplugin@1.16.1: - resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} - engines: {node: '>=14.0.0'} - - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} - hasBin: true - - v-network-graph@0.9.21: - resolution: {integrity: sha512-/KjaKtBMTg5TBI98N0Gf7gvtl6+6Q3tv14cJRYmzNb66iYtciET4gyagReZ0GwMt+X1EzUAnSezwqEuhH7Ya3w==} - peerDependencies: - d3-force: ^3.0.0 - vue: ^3.5.13 - peerDependenciesMeta: - d3-force: - optional: true - - varint@6.0.0: - resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - vite-dev-rpc@1.1.0: - resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==} - peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 - - vite-hot-client@2.1.0: - resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==} - peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 - - vite-plugin-inspect@11.3.2: - resolution: {integrity: sha512-nzwvyFQg58XSMAmKVLr2uekAxNYvAbz1lyPmCAFVIBncCgN9S/HPM+2UM9Q9cvc4JEbC5ZBgwLAdaE2onmQuKg==} - engines: {node: '>=14'} - peerDependencies: - '@nuxt/kit': '*' - vite: ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - '@nuxt/kit': - optional: true - - vite-plugin-vue-devtools@8.0.0: - resolution: {integrity: sha512-9bWQig8UMu3nPbxX86NJv56aelpFYoBHxB5+pxuQz3pa3Tajc1ezRidj/0dnADA4/UHuVIfwIVYHOvMXYcPshg==} - engines: {node: '>=v14.21.3'} - peerDependencies: - vite: ^6.0.0 || ^7.0.0-0 - - vite-plugin-vue-inspector@5.3.2: - resolution: {integrity: sha512-YvEKooQcSiBTAs0DoYLfefNja9bLgkFM7NI2b07bE2SruuvX0MEa9cMaxjKVMkeCp5Nz9FRIdcN1rOdFVBeL6Q==} - peerDependencies: - vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 - - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - void-elements@3.1.0: - resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} - engines: {node: '>=0.10.0'} - - volar-service-html@0.0.65: - resolution: {integrity: sha512-AxXckCTbCr5j5z81d3bNiRRL32xCaBSa8lmYhq0QfzBPVPaRv06YYaxp22XizM061f96iizM7ZkSHCu1RuSwRA==} - peerDependencies: - '@volar/language-service': ~2.4.0 - peerDependenciesMeta: - '@volar/language-service': - optional: true - - volar-service-pug@0.0.65: - resolution: {integrity: sha512-QTpxpLmpwNjSPASM4n5d+MF9DHKaBUuHeoV7SXVH5wmrx513da6wljlXNk34IU1npBglNp9sO0qaNokP1Gn42g==} - - vscode-html-languageservice@5.5.1: - resolution: {integrity: sha512-/ZdEtsZ3OiFSyL00kmmu7crFV9KwWR+MgpzjsxO60DQH7sIfHZM892C/E4iDd11EKocr+NYuvOA4Y7uc3QzLEA==} - - vscode-jsonrpc@8.2.0: - resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} - engines: {node: '>=14.0.0'} - - vscode-languageserver-protocol@3.17.5: - resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} - - vscode-languageserver-textdocument@1.0.12: - resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} - - vscode-languageserver-types@3.17.5: - resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} - - vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - - vue-eslint-parser-template-tokenizer-pug@1.0.0: - resolution: {integrity: sha512-kBNkXTDvxb0K4KScHOfMdVGngHAQxE1VqCeQmGyhgUOO1VgrDBWW2nb4mhHvAZhX7dIS8f2S48YI1MdjFboNEg==} - peerDependencies: - vue-eslint-parser: ^10.0.0 - - vue-eslint-parser@10.1.1: - resolution: {integrity: sha512-bh2Z/Au5slro9QJ3neFYLanZtb1jH+W2bKqGHXAoYD4vZgNG3KeotL7JpPv5xzY4UXUXJl7TrIsnzECH63kd3Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - - vue-i18n@11.1.11: - resolution: {integrity: sha512-LvyteQoXeQiuILbzqv13LbyBna/TEv2Ha+4ZWK2AwGHUzZ8+IBaZS0TJkCgn5izSPLcgZwXy9yyTrewCb2u/MA==} - engines: {node: '>= 16'} - peerDependencies: - vue: ^3.0.0 - - vue-router@4.5.1: - resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==} - peerDependencies: - vue: ^3.2.0 - - vue3-otp-input@0.5.40: - resolution: {integrity: sha512-3AMYHqNz9ZDa9y7ICwcEcsJG7XdZGaLAr6IRLIl3whvseFE95F5Duc9q963HcqEbu8CeMWilkmbAt/0eZOZxow==} - peerDependencies: - vue: ^3.0.* - - vue@3.5.18: - resolution: {integrity: sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - vuedraggable@4.1.0: - resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==} - peerDependencies: - vue: ^3.0.1 - - w3c-keyname@2.2.8: - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - - webpack-merge@6.0.1: - resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} - engines: {node: '>=18.0.0'} - - webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} - engines: {node: '>= 0.4'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wildcard@2.0.1: - resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} - - with@7.0.2: - resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} - engines: {node: '>= 10.0.0'} - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - ws@8.17.1: - resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - wsl-utils@0.1.0: - resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} - engines: {node: '>=18'} - - xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} - - xmlhttprequest-ssl@2.1.2: - resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} - engines: {node: '>=0.4.0'} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - yaml-eslint-parser@1.3.0: - resolution: {integrity: sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==} - engines: {node: ^14.17.0 || >=16.0.0} - - yaml@2.8.0: - resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} - engines: {node: '>= 14.6'} - hasBin: true - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - yoctocolors-cjs@2.1.2: - resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} - engines: {node: '>=18'} - - yoctocolors@2.1.1: - resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} - engines: {node: '>=18'} - - zen-observable-ts@1.2.5: - resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} - - zen-observable@0.8.15: - resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} - - zip-stream@6.0.1: - resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} - engines: {node: '>= 14'} - - zxcvbn@4.4.2: - resolution: {integrity: sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ==} - -snapshots: - - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - - '@apollo/client@3.13.8(graphql@16.11.0)': - dependencies: - '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) - '@wry/caches': 1.0.1 - '@wry/equality': 0.5.7 - '@wry/trie': 0.5.0 - graphql: 16.11.0 - graphql-tag: 2.12.6(graphql@16.11.0) - hoist-non-react-statics: 3.3.2 - optimism: 0.18.1 - prop-types: 15.8.1 - rehackt: 0.1.0 - symbol-observable: 4.0.0 - ts-invariant: 0.10.3 - tslib: 2.8.1 - zen-observable-ts: 1.2.5 - transitivePeerDependencies: - - '@types/react' - - '@babel/code-frame@7.27.1': - dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.28.0': {} - - '@babel/core@7.28.0': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) - '@babel/helpers': 7.28.2 - '@babel/parser': 7.28.0 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 - convert-source-map: 2.0.0 - debug: 4.4.1 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.28.0': - dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - jsesc: 3.1.0 - - '@babel/helper-annotate-as-pure@7.27.3': - dependencies: - '@babel/types': 7.28.2 - - '@babel/helper-compilation-targets@7.27.2': - dependencies: - '@babel/compat-data': 7.28.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.24.4 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.27.1 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.0) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-member-expression-to-functions@7.27.1': - dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-imports@7.27.1': - dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-optimise-call-expression@7.27.1': - dependencies: - '@babel/types': 7.28.2 - - '@babel/helper-plugin-utils@7.27.1': {} - - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-member-expression-to-functions': 7.27.1 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-skip-transparent-expression-wrappers@7.27.1': - dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.24.8': {} - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.24.7': {} - - '@babel/helper-validator-identifier@7.27.1': {} - - '@babel/helper-validator-option@7.27.1': {} - - '@babel/helpers@7.28.2': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - - '@babel/parser@7.24.8': - dependencies: - '@babel/types': 7.24.8 - - '@babel/parser@7.28.0': - dependencies: - '@babel/types': 7.28.2 - - '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) - transitivePeerDependencies: - - supports-color - - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 - - '@babel/traverse@7.28.0': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.0 - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.24.8': - dependencies: - '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 - to-fast-properties: 2.0.0 - - '@babel/types@7.28.2': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@bufbuild/protobuf@2.6.2': {} - - '@dash14/svg-pan-zoom@3.6.9': {} - - '@emnapi/core@1.4.5': - dependencies: - '@emnapi/wasi-threads': 1.0.4 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.4.5': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.0.4': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.25.8': - optional: true - - '@esbuild/android-arm64@0.25.8': - optional: true - - '@esbuild/android-arm@0.25.8': - optional: true - - '@esbuild/android-x64@0.25.8': - optional: true - - '@esbuild/darwin-arm64@0.25.8': - optional: true - - '@esbuild/darwin-x64@0.25.8': - optional: true - - '@esbuild/freebsd-arm64@0.25.8': - optional: true - - '@esbuild/freebsd-x64@0.25.8': - optional: true - - '@esbuild/linux-arm64@0.25.8': - optional: true - - '@esbuild/linux-arm@0.25.8': - optional: true - - '@esbuild/linux-ia32@0.25.8': - optional: true - - '@esbuild/linux-loong64@0.25.8': - optional: true - - '@esbuild/linux-mips64el@0.25.8': - optional: true - - '@esbuild/linux-ppc64@0.25.8': - optional: true - - '@esbuild/linux-riscv64@0.25.8': - optional: true - - '@esbuild/linux-s390x@0.25.8': - optional: true - - '@esbuild/linux-x64@0.25.8': - optional: true - - '@esbuild/netbsd-arm64@0.25.8': - optional: true - - '@esbuild/netbsd-x64@0.25.8': - optional: true - - '@esbuild/openbsd-arm64@0.25.8': - optional: true - - '@esbuild/openbsd-x64@0.25.8': - optional: true - - '@esbuild/openharmony-arm64@0.25.8': - optional: true - - '@esbuild/sunos-x64@0.25.8': - optional: true - - '@esbuild/win32-arm64@0.25.8': - optional: true - - '@esbuild/win32-ia32@0.25.8': - optional: true - - '@esbuild/win32-x64@0.25.8': - optional: true - - '@eslint-community/eslint-utils@4.4.1(eslint@9.32.0)': - dependencies: - eslint: 9.32.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/eslint-utils@4.7.0(eslint@9.32.0)': - dependencies: - eslint: 9.32.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/config-array@0.21.0': - dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.1 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.3.0': {} - - '@eslint/core@0.15.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.1': - dependencies: - ajv: 6.12.6 - debug: 4.4.1 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.32.0': {} - - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.3.4': - dependencies: - '@eslint/core': 0.15.1 - levn: 0.4.1 - - '@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)': - dependencies: - graphql: 16.11.0 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 - - '@humanwhocodes/gitignore-to-minimatch@1.0.2': {} - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@inquirer/figures@1.0.13': {} - - '@intlify/bundle-utils@10.0.1(vue-i18n@11.1.11(vue@3.5.18(typescript@5.8.3)))': - dependencies: - '@intlify/message-compiler': 11.1.11 - '@intlify/shared': 11.1.11 - acorn: 8.15.0 - escodegen: 2.1.0 - estree-walker: 2.0.2 - jsonc-eslint-parser: 2.4.0 - mlly: 1.7.4 - source-map-js: 1.2.1 - yaml-eslint-parser: 1.3.0 - optionalDependencies: - vue-i18n: 11.1.11(vue@3.5.18(typescript@5.8.3)) - - '@intlify/core-base@11.1.11': - dependencies: - '@intlify/message-compiler': 11.1.11 - '@intlify/shared': 11.1.11 - - '@intlify/message-compiler@11.1.11': - dependencies: - '@intlify/shared': 11.1.11 - source-map-js: 1.2.1 - - '@intlify/shared@11.1.11': {} - - '@intlify/unplugin-vue-i18n@6.0.8(@vue/compiler-dom@3.5.18)(eslint@9.32.0)(rollup@4.45.3)(typescript@5.8.3)(vue-i18n@11.1.11(vue@3.5.18(typescript@5.8.3)))(vue@3.5.18(typescript@5.8.3))': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - '@intlify/bundle-utils': 10.0.1(vue-i18n@11.1.11(vue@3.5.18(typescript@5.8.3))) - '@intlify/shared': 11.1.11 - '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.11)(@vue/compiler-dom@3.5.18)(vue-i18n@11.1.11(vue@3.5.18(typescript@5.8.3)))(vue@3.5.18(typescript@5.8.3)) - '@rollup/pluginutils': 5.2.0(rollup@4.45.3) - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - debug: 4.4.1 - fast-glob: 3.3.3 - js-yaml: 4.1.0 - json5: 2.2.3 - pathe: 1.1.2 - picocolors: 1.1.1 - source-map-js: 1.2.1 - unplugin: 1.16.1 - vue: 3.5.18(typescript@5.8.3) - optionalDependencies: - vue-i18n: 11.1.11(vue@3.5.18(typescript@5.8.3)) - transitivePeerDependencies: - - '@vue/compiler-dom' - - eslint - - rollup - - supports-color - - typescript - - '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.11)(@vue/compiler-dom@3.5.18)(vue-i18n@11.1.11(vue@3.5.18(typescript@5.8.3)))(vue@3.5.18(typescript@5.8.3))': - dependencies: - '@babel/parser': 7.28.0 - optionalDependencies: - '@intlify/shared': 11.1.11 - '@vue/compiler-dom': 3.5.18 - vue: 3.5.18(typescript@5.8.3) - vue-i18n: 11.1.11(vue@3.5.18(typescript@5.8.3)) - - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jridgewell/gen-mapping@0.3.12': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping': 0.3.29 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/source-map@0.3.10': - dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - - '@jridgewell/sourcemap-codec@1.5.4': {} - - '@jridgewell/trace-mapping@0.3.29': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 - - '@lezer/common@1.2.3': {} - - '@mdi/font@7.4.47': {} - - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.4.5 - '@emnapi/runtime': 1.4.5 - '@tybys/wasm-util': 0.10.0 - optional: true - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@nolyfill/is-core-module@1.0.39': {} - - '@parcel/watcher-android-arm64@2.5.1': - optional: true - - '@parcel/watcher-darwin-arm64@2.5.1': - optional: true - - '@parcel/watcher-darwin-x64@2.5.1': - optional: true - - '@parcel/watcher-freebsd-x64@2.5.1': - optional: true - - '@parcel/watcher-linux-arm-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-arm-musl@2.5.1': - optional: true - - '@parcel/watcher-linux-arm64-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-arm64-musl@2.5.1': - optional: true - - '@parcel/watcher-linux-x64-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-x64-musl@2.5.1': - optional: true - - '@parcel/watcher-win32-arm64@2.5.1': - optional: true - - '@parcel/watcher-win32-ia32@2.5.1': - optional: true - - '@parcel/watcher-win32-x64@2.5.1': - optional: true - - '@parcel/watcher@2.5.1': - dependencies: - detect-libc: 1.0.3 - is-glob: 4.0.3 - micromatch: 4.0.8 - node-addon-api: 7.1.1 - optionalDependencies: - '@parcel/watcher-android-arm64': 2.5.1 - '@parcel/watcher-darwin-arm64': 2.5.1 - '@parcel/watcher-darwin-x64': 2.5.1 - '@parcel/watcher-freebsd-x64': 2.5.1 - '@parcel/watcher-linux-arm-glibc': 2.5.1 - '@parcel/watcher-linux-arm-musl': 2.5.1 - '@parcel/watcher-linux-arm64-glibc': 2.5.1 - '@parcel/watcher-linux-arm64-musl': 2.5.1 - '@parcel/watcher-linux-x64-glibc': 2.5.1 - '@parcel/watcher-linux-x64-musl': 2.5.1 - '@parcel/watcher-win32-arm64': 2.5.1 - '@parcel/watcher-win32-ia32': 2.5.1 - '@parcel/watcher-win32-x64': 2.5.1 - optional: true - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@polka/url@1.0.0-next.29': {} - - '@popperjs/core@2.11.8': {} - - '@quasar/app-vite@2.3.0(@types/node@24.1.0)(eslint@9.32.0)(pinia@3.0.3(typescript@5.8.3)(vue@3.5.18(typescript@5.8.3)))(quasar@2.18.2)(rollup@4.45.3)(sass@1.89.2)(terser@5.43.1)(typescript@5.8.3)(vue-router@4.5.1(vue@3.5.18(typescript@5.8.3)))(vue@3.5.18(typescript@5.8.3))(yaml@2.8.0)': - dependencies: - '@quasar/render-ssr-error': 1.0.3 - '@quasar/ssl-certificate': 1.0.0 - '@quasar/vite-plugin': 1.10.0(@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)))(quasar@2.18.2)(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)) - '@types/chrome': 0.0.262 - '@types/compression': 1.8.1 - '@types/cordova': 11.0.3 - '@types/express': 4.17.23 - '@vitejs/plugin-vue': 5.2.4(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)) - archiver: 7.0.1 - chokidar: 3.6.0 - ci-info: 4.3.0 - compression: 1.8.1 - confbox: 0.1.8 - cross-spawn: 7.0.6 - dot-prop: 9.0.0 - dotenv: 16.6.1 - dotenv-expand: 11.0.7 - elementtree: 0.1.7 - esbuild: 0.25.8 - express: 4.21.2 - fs-extra: 11.3.0 - html-minifier-terser: 7.2.0 - inquirer: 9.3.7 - isbinaryfile: 5.0.4 - kolorist: 1.8.0 - lodash: 4.17.21 - minimist: 1.2.8 - mlly: 1.7.4 - open: 10.2.0 - quasar: 2.18.2 - rollup-plugin-visualizer: 5.14.0(rollup@4.45.3) - sass-embedded: 1.89.2 - semver: 7.7.2 - serialize-javascript: 6.0.2 - tinyglobby: 0.2.14 - ts-essentials: 9.4.2(typescript@5.8.3) - vite: 6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0) - vue: 3.5.18(typescript@5.8.3) - vue-router: 4.5.1(vue@3.5.18(typescript@5.8.3)) - webpack-merge: 6.0.1 - optionalDependencies: - eslint: 9.32.0 - pinia: 3.0.3(typescript@5.8.3)(vue@3.5.18(typescript@5.8.3)) - typescript: 5.8.3 - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - rolldown - - rollup - - sass - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - '@quasar/extras@1.17.0': {} - - '@quasar/render-ssr-error@1.0.3': - dependencies: - stack-trace: 1.0.0-pre2 - - '@quasar/ssl-certificate@1.0.0': - dependencies: - fs-extra: 11.3.0 - selfsigned: 2.4.1 - - '@quasar/vite-plugin@1.10.0(@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)))(quasar@2.18.2)(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3))': - dependencies: - '@vitejs/plugin-vue': 5.2.4(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)) - quasar: 2.18.2 - vite: 6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0) - vue: 3.5.18(typescript@5.8.3) - - '@remirror/core-constants@3.0.0': {} - - '@rollup/pluginutils@5.2.0(rollup@4.45.3)': - dependencies: - '@types/estree': 1.0.8 - estree-walker: 2.0.2 - picomatch: 4.0.3 - optionalDependencies: - rollup: 4.45.3 - - '@rollup/rollup-android-arm-eabi@4.45.3': - optional: true - - '@rollup/rollup-android-arm64@4.45.3': - optional: true - - '@rollup/rollup-darwin-arm64@4.45.3': - optional: true - - '@rollup/rollup-darwin-x64@4.45.3': - optional: true - - '@rollup/rollup-freebsd-arm64@4.45.3': - optional: true - - '@rollup/rollup-freebsd-x64@4.45.3': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.45.3': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.45.3': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.45.3': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.45.3': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.45.3': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.45.3': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.45.3': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.45.3': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.45.3': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.45.3': - optional: true - - '@rollup/rollup-linux-x64-musl@4.45.3': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.45.3': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.45.3': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.45.3': - optional: true - - '@rtsao/scc@1.1.0': {} - - '@sec-ant/readable-stream@0.4.1': {} - - '@simplewebauthn/browser@13.1.2': {} - - '@sindresorhus/merge-streams@4.0.0': {} - - '@socket.io/component-emitter@3.1.2': {} - - '@stylistic/eslint-plugin@2.11.0(eslint@9.32.0)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - eslint: 9.32.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - estraverse: 5.3.0 - picomatch: 4.0.3 - transitivePeerDependencies: - - supports-color - - typescript - - '@tiptap/core@2.11.5(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-blockquote@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-bold@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-bubble-menu@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - tippy.js: 6.3.7 - - '@tiptap/extension-bullet-list@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-code-block-lowlight@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/extension-code-block@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)(highlight.js@11.11.1)(lowlight@3.3.0)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/extension-code-block': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - highlight.js: 11.11.1 - lowlight: 3.3.0 - - '@tiptap/extension-code-block@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-code@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-color@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/extension-text-style@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/extension-text-style': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - - '@tiptap/extension-document@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-dropcursor@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-floating-menu@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - tippy.js: 6.3.7 - - '@tiptap/extension-font-family@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/extension-text-style@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/extension-text-style': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - - '@tiptap/extension-gapcursor@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-hard-break@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-heading@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-highlight@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-history@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-horizontal-rule@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-image@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-italic@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-list-item@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-mention@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)(@tiptap/suggestion@2.8.0(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - '@tiptap/suggestion': 2.8.0(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - - '@tiptap/extension-ordered-list@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-paragraph@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-placeholder@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-strike@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-table-cell@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-table-header@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-table-row@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-table@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-task-item@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/extension-task-list@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-text-align@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-text-style@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-text@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/extension-typography@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - - '@tiptap/pm@2.11.5': - dependencies: - prosemirror-changeset: 2.2.1 - prosemirror-collab: 1.3.1 - prosemirror-commands: 1.7.1 - prosemirror-dropcursor: 1.8.1 - prosemirror-gapcursor: 1.3.2 - prosemirror-history: 1.4.1 - prosemirror-inputrules: 1.4.0 - prosemirror-keymap: 1.2.3 - prosemirror-markdown: 1.13.1 - prosemirror-menu: 1.2.4 - prosemirror-model: 1.25.2 - prosemirror-schema-basic: 1.2.3 - prosemirror-schema-list: 1.5.1 - prosemirror-state: 1.4.3 - prosemirror-tables: 1.6.4 - prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.2)(prosemirror-state@1.4.3)(prosemirror-view@1.40.1) - prosemirror-transform: 1.10.4 - prosemirror-view: 1.40.1 - - '@tiptap/starter-kit@2.11.5': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/extension-blockquote': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-bold': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-bullet-list': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-code': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-code-block': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-document': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-dropcursor': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-gapcursor': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-hard-break': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-heading': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-history': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-horizontal-rule': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-italic': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-list-item': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-ordered-list': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-paragraph': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-strike': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-text': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/extension-text-style': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) - '@tiptap/pm': 2.11.5 - - '@tiptap/suggestion@2.8.0(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - - '@tiptap/vue-3@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)(vue@3.5.18(typescript@5.8.3))': - dependencies: - '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) - '@tiptap/extension-bubble-menu': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/extension-floating-menu': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) - '@tiptap/pm': 2.11.5 - vue: 3.5.18(typescript@5.8.3) - - '@tybys/wasm-util@0.10.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@types/body-parser@1.19.6': - dependencies: - '@types/connect': 3.4.38 - '@types/node': 24.1.0 - - '@types/chrome@0.0.262': - dependencies: - '@types/filesystem': 0.0.36 - '@types/har-format': 1.2.16 - - '@types/compression@1.8.1': - dependencies: - '@types/express': 4.17.23 - '@types/node': 24.1.0 - - '@types/connect@3.4.38': - dependencies: - '@types/node': 24.1.0 - - '@types/cordova@11.0.3': {} - - '@types/estree@1.0.8': {} - - '@types/express-serve-static-core@4.19.6': - dependencies: - '@types/node': 24.1.0 - '@types/qs': 6.14.0 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.5 - - '@types/express@4.17.23': - dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 4.19.6 - '@types/qs': 6.14.0 - '@types/serve-static': 1.15.8 - - '@types/filesystem@0.0.36': - dependencies: - '@types/filewriter': 0.0.33 - - '@types/filewriter@0.0.33': {} - - '@types/har-format@1.2.16': {} - - '@types/hast@3.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/http-errors@2.0.5': {} - - '@types/json-schema@7.0.15': {} - - '@types/json5@0.0.29': {} - - '@types/linkify-it@5.0.0': {} - - '@types/lodash@4.17.20': {} - - '@types/markdown-it@14.1.2': - dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 - - '@types/mdurl@2.0.0': {} - - '@types/mime@1.3.5': {} - - '@types/node-forge@1.3.13': - dependencies: - '@types/node': 24.1.0 - - '@types/node@24.1.0': - dependencies: - undici-types: 7.8.0 - - '@types/qs@6.14.0': {} - - '@types/range-parser@1.2.7': {} - - '@types/send@0.17.5': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 24.1.0 - - '@types/serve-static@1.15.8': - dependencies: - '@types/http-errors': 2.0.5 - '@types/node': 24.1.0 - '@types/send': 0.17.5 - - '@types/unist@3.0.3': {} - - '@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(typescript@5.8.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/type-utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.38.0 - eslint: 9.32.0 - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.1 - eslint: 9.32.0 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.38.0(typescript@5.8.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) - '@typescript-eslint/types': 8.38.0 - debug: 4.4.1 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.38.0': - dependencies: - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/visitor-keys': 8.38.0 - - '@typescript-eslint/tsconfig-utils@8.38.0(typescript@5.8.3)': - dependencies: - typescript: 5.8.3 - - '@typescript-eslint/type-utils@8.38.0(eslint@9.32.0)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - debug: 4.4.1 - eslint: 9.32.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.38.0': {} - - '@typescript-eslint/typescript-estree@8.38.0(typescript@5.8.3)': - dependencies: - '@typescript-eslint/project-service': 8.38.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.8.3) - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.1 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - '@typescript-eslint/scope-manager': 8.38.0 - '@typescript-eslint/types': 8.38.0 - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - eslint: 9.32.0 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.38.0': - dependencies: - '@typescript-eslint/types': 8.38.0 - eslint-visitor-keys: 4.2.1 - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - optional: true - - '@unrs/resolver-binding-android-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-arm64@1.11.1': - optional: true - - '@unrs/resolver-binding-darwin-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-freebsd-x64@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - optional: true - - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - optional: true - - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - optional: true - - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - optional: true - - '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3))': - dependencies: - vite: 6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0) - vue: 3.5.18(typescript@5.8.3) - - '@volar/language-core@2.4.20': - dependencies: - '@volar/source-map': 2.4.20 - - '@volar/language-service@2.4.20': - dependencies: - '@volar/language-core': 2.4.20 - vscode-languageserver-protocol: 3.17.5 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.1.0 - - '@volar/source-map@2.4.20': {} - - '@vscode/l10n@0.0.18': {} - - '@vue/babel-helper-vue-transform-on@1.4.0': {} - - '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.28.0)': - dependencies: - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 - '@vue/babel-helper-vue-transform-on': 1.4.0 - '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.28.0) - '@vue/shared': 3.5.18 - optionalDependencies: - '@babel/core': 7.28.0 - transitivePeerDependencies: - - supports-color - - '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.28.0)': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/core': 7.28.0 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/parser': 7.28.0 - '@vue/compiler-sfc': 3.5.18 - transitivePeerDependencies: - - supports-color - - '@vue/compiler-core@3.5.18': - dependencies: - '@babel/parser': 7.28.0 - '@vue/shared': 3.5.18 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.18': - dependencies: - '@vue/compiler-core': 3.5.18 - '@vue/shared': 3.5.18 - - '@vue/compiler-sfc@3.5.18': - dependencies: - '@babel/parser': 7.28.0 - '@vue/compiler-core': 3.5.18 - '@vue/compiler-dom': 3.5.18 - '@vue/compiler-ssr': 3.5.18 - '@vue/shared': 3.5.18 - estree-walker: 2.0.2 - magic-string: 0.30.17 - postcss: 8.5.6 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.18': - dependencies: - '@vue/compiler-dom': 3.5.18 - '@vue/shared': 3.5.18 - - '@vue/devtools-api@6.6.4': {} - - '@vue/devtools-api@7.7.7': - dependencies: - '@vue/devtools-kit': 7.7.7 - - '@vue/devtools-core@8.0.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3))': - dependencies: - '@vue/devtools-kit': 8.0.0 - '@vue/devtools-shared': 8.0.0 - mitt: 3.0.1 - nanoid: 5.1.5 - pathe: 2.0.3 - vite-hot-client: 2.1.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)) - vue: 3.5.18(typescript@5.8.3) - transitivePeerDependencies: - - vite - - '@vue/devtools-kit@7.7.7': - dependencies: - '@vue/devtools-shared': 7.7.7 - birpc: 2.5.0 - hookable: 5.5.3 - mitt: 3.0.1 - perfect-debounce: 1.0.0 - speakingurl: 14.0.1 - superjson: 2.2.2 - - '@vue/devtools-kit@8.0.0': - dependencies: - '@vue/devtools-shared': 8.0.0 - birpc: 2.5.0 - hookable: 5.5.3 - mitt: 3.0.1 - perfect-debounce: 1.0.0 - speakingurl: 14.0.1 - superjson: 2.2.2 - - '@vue/devtools-shared@7.7.7': - dependencies: - rfdc: 1.4.1 - - '@vue/devtools-shared@8.0.0': - dependencies: - rfdc: 1.4.1 - - '@vue/language-plugin-pug@3.0.4': - dependencies: - '@volar/source-map': 2.4.20 - volar-service-pug: 0.0.65 - - '@vue/reactivity@3.5.18': - dependencies: - '@vue/shared': 3.5.18 - - '@vue/repl@3.4.0': {} - - '@vue/runtime-core@3.5.18': - dependencies: - '@vue/reactivity': 3.5.18 - '@vue/shared': 3.5.18 - - '@vue/runtime-dom@3.5.18': - dependencies: - '@vue/reactivity': 3.5.18 - '@vue/runtime-core': 3.5.18 - '@vue/shared': 3.5.18 - csstype: 3.1.3 - - '@vue/server-renderer@3.5.18(vue@3.5.18(typescript@5.8.3))': - dependencies: - '@vue/compiler-ssr': 3.5.18 - '@vue/shared': 3.5.18 - vue: 3.5.18(typescript@5.8.3) - - '@vue/shared@3.5.18': {} - - '@wry/caches@1.0.1': - dependencies: - tslib: 2.8.1 - - '@wry/context@0.7.4': - dependencies: - tslib: 2.8.1 - - '@wry/equality@0.5.7': - dependencies: - tslib: 2.8.1 - - '@wry/trie@0.5.0': - dependencies: - tslib: 2.8.1 - - '@xterm/xterm@5.5.0': {} - - abort-controller@3.0.0: - dependencies: - event-target-shim: 5.0.1 - - accepts@1.3.8: - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@7.4.1: {} - - acorn@8.15.0: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - ansis@4.1.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - apollo-upload-client@18.0.1(@apollo/client@3.13.8(graphql@16.11.0))(graphql@16.11.0): - dependencies: - '@apollo/client': 3.13.8(graphql@16.11.0) - extract-files: 13.0.0 - graphql: 16.11.0 - - archiver-utils@5.0.2: - dependencies: - glob: 10.4.5 - graceful-fs: 4.2.11 - is-stream: 2.0.1 - lazystream: 1.0.1 - lodash: 4.17.21 - normalize-path: 3.0.0 - readable-stream: 4.7.0 - - archiver@7.0.1: - dependencies: - archiver-utils: 5.0.2 - async: 3.2.6 - buffer-crc32: 1.0.0 - readable-stream: 4.7.0 - readdir-glob: 1.1.3 - tar-stream: 3.1.7 - zip-stream: 6.0.1 - - argparse@2.0.1: {} - - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - - array-flatten@1.1.1: {} - - array-includes@3.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - - array.prototype.findlast@1.2.5: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 - - array.prototype.tosorted@1.1.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-shim-unscopables: 1.1.0 - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - - asap@2.0.6: {} - - assert-never@1.3.0: {} - - async-function@1.0.0: {} - - async@3.2.6: {} - - autoprefixer@10.4.21(postcss@8.5.6): - dependencies: - browserslist: 4.24.4 - caniuse-lite: 1.0.30001707 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.1.1 - postcss: 8.5.6 - postcss-value-parser: 4.2.0 - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - b4a@1.6.7: {} - - babel-walk@3.0.0-canary-5: - dependencies: - '@babel/types': 7.24.8 - - balanced-match@1.0.2: {} - - bare-events@2.6.0: - optional: true - - base64-js@1.5.1: {} - - binary-extensions@2.3.0: {} - - birpc@2.5.0: {} - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - body-parser@1.20.3: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.13.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - boolbase@1.0.0: {} - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browser-fs-access@0.38.0: {} - - browserlist@1.0.1: - dependencies: - chalk: 2.4.2 - - browserslist@4.24.4: - dependencies: - caniuse-lite: 1.0.30001707 - electron-to-chromium: 1.5.123 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.4) - - buffer-builder@0.2.0: {} - - buffer-crc32@1.0.0: {} - - buffer-from@1.1.2: {} - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - bundle-name@4.1.0: - dependencies: - run-applescript: 7.0.0 - - bytes@3.1.2: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.2: - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 - - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - camel-case@4.1.2: - dependencies: - pascal-case: 3.1.2 - tslib: 2.8.1 - - caniuse-lite@1.0.30001707: {} - - chalk@2.4.2: - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - character-parser@2.2.0: - dependencies: - is-regex: 1.1.4 - - chardet@0.7.0: {} - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - ci-info@4.3.0: {} - - clean-css@5.3.3: - dependencies: - source-map: 0.6.1 - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.9.2: {} - - cli-width@4.1.0: {} - - clipboard@2.0.11: - dependencies: - good-listener: 1.2.2 - select: 1.1.2 - tiny-emitter: 2.1.0 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone-deep@4.0.1: - dependencies: - is-plain-object: 2.0.4 - kind-of: 6.0.3 - shallow-clone: 3.0.1 - - clone@1.0.4: {} - - codemirror-asciidoc@1.0.4: {} - - codemirror@5.65.11: {} - - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.3: {} - - color-name@1.1.4: {} - - colorjs.io@0.5.2: {} - - commander@10.0.1: {} - - commander@2.20.3: {} - - commander@8.3.0: {} - - comment-parser@1.4.1: {} - - compress-commons@6.0.2: - dependencies: - crc-32: 1.2.2 - crc32-stream: 6.0.0 - is-stream: 2.0.1 - normalize-path: 3.0.0 - readable-stream: 4.7.0 - - compressible@2.0.18: - dependencies: - mime-db: 1.54.0 - - compression@1.8.1: - dependencies: - bytes: 3.1.2 - compressible: 2.0.18 - debug: 2.6.9 - negotiator: 0.6.4 - on-headers: 1.1.0 - safe-buffer: 5.2.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - concat-map@0.0.1: {} - - confbox@0.1.8: {} - - constantinople@4.0.1: - dependencies: - '@babel/parser': 7.24.8 - '@babel/types': 7.24.8 - - content-disposition@0.5.4: - dependencies: - safe-buffer: 5.2.1 - - content-type@1.0.5: {} - - convert-source-map@2.0.0: {} - - cookie-signature@1.0.6: {} - - cookie@0.7.1: {} - - copy-anything@3.0.5: - dependencies: - is-what: 4.1.16 - - core-util-is@1.0.3: {} - - crc-32@1.2.2: {} - - crc32-stream@6.0.0: - dependencies: - crc-32: 1.2.2 - readable-stream: 4.7.0 - - crelt@1.0.6: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - cssesc@3.0.0: {} - - csstype@3.1.3: {} - - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - debug@2.6.9: - dependencies: - ms: 2.0.0 - - debug@3.2.7: - dependencies: - ms: 2.1.3 - - debug@4.3.7: - dependencies: - ms: 2.1.3 - - debug@4.4.1: - dependencies: - ms: 2.1.3 - - deep-is@0.1.4: {} - - default-browser-id@5.0.0: {} - - default-browser@5.2.1: - dependencies: - bundle-name: 4.1.0 - default-browser-id: 5.0.0 - - defaults@1.0.4: - dependencies: - clone: 1.0.4 - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-lazy-prop@2.0.0: {} - - define-lazy-prop@3.0.0: {} - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - delegate@3.2.0: {} - - depd@2.0.0: {} - - dependency-graph@1.0.0: {} - - dequal@2.0.3: {} - - destroy@1.2.0: {} - - detect-libc@1.0.3: - optional: true - - devlop@1.1.0: - dependencies: - dequal: 2.0.3 - - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - - doctypes@1.1.0: {} - - dot-case@3.0.4: - dependencies: - no-case: 3.0.4 - tslib: 2.8.1 - - dot-prop@9.0.0: - dependencies: - type-fest: 4.41.0 - - dotenv-expand@11.0.7: - dependencies: - dotenv: 16.6.1 - - dotenv@16.6.1: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - eastasianwidth@0.2.0: {} - - ee-first@1.1.1: {} - - electron-to-chromium@1.5.123: {} - - elementtree@0.1.7: - dependencies: - sax: 1.1.4 - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - encodeurl@1.0.2: {} - - encodeurl@2.0.0: {} - - engine.io-client@6.6.3: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - engine.io-parser: 5.2.3 - ws: 8.17.1 - xmlhttprequest-ssl: 2.1.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - engine.io-parser@5.2.3: {} - - enhanced-resolve@5.18.2: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.2 - - entities@4.5.0: {} - - error-stack-parser-es@1.0.5: {} - - es-abstract@1.24.0: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-iterator-helpers@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-set-tostringtag: 2.1.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - - esbuild@0.25.8: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.8 - '@esbuild/android-arm': 0.25.8 - '@esbuild/android-arm64': 0.25.8 - '@esbuild/android-x64': 0.25.8 - '@esbuild/darwin-arm64': 0.25.8 - '@esbuild/darwin-x64': 0.25.8 - '@esbuild/freebsd-arm64': 0.25.8 - '@esbuild/freebsd-x64': 0.25.8 - '@esbuild/linux-arm': 0.25.8 - '@esbuild/linux-arm64': 0.25.8 - '@esbuild/linux-ia32': 0.25.8 - '@esbuild/linux-loong64': 0.25.8 - '@esbuild/linux-mips64el': 0.25.8 - '@esbuild/linux-ppc64': 0.25.8 - '@esbuild/linux-riscv64': 0.25.8 - '@esbuild/linux-s390x': 0.25.8 - '@esbuild/linux-x64': 0.25.8 - '@esbuild/netbsd-arm64': 0.25.8 - '@esbuild/netbsd-x64': 0.25.8 - '@esbuild/openbsd-arm64': 0.25.8 - '@esbuild/openbsd-x64': 0.25.8 - '@esbuild/openharmony-arm64': 0.25.8 - '@esbuild/sunos-x64': 0.25.8 - '@esbuild/win32-arm64': 0.25.8 - '@esbuild/win32-ia32': 0.25.8 - '@esbuild/win32-x64': 0.25.8 - - escalade@3.2.0: {} - - escape-html@1.0.3: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@4.0.0: {} - - escodegen@2.1.0: - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - - eslint-compat-utils@0.5.1(eslint@9.32.0): - dependencies: - eslint: 9.32.0 - semver: 7.7.2 - - eslint-import-context@0.1.9(unrs-resolver@1.11.1): - dependencies: - get-tsconfig: 4.10.1 - stable-hash-x: 0.2.0 - optionalDependencies: - unrs-resolver: 1.11.1 - - eslint-import-resolver-node@0.3.9: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 1.22.10 - transitivePeerDependencies: - - supports-color - - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0))(eslint@9.32.0): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 - eslint: 9.32.0 - get-tsconfig: 4.10.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.14 - unrs-resolver: 1.11.1 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - eslint: 9.32.0 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-plugin-es-x@7.8.0(eslint@9.32.0): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - '@eslint-community/regexpp': 4.12.1 - eslint: 9.32.0 - eslint-compat-utils: 0.5.1(eslint@9.32.0) - - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0): - dependencies: - '@typescript-eslint/types': 8.38.0 - comment-parser: 1.4.1 - debug: 4.4.1 - eslint: 9.32.0 - eslint-import-context: 0.1.9(unrs-resolver@1.11.1) - is-glob: 4.0.3 - minimatch: 10.0.3 - semver: 7.7.2 - stable-hash-x: 0.2.0 - unrs-resolver: 1.11.1 - optionalDependencies: - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.32.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-n@17.21.2(eslint@9.32.0)(typescript@5.8.3): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - enhanced-resolve: 5.18.2 - eslint: 9.32.0 - eslint-plugin-es-x: 7.8.0(eslint@9.32.0) - get-tsconfig: 4.10.1 - globals: 15.15.0 - globrex: 0.1.2 - ignore: 5.3.2 - semver: 7.7.2 - ts-declaration-location: 1.0.7(typescript@5.8.3) - transitivePeerDependencies: - - typescript - - eslint-plugin-promise@7.2.1(eslint@9.32.0): - dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.32.0) - eslint: 9.32.0 - - eslint-plugin-react@7.37.5(eslint@9.32.0): - dependencies: - array-includes: 3.1.9 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 9.32.0 - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.9 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.12 - string.prototype.repeat: 1.0.0 - - eslint-plugin-vue-pug@1.0.0-alpha.3(eslint-plugin-vue@10.3.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(vue-eslint-parser@10.1.1(eslint@9.32.0)))(vue-eslint-parser@10.1.1(eslint@9.32.0)): - dependencies: - eslint-plugin-vue: 10.3.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(vue-eslint-parser@10.1.1(eslint@9.32.0)) - vue-eslint-parser-template-tokenizer-pug: 1.0.0(vue-eslint-parser@10.1.1(eslint@9.32.0)) - transitivePeerDependencies: - - vue-eslint-parser - - eslint-plugin-vue@10.3.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(vue-eslint-parser@10.1.1(eslint@9.32.0)): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - eslint: 9.32.0 - natural-compare: 1.4.0 - nth-check: 2.1.1 - postcss-selector-parser: 6.1.2 - semver: 7.7.2 - vue-eslint-parser: 10.1.1(eslint@9.32.0) - xml-name-validator: 4.0.0 - optionalDependencies: - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.32.0: - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.32.0) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.0 - '@eslint/core': 0.15.1 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.32.0 - '@eslint/plugin-kit': 0.3.4 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.1 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - espree@9.6.1: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 3.4.3 - - esprima@4.0.1: {} - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@2.0.2: {} - - esutils@2.0.3: {} - - etag@1.8.1: {} - - event-target-shim@5.0.1: {} - - events@3.3.0: {} - - execa@9.6.0: - dependencies: - '@sindresorhus/merge-streams': 4.0.0 - cross-spawn: 7.0.6 - figures: 6.1.0 - get-stream: 9.0.1 - human-signals: 8.0.1 - is-plain-obj: 4.1.0 - is-stream: 4.0.1 - npm-run-path: 6.0.0 - pretty-ms: 9.2.0 - signal-exit: 4.1.0 - strip-final-newline: 4.0.0 - yoctocolors: 2.1.1 - - express@4.21.2: - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.3 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.3.1 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.3 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.12 - proxy-addr: 2.0.7 - qs: 6.13.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.19.0 - serve-static: 1.16.2 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - - extract-files@13.0.0: - dependencies: - is-plain-obj: 4.1.0 - - fast-deep-equal@3.1.3: {} - - fast-fifo@1.3.2: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fdir@6.4.6(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - figures@6.1.0: - dependencies: - is-unicode-supported: 2.1.0 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - filesize-parser@1.5.1: {} - - filesize@11.0.2: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - finalhandler@1.3.1: - dependencies: - debug: 2.6.9 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flat@5.0.2: {} - - flatted@3.3.3: {} - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - forwarded@0.2.0: {} - - fraction.js@4.3.7: {} - - fresh@0.5.2: {} - - fs-extra@11.3.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - - fs-extra@8.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.1: {} - - function-bind@1.1.2: {} - - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - - fuse.js@7.1.0: {} - - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - - get-intrinsic@1.2.1: - dependencies: - function-bind: 1.1.1 - has: 1.0.4 - has-proto: 1.0.1 - has-symbols: 1.0.3 - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stream@9.0.1: - dependencies: - '@sec-ant/readable-stream': 0.4.1 - is-stream: 4.0.1 - - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - - get-tsconfig@4.10.1: - dependencies: - resolve-pkg-maps: 1.0.0 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@10.4.5: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - - globals@14.0.0: {} - - globals@15.15.0: {} - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - - globrex@0.1.2: {} - - good-listener@1.2.2: - dependencies: - delegate: 3.2.0 - - gopd@1.2.0: {} - - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - graphql-tag@2.12.6(graphql@16.11.0): - dependencies: - graphql: 16.11.0 - tslib: 2.6.2 - - graphql@16.11.0: {} - - has-bigints@1.1.0: {} - - has-flag@3.0.0: {} - - has-flag@4.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-proto@1.0.1: {} - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.0.3: {} - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.0: - dependencies: - has-symbols: 1.0.3 - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - has@1.0.4: {} - - hasown@2.0.0: - dependencies: - function-bind: 1.1.2 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - highlight.js@11.11.1: {} - - hoist-non-react-statics@3.3.2: - dependencies: - react-is: 16.13.1 - - hookable@5.5.3: {} - - html-minifier-terser@7.2.0: - dependencies: - camel-case: 4.1.2 - clean-css: 5.3.3 - commander: 10.0.1 - entities: 4.5.0 - param-case: 3.0.4 - relateurl: 0.2.7 - terser: 5.43.1 - - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - human-signals@8.0.1: {} - - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - immutable@5.1.3: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - inherits@2.0.4: {} - - inquirer@9.3.7: - dependencies: - '@inquirer/figures': 1.0.13 - ansi-escapes: 4.3.2 - cli-width: 4.1.0 - external-editor: 3.1.0 - mute-stream: 1.0.0 - ora: 5.4.1 - run-async: 3.0.0 - rxjs: 7.8.2 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.2 - - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - - ipaddr.js@1.9.1: {} - - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-async-function@2.1.1: - dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-bun-module@2.0.0: - dependencies: - semver: 7.7.2 - - is-callable@1.2.7: {} - - is-core-module@2.13.1: - dependencies: - hasown: 2.0.0 - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 - - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-docker@2.2.1: {} - - is-docker@3.0.0: {} - - is-expression@4.0.0: - dependencies: - acorn: 7.4.1 - object-assign: 4.1.1 - - is-extglob@2.1.1: {} - - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-fullwidth-code-point@3.0.0: {} - - is-generator-function@1.1.0: - dependencies: - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-inside-container@1.0.0: - dependencies: - is-docker: 3.0.0 - - is-interactive@1.0.0: {} - - is-map@2.0.3: {} - - is-negative-zero@2.0.3: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-number@7.0.0: {} - - is-plain-obj@4.1.0: {} - - is-plain-object@2.0.4: - dependencies: - isobject: 3.0.1 - - is-promise@2.2.2: {} - - is-regex@1.1.4: - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 - - is-stream@2.0.1: {} - - is-stream@4.0.1: {} - - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.19 - - is-unicode-supported@0.1.0: {} - - is-unicode-supported@2.1.0: {} - - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-what@4.1.16: {} - - is-wsl@2.2.0: - dependencies: - is-docker: 2.2.1 - - is-wsl@3.1.0: - dependencies: - is-inside-container: 1.0.0 - - isarray@1.0.0: {} - - isarray@2.0.5: {} - - isbinaryfile@5.0.4: {} - - isexe@2.0.0: {} - - isobject@3.0.1: {} - - iterator.prototype@1.1.5: - dependencies: - define-data-property: 1.1.4 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - has-symbols: 1.1.0 - set-function-name: 2.0.2 - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - js-cookie@3.0.5: {} - - js-stringify@1.0.2: {} - - js-tokens@4.0.0: {} - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@1.0.2: - dependencies: - minimist: 1.2.8 - - json5@2.2.3: {} - - jsonc-eslint-parser@2.4.0: - dependencies: - acorn: 8.15.0 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - semver: 7.7.2 - - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - - jsonfile@5.0.0: - dependencies: - universalify: 0.1.2 - optionalDependencies: - graceful-fs: 4.2.11 - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - jstransformer@1.0.0: - dependencies: - is-promise: 2.2.2 - promise: 7.3.1 - - jsx-ast-utils@3.3.5: - dependencies: - array-includes: 3.1.9 - array.prototype.flat: 1.3.3 - object.assign: 4.1.7 - object.values: 1.2.1 - - jwt-decode@4.0.0: {} - - katex@0.16.22: - dependencies: - commander: 8.3.0 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kind-of@6.0.3: {} - - kolorist@1.8.0: {} - - lazystream@1.0.1: - dependencies: - readable-stream: 2.3.8 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - linkify-it@5.0.0: - dependencies: - uc.micro: 2.1.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash-es@4.17.21: {} - - lodash.merge@4.6.2: {} - - lodash.repeat@4.1.0: {} - - lodash@4.17.21: {} - - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - - lower-case@2.0.2: - dependencies: - tslib: 2.8.1 - - lowlight@3.3.0: - dependencies: - '@types/hast': 3.0.4 - devlop: 1.1.0 - highlight.js: 11.11.1 - - lru-cache@10.4.3: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - luxon@3.7.1: {} - - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - - markdown-it-abbr@2.0.0: {} - - markdown-it-attrs@4.3.1(markdown-it@14.1.0): - dependencies: - markdown-it: 14.1.0 - - markdown-it-decorate@1.2.2: {} - - markdown-it-emoji@3.0.0: {} - - markdown-it-expand-tabs@1.0.13: - dependencies: - lodash.repeat: 4.1.0 - - markdown-it-footnote@4.0.0: {} - - markdown-it-imsize@2.0.1: {} - - markdown-it-mark@4.0.0: {} - - markdown-it-mdc@0.2.6(@types/markdown-it@14.1.2)(markdown-it@14.1.0): - dependencies: - '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 - yaml: 2.8.0 - - markdown-it-multimd-table@4.2.3: {} - - markdown-it-sub@2.0.0: {} - - markdown-it-sup@2.0.0: {} - - markdown-it-task-lists@2.1.1: {} - - markdown-it@14.1.0: - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - - math-intrinsics@1.1.0: {} - - mdurl@2.0.0: {} - - media-typer@0.3.0: {} - - merge-descriptors@1.0.3: {} - - merge2@1.4.1: {} - - methods@1.1.2: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mime-db@1.52.0: {} - - mime-db@1.54.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mime@1.6.0: {} - - mimic-fn@2.1.0: {} - - minimatch@10.0.3: - dependencies: - '@isaacs/brace-expansion': 5.0.0 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.2 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist@1.2.8: {} - - minipass@7.1.2: {} - - mitt@3.0.1: {} - - mlly@1.7.4: - dependencies: - acorn: 8.15.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.1 - - monaco-editor@0.52.2: {} - - mrmime@2.0.1: {} - - ms@2.0.0: {} - - ms@2.1.3: {} - - muggle-string@0.4.1: {} - - mute-stream@1.0.0: {} - - nanoid@3.3.11: {} - - nanoid@5.1.5: {} - - napi-postinstall@0.3.2: {} - - natural-compare@1.4.0: {} - - negotiator@0.6.3: {} - - negotiator@0.6.4: {} - - neostandard@0.12.2(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0))(eslint@9.32.0)(typescript@5.8.3): - dependencies: - '@humanwhocodes/gitignore-to-minimatch': 1.0.2 - '@stylistic/eslint-plugin': 2.11.0(eslint@9.32.0)(typescript@5.8.3) - eslint: 9.32.0 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0))(eslint@9.32.0) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.32.0) - eslint-plugin-n: 17.21.2(eslint@9.32.0)(typescript@5.8.3) - eslint-plugin-promise: 7.2.1(eslint@9.32.0) - eslint-plugin-react: 7.37.5(eslint@9.32.0) - find-up: 5.0.0 - globals: 15.15.0 - peowly: 1.3.2 - typescript-eslint: 8.38.0(eslint@9.32.0)(typescript@5.8.3) - transitivePeerDependencies: - - '@typescript-eslint/utils' - - eslint-import-resolver-node - - eslint-plugin-import - - supports-color - - typescript - - no-case@3.0.4: - dependencies: - lower-case: 2.0.2 - tslib: 2.8.1 - - node-addon-api@7.1.1: - optional: true - - node-forge@1.3.1: {} - - node-releases@2.0.19: {} - - normalize-path@3.0.0: {} - - normalize-range@0.1.2: {} - - npm-run-path@6.0.0: - dependencies: - path-key: 4.0.0 - unicorn-magic: 0.3.0 - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - object-assign@4.1.1: {} - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.entries@1.1.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - ohash@2.0.11: {} - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - - on-headers@1.1.0: {} - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - open@10.2.0: - dependencies: - default-browser: 5.2.1 - define-lazy-prop: 3.0.0 - is-inside-container: 1.0.0 - wsl-utils: 0.1.0 - - open@8.4.2: - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - - optimism@0.18.1: - dependencies: - '@wry/caches': 1.0.1 - '@wry/context': 0.7.4 - '@wry/trie': 0.5.0 - tslib: 2.8.1 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - ora@5.4.1: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - orderedmap@2.1.1: {} - - os-tmpdir@1.0.2: {} - - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - package-json-from-dist@1.0.1: {} - - pako@2.1.0: {} - - param-case@3.0.4: - dependencies: - dot-case: 3.0.4 - tslib: 2.8.1 - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-ms@4.0.0: {} - - parseurl@1.3.3: {} - - pascal-case@3.1.2: - dependencies: - no-case: 3.0.4 - tslib: 2.8.1 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - path-key@4.0.0: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - path-to-regexp@0.1.12: {} - - pathe@1.1.2: {} - - pathe@2.0.3: {} - - peowly@1.3.2: {} - - perfect-debounce@1.0.0: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - pinia@3.0.3(typescript@5.8.3)(vue@3.5.18(typescript@5.8.3)): - dependencies: - '@vue/devtools-api': 7.7.7 - vue: 3.5.18(typescript@5.8.3) - optionalDependencies: - typescript: 5.8.3 - - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.7.4 - pathe: 2.0.3 - - possible-typed-array-names@1.1.0: {} - - postcss-selector-parser@6.1.2: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-value-parser@4.2.0: {} - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prelude-ls@1.2.1: {} - - pretty-ms@9.2.0: - dependencies: - parse-ms: 4.0.0 - - process-nextick-args@2.0.1: {} - - process@0.11.10: {} - - promise@7.3.1: - dependencies: - asap: 2.0.6 - - prop-types@15.8.1: - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - - prosemirror-changeset@2.2.1: - dependencies: - prosemirror-transform: 1.10.4 - - prosemirror-collab@1.3.1: - dependencies: - prosemirror-state: 1.4.3 - - prosemirror-commands@1.7.1: - dependencies: - prosemirror-model: 1.25.2 - prosemirror-state: 1.4.3 - prosemirror-transform: 1.10.4 - - prosemirror-dropcursor@1.8.1: - dependencies: - prosemirror-state: 1.4.3 - prosemirror-transform: 1.10.4 - prosemirror-view: 1.40.1 - - prosemirror-gapcursor@1.3.2: - dependencies: - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.2 - prosemirror-state: 1.4.3 - prosemirror-view: 1.40.1 - - prosemirror-history@1.4.1: - dependencies: - prosemirror-state: 1.4.3 - prosemirror-transform: 1.10.4 - prosemirror-view: 1.40.1 - rope-sequence: 1.3.4 - - prosemirror-inputrules@1.4.0: - dependencies: - prosemirror-state: 1.4.3 - prosemirror-transform: 1.10.4 - - prosemirror-keymap@1.2.3: - dependencies: - prosemirror-state: 1.4.3 - w3c-keyname: 2.2.8 - - prosemirror-markdown@1.13.1: - dependencies: - '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 - prosemirror-model: 1.25.2 - - prosemirror-menu@1.2.4: - dependencies: - crelt: 1.0.6 - prosemirror-commands: 1.7.1 - prosemirror-history: 1.4.1 - prosemirror-state: 1.4.3 - - prosemirror-model@1.25.2: - dependencies: - orderedmap: 2.1.1 - - prosemirror-schema-basic@1.2.3: - dependencies: - prosemirror-model: 1.25.2 - - prosemirror-schema-list@1.5.1: - dependencies: - prosemirror-model: 1.25.2 - prosemirror-state: 1.4.3 - prosemirror-transform: 1.10.4 - - prosemirror-state@1.4.3: - dependencies: - prosemirror-model: 1.25.2 - prosemirror-transform: 1.10.4 - prosemirror-view: 1.40.1 - - prosemirror-tables@1.6.4: - dependencies: - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.2 - prosemirror-state: 1.4.3 - prosemirror-transform: 1.10.4 - prosemirror-view: 1.40.1 - - prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.2)(prosemirror-state@1.4.3)(prosemirror-view@1.40.1): - dependencies: - '@remirror/core-constants': 3.0.0 - escape-string-regexp: 4.0.0 - prosemirror-model: 1.25.2 - prosemirror-state: 1.4.3 - prosemirror-view: 1.40.1 - - prosemirror-transform@1.10.4: - dependencies: - prosemirror-model: 1.25.2 - - prosemirror-view@1.40.1: - dependencies: - prosemirror-model: 1.25.2 - prosemirror-state: 1.4.3 - prosemirror-transform: 1.10.4 - - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - pug-attrs@3.0.0: - dependencies: - constantinople: 4.0.1 - js-stringify: 1.0.2 - pug-runtime: 3.0.1 - - pug-code-gen@3.0.3: - dependencies: - constantinople: 4.0.1 - doctypes: 1.1.0 - js-stringify: 1.0.2 - pug-attrs: 3.0.0 - pug-error: 2.1.0 - pug-runtime: 3.0.1 - void-elements: 3.1.0 - with: 7.0.2 - - pug-error@2.0.0: {} - - pug-error@2.1.0: {} - - pug-filters@4.0.0: - dependencies: - constantinople: 4.0.1 - jstransformer: 1.0.0 - pug-error: 2.1.0 - pug-walk: 2.0.0 - resolve: 1.22.8 - - pug-lexer@5.0.1: - dependencies: - character-parser: 2.2.0 - is-expression: 4.0.0 - pug-error: 2.0.0 - - pug-linker@4.0.0: - dependencies: - pug-error: 2.1.0 - pug-walk: 2.0.0 - - pug-load@3.0.0: - dependencies: - object-assign: 4.1.1 - pug-walk: 2.0.0 - - pug-parser@6.0.0: - dependencies: - pug-error: 2.1.0 - token-stream: 1.0.0 - - pug-runtime@3.0.1: {} - - pug-strip-comments@2.0.0: - dependencies: - pug-error: 2.1.0 - - pug-walk@2.0.0: {} - - pug@3.0.3: - dependencies: - pug-code-gen: 3.0.3 - pug-filters: 4.0.0 - pug-lexer: 5.0.1 - pug-linker: 4.0.0 - pug-load: 3.0.0 - pug-parser: 6.0.0 - pug-runtime: 3.0.1 - pug-strip-comments: 2.0.0 - - punycode.js@2.3.1: {} - - punycode@2.3.1: {} - - qs@6.13.0: - dependencies: - side-channel: 1.1.0 - - quasar@2.18.2: {} - - queue-microtask@1.2.3: {} - - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - range-parser@1.2.1: {} - - raw-body@2.5.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - - react-is@16.13.1: {} - - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readable-stream@4.7.0: - dependencies: - abort-controller: 3.0.0 - buffer: 6.0.3 - events: 3.3.0 - process: 0.11.10 - string_decoder: 1.3.0 - - readdir-glob@1.1.3: - dependencies: - minimatch: 5.1.6 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - readdirp@4.1.2: {} - - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 - - rehackt@0.1.0: {} - - relateurl@0.2.7: {} - - require-directory@2.1.1: {} - - resolve-from@4.0.0: {} - - resolve-pkg-maps@1.0.0: {} - - resolve@1.22.10: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - resolve@1.22.8: - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - resolve@2.0.0-next.5: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - reusify@1.1.0: {} - - rfdc@1.4.1: {} - - rollup-plugin-visualizer@5.14.0(rollup@4.45.3): - dependencies: - open: 8.4.2 - picomatch: 4.0.3 - source-map: 0.7.6 - yargs: 17.7.2 - optionalDependencies: - rollup: 4.45.3 - - rollup@4.45.3: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.45.3 - '@rollup/rollup-android-arm64': 4.45.3 - '@rollup/rollup-darwin-arm64': 4.45.3 - '@rollup/rollup-darwin-x64': 4.45.3 - '@rollup/rollup-freebsd-arm64': 4.45.3 - '@rollup/rollup-freebsd-x64': 4.45.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.45.3 - '@rollup/rollup-linux-arm-musleabihf': 4.45.3 - '@rollup/rollup-linux-arm64-gnu': 4.45.3 - '@rollup/rollup-linux-arm64-musl': 4.45.3 - '@rollup/rollup-linux-loongarch64-gnu': 4.45.3 - '@rollup/rollup-linux-ppc64-gnu': 4.45.3 - '@rollup/rollup-linux-riscv64-gnu': 4.45.3 - '@rollup/rollup-linux-riscv64-musl': 4.45.3 - '@rollup/rollup-linux-s390x-gnu': 4.45.3 - '@rollup/rollup-linux-x64-gnu': 4.45.3 - '@rollup/rollup-linux-x64-musl': 4.45.3 - '@rollup/rollup-win32-arm64-msvc': 4.45.3 - '@rollup/rollup-win32-ia32-msvc': 4.45.3 - '@rollup/rollup-win32-x64-msvc': 4.45.3 - fsevents: 2.3.3 - - rope-sequence@1.3.4: {} - - run-applescript@7.0.0: {} - - run-async@3.0.0: {} - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - rxjs@7.8.2: - dependencies: - tslib: 2.8.1 - - safe-array-concat@1.1.3: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} - - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - - safer-buffer@2.1.2: {} - - sass-embedded-android-arm64@1.89.2: - optional: true - - sass-embedded-android-arm@1.89.2: - optional: true - - sass-embedded-android-riscv64@1.89.2: - optional: true - - sass-embedded-android-x64@1.89.2: - optional: true - - sass-embedded-darwin-arm64@1.89.2: - optional: true - - sass-embedded-darwin-x64@1.89.2: - optional: true - - sass-embedded-linux-arm64@1.89.2: - optional: true - - sass-embedded-linux-arm@1.89.2: - optional: true - - sass-embedded-linux-musl-arm64@1.89.2: - optional: true - - sass-embedded-linux-musl-arm@1.89.2: - optional: true - - sass-embedded-linux-musl-riscv64@1.89.2: - optional: true - - sass-embedded-linux-musl-x64@1.89.2: - optional: true - - sass-embedded-linux-riscv64@1.89.2: - optional: true - - sass-embedded-linux-x64@1.89.2: - optional: true - - sass-embedded-win32-arm64@1.89.2: - optional: true - - sass-embedded-win32-x64@1.89.2: - optional: true - - sass-embedded@1.89.2: - dependencies: - '@bufbuild/protobuf': 2.6.2 - buffer-builder: 0.2.0 - colorjs.io: 0.5.2 - immutable: 5.1.3 - rxjs: 7.8.2 - supports-color: 8.1.1 - sync-child-process: 1.0.2 - varint: 6.0.0 - optionalDependencies: - sass-embedded-android-arm: 1.89.2 - sass-embedded-android-arm64: 1.89.2 - sass-embedded-android-riscv64: 1.89.2 - sass-embedded-android-x64: 1.89.2 - sass-embedded-darwin-arm64: 1.89.2 - sass-embedded-darwin-x64: 1.89.2 - sass-embedded-linux-arm: 1.89.2 - sass-embedded-linux-arm64: 1.89.2 - sass-embedded-linux-musl-arm: 1.89.2 - sass-embedded-linux-musl-arm64: 1.89.2 - sass-embedded-linux-musl-riscv64: 1.89.2 - sass-embedded-linux-musl-x64: 1.89.2 - sass-embedded-linux-riscv64: 1.89.2 - sass-embedded-linux-x64: 1.89.2 - sass-embedded-win32-arm64: 1.89.2 - sass-embedded-win32-x64: 1.89.2 - - sass@1.89.2: - dependencies: - chokidar: 4.0.3 - immutable: 5.1.3 - source-map-js: 1.2.1 - optionalDependencies: - '@parcel/watcher': 2.5.1 - - sax@1.1.4: {} - - select@1.1.2: {} - - selfsigned@2.4.1: - dependencies: - '@types/node-forge': 1.3.13 - node-forge: 1.3.1 - - semver@6.3.1: {} - - semver@7.7.2: {} - - send@0.19.0: - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 - - serve-static@1.16.2: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.19.0 - transitivePeerDependencies: - - supports-color - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - - setprototypeof@1.2.0: {} - - shallow-clone@3.0.1: - dependencies: - kind-of: 6.0.3 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - sirv@3.0.1: - dependencies: - '@polka/url': 1.0.0-next.29 - mrmime: 2.0.1 - totalist: 3.0.1 - - slugify@1.6.6: {} - - socket.io-client@4.8.1: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - engine.io-client: 6.6.3 - socket.io-parser: 4.2.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-parser@4.2.4: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - transitivePeerDependencies: - - supports-color - - sortablejs-vue3@1.2.11(sortablejs@1.15.6)(vue@3.5.18(typescript@5.8.3)): - dependencies: - sortablejs: 1.15.6 - vue: 3.5.18(typescript@5.8.3) - - sortablejs@1.14.0: {} - - sortablejs@1.15.6: {} - - source-map-js@1.2.1: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - source-map@0.7.6: {} - - speakingurl@14.0.1: {} - - stable-hash-x@0.2.0: {} - - stable-hash@0.0.5: {} - - stack-trace@1.0.0-pre2: {} - - statuses@2.0.1: {} - - stop-iteration-iterator@1.1.0: - dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 - - streamx@2.22.1: - dependencies: - fast-fifo: 1.3.2 - text-decoder: 1.2.3 - optionalDependencies: - bare-events: 2.6.0 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string.prototype.matchall@4.0.12: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - regexp.prototype.flags: 1.5.4 - set-function-name: 2.0.2 - side-channel: 1.1.0 - - string.prototype.repeat@1.0.0: - dependencies: - define-properties: 1.2.1 - es-abstract: 1.24.0 - - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - - strip-bom@3.0.0: {} - - strip-final-newline@4.0.0: {} - - strip-json-comments@3.1.1: {} - - superjson@2.2.2: - dependencies: - copy-anything: 3.0.5 - - supports-color@5.5.0: - dependencies: - has-flag: 3.0.0 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - symbol-observable@4.0.0: {} - - sync-child-process@1.0.2: - dependencies: - sync-message-port: 1.1.3 - - sync-message-port@1.1.3: {} - - tabulator-tables@6.3.1: {} - - tapable@2.2.2: {} - - tar-stream@3.1.7: - dependencies: - b4a: 1.6.7 - fast-fifo: 1.3.2 - streamx: 2.22.1 - - terser@5.43.1: - dependencies: - '@jridgewell/source-map': 0.3.10 - acorn: 8.15.0 - commander: 2.20.3 - source-map-support: 0.5.21 - - text-decoder@1.2.3: - dependencies: - b4a: 1.6.7 - - tiny-emitter@2.1.0: {} - - tinyglobby@0.2.14: - dependencies: - fdir: 6.4.6(picomatch@4.0.3) - picomatch: 4.0.3 - - tippy.js@6.3.7: - dependencies: - '@popperjs/core': 2.11.8 - - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - - to-fast-properties@2.0.0: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - toidentifier@1.0.1: {} - - token-stream@1.0.0: {} - - totalist@3.0.1: {} - - ts-api-utils@2.1.0(typescript@5.8.3): - dependencies: - typescript: 5.8.3 - - ts-declaration-location@1.0.7(typescript@5.8.3): - dependencies: - picomatch: 4.0.3 - typescript: 5.8.3 - - ts-essentials@9.4.2(typescript@5.8.3): - optionalDependencies: - typescript: 5.8.3 - - ts-invariant@0.10.3: - dependencies: - tslib: 2.8.1 - - tsconfig-paths@3.15.0: - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - - tslib@2.6.2: {} - - tslib@2.8.1: {} - - twemoji-parser@14.0.0: {} - - twemoji@14.0.2: - dependencies: - fs-extra: 8.1.0 - jsonfile: 5.0.0 - twemoji-parser: 14.0.0 - universalify: 0.1.2 - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-fest@0.21.3: {} - - type-fest@4.41.0: {} - - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 - - typescript-eslint@8.38.0(eslint@9.32.0)(typescript@5.8.3): - dependencies: - '@typescript-eslint/eslint-plugin': 8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0)(typescript@5.8.3))(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/parser': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.38.0(eslint@9.32.0)(typescript@5.8.3) - eslint: 9.32.0 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - typescript@5.8.3: {} - - uc.micro@2.1.0: {} - - ufo@1.6.1: {} - - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - - undici-types@7.8.0: {} - - unicorn-magic@0.3.0: {} - - universalify@0.1.2: {} - - universalify@2.0.1: {} - - unpipe@1.0.0: {} - - unplugin-utils@0.2.4: - dependencies: - pathe: 2.0.3 - picomatch: 4.0.3 - - unplugin@1.16.1: - dependencies: - acorn: 8.15.0 - webpack-virtual-modules: 0.6.2 - - unrs-resolver@1.11.1: - dependencies: - napi-postinstall: 0.3.2 - optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - - update-browserslist-db@1.1.3(browserslist@4.24.4): - dependencies: - browserslist: 4.24.4 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - util-deprecate@1.0.2: {} - - utils-merge@1.0.1: {} - - uuid@11.1.0: {} - - v-network-graph@0.9.21(vue@3.5.18(typescript@5.8.3)): - dependencies: - '@dash14/svg-pan-zoom': 3.6.9 - lodash-es: 4.17.21 - mitt: 3.0.1 - vue: 3.5.18(typescript@5.8.3) - - varint@6.0.0: {} - - vary@1.1.2: {} - - vite-dev-rpc@1.1.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)): - dependencies: - birpc: 2.5.0 - vite: 6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0) - vite-hot-client: 2.1.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)) - - vite-hot-client@2.1.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)): - dependencies: - vite: 6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0) - - vite-plugin-inspect@11.3.2(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)): - dependencies: - ansis: 4.1.0 - debug: 4.4.1 - error-stack-parser-es: 1.0.5 - ohash: 2.0.11 - open: 10.2.0 - perfect-debounce: 1.0.0 - sirv: 3.0.1 - unplugin-utils: 0.2.4 - vite: 6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0) - vite-dev-rpc: 1.1.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)) - transitivePeerDependencies: - - supports-color - - vite-plugin-vue-devtools@8.0.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)): - dependencies: - '@vue/devtools-core': 8.0.0(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.18(typescript@5.8.3)) - '@vue/devtools-kit': 8.0.0 - '@vue/devtools-shared': 8.0.0 - execa: 9.6.0 - sirv: 3.0.1 - vite: 6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0) - vite-plugin-inspect: 11.3.2(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)) - vite-plugin-vue-inspector: 5.3.2(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)) - transitivePeerDependencies: - - '@nuxt/kit' - - supports-color - - vue - - vite-plugin-vue-inspector@5.3.2(vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0)): - dependencies: - '@babel/core': 7.28.0 - '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.0) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.0) - '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.28.0) - '@vue/compiler-dom': 3.5.18 - kolorist: 1.8.0 - magic-string: 0.30.17 - vite: 6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0) - transitivePeerDependencies: - - supports-color - - vite@6.3.5(@types/node@24.1.0)(sass-embedded@1.89.2)(sass@1.89.2)(terser@5.43.1)(yaml@2.8.0): - dependencies: - esbuild: 0.25.8 - fdir: 6.4.6(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.45.3 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 24.1.0 - fsevents: 2.3.3 - sass: 1.89.2 - sass-embedded: 1.89.2 - terser: 5.43.1 - yaml: 2.8.0 - - void-elements@3.1.0: {} - - volar-service-html@0.0.65(@volar/language-service@2.4.20): - dependencies: - vscode-html-languageservice: 5.5.1 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.1.0 - optionalDependencies: - '@volar/language-service': 2.4.20 - - volar-service-pug@0.0.65: - dependencies: - '@volar/language-service': 2.4.20 - muggle-string: 0.4.1 - pug-lexer: 5.0.1 - pug-parser: 6.0.0 - volar-service-html: 0.0.65(@volar/language-service@2.4.20) - vscode-html-languageservice: 5.5.1 - vscode-languageserver-textdocument: 1.0.12 - - vscode-html-languageservice@5.5.1: - dependencies: - '@vscode/l10n': 0.0.18 - vscode-languageserver-textdocument: 1.0.12 - vscode-languageserver-types: 3.17.5 - vscode-uri: 3.1.0 - - vscode-jsonrpc@8.2.0: {} - - vscode-languageserver-protocol@3.17.5: - dependencies: - vscode-jsonrpc: 8.2.0 - vscode-languageserver-types: 3.17.5 - - vscode-languageserver-textdocument@1.0.12: {} - - vscode-languageserver-types@3.17.5: {} - - vscode-uri@3.1.0: {} - - vue-eslint-parser-template-tokenizer-pug@1.0.0(vue-eslint-parser@10.1.1(eslint@9.32.0)): - dependencies: - pug-lexer: 5.0.1 - vue-eslint-parser: 10.1.1(eslint@9.32.0) - - vue-eslint-parser@10.1.1(eslint@9.32.0): - dependencies: - debug: 4.4.1 - eslint: 9.32.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - lodash: 4.17.21 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - vue-i18n@11.1.11(vue@3.5.18(typescript@5.8.3)): - dependencies: - '@intlify/core-base': 11.1.11 - '@intlify/shared': 11.1.11 - '@vue/devtools-api': 6.6.4 - vue: 3.5.18(typescript@5.8.3) - - vue-router@4.5.1(vue@3.5.18(typescript@5.8.3)): - dependencies: - '@vue/devtools-api': 6.6.4 - vue: 3.5.18(typescript@5.8.3) - - vue3-otp-input@0.5.40(vue@3.5.18(typescript@5.8.3)): - dependencies: - vue: 3.5.18(typescript@5.8.3) - - vue@3.5.18(typescript@5.8.3): - dependencies: - '@vue/compiler-dom': 3.5.18 - '@vue/compiler-sfc': 3.5.18 - '@vue/runtime-dom': 3.5.18 - '@vue/server-renderer': 3.5.18(vue@3.5.18(typescript@5.8.3)) - '@vue/shared': 3.5.18 - optionalDependencies: - typescript: 5.8.3 - - vuedraggable@4.1.0(vue@3.5.18(typescript@5.8.3)): - dependencies: - sortablejs: 1.14.0 - vue: 3.5.18(typescript@5.8.3) - - w3c-keyname@2.2.8: {} - - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - - webpack-merge@6.0.1: - dependencies: - clone-deep: 4.0.1 - flat: 5.0.2 - wildcard: 2.0.1 - - webpack-virtual-modules@0.6.2: {} - - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.19 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-typed-array@1.1.19: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wildcard@2.0.1: {} - - with@7.0.2: - dependencies: - '@babel/parser': 7.24.8 - '@babel/types': 7.24.8 - assert-never: 1.3.0 - babel-walk: 3.0.0-canary-5 - - word-wrap@1.2.5: {} - - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - ws@8.17.1: {} - - wsl-utils@0.1.0: - dependencies: - is-wsl: 3.1.0 - - xml-name-validator@4.0.0: {} - - xmlhttprequest-ssl@2.1.2: {} - - y18n@5.0.8: {} - - yallist@3.1.1: {} - - yaml-eslint-parser@1.3.0: - dependencies: - eslint-visitor-keys: 3.4.3 - yaml: 2.8.0 - - yaml@2.8.0: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yocto-queue@0.1.0: {} - - yoctocolors-cjs@2.1.2: {} - - yoctocolors@2.1.1: {} - - zen-observable-ts@1.2.5: - dependencies: - zen-observable: 0.8.15 - - zen-observable@0.8.15: {} - - zip-stream@6.0.1: - dependencies: - archiver-utils: 5.0.2 - compress-commons: 6.0.2 - readable-stream: 4.7.0 - - zxcvbn@4.4.2: {} diff --git a/ux/postcss.config.js b/ux/postcss.config.js deleted file mode 100644 index aa61ec3d6..000000000 --- a/ux/postcss.config.js +++ /dev/null @@ -1,29 +0,0 @@ -import autoprefixer from 'autoprefixer' - -/* eslint-disable */ -// https://github.com/michael-ciniawsky/postcss-load-config - -export default { - plugins: [ - // https://github.com/postcss/autoprefixer - autoprefixer({ - overrideBrowserslist: [ - 'last 4 Chrome versions', - 'last 4 Firefox versions', - 'last 4 Edge versions', - 'last 4 Safari versions', - 'last 4 Android versions', - 'last 4 ChromeAndroid versions', - 'last 4 FirefoxAndroid versions', - 'last 4 iOS versions' - ] - }) - - // https://github.com/elchininet/postcss-rtlcss - // If you want to support RTL css, then - // 1. yarn/npm install postcss-rtlcss - // 2. optionally set quasar.config.js > framework > lang to an RTL language - // 3. uncomment the following line: - // require('postcss-rtlcss') - ] -} diff --git a/ux/public/_assets/bg/login.jpg b/ux/public/_assets/bg/login.jpg deleted file mode 100644 index 58367b266..000000000 Binary files a/ux/public/_assets/bg/login.jpg and /dev/null differ diff --git a/ux/public/_assets/fonts/roboto-mono/roboto-mono.woff2 b/ux/public/_assets/fonts/roboto-mono/roboto-mono.woff2 deleted file mode 100644 index 213e0cc28..000000000 Binary files a/ux/public/_assets/fonts/roboto-mono/roboto-mono.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/roboto/roboto-all-300.woff2 b/ux/public/_assets/fonts/roboto/roboto-all-300.woff2 deleted file mode 100644 index dd8320812..000000000 Binary files a/ux/public/_assets/fonts/roboto/roboto-all-300.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/roboto/roboto-all-500.woff2 b/ux/public/_assets/fonts/roboto/roboto-all-500.woff2 deleted file mode 100644 index 0c5ede003..000000000 Binary files a/ux/public/_assets/fonts/roboto/roboto-all-500.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/roboto/roboto-all-700.woff2 b/ux/public/_assets/fonts/roboto/roboto-all-700.woff2 deleted file mode 100644 index 90e504f0c..000000000 Binary files a/ux/public/_assets/fonts/roboto/roboto-all-700.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/roboto/roboto-all-900.woff2 b/ux/public/_assets/fonts/roboto/roboto-all-900.woff2 deleted file mode 100644 index c3938e1ce..000000000 Binary files a/ux/public/_assets/fonts/roboto/roboto-all-900.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/roboto/roboto-all-regular.woff2 b/ux/public/_assets/fonts/roboto/roboto-all-regular.woff2 deleted file mode 100644 index f7a80a01b..000000000 Binary files a/ux/public/_assets/fonts/roboto/roboto-all-regular.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/roboto/roboto.css b/ux/public/_assets/fonts/roboto/roboto.css deleted file mode 100644 index 9354507c6..000000000 --- a/ux/public/_assets/fonts/roboto/roboto.css +++ /dev/null @@ -1,40 +0,0 @@ -/* roboto-300 - vietnamese_latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local(''), - url('/_assets/fonts/roboto/roboto-all-300.woff2') format('woff2') -} -/* roboto-regular - vietnamese_latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local(''), - url('/_assets/fonts/roboto/roboto-all-regular.woff2') format('woff2') -} -/* roboto-500 - vietnamese_latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local(''), - url('/_assets/fonts/roboto/roboto-all-500.woff2') format('woff2') -} -/* roboto-700 - vietnamese_latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local(''), - url('/_assets/fonts/roboto/roboto-all-700.woff2') format('woff2') -} -/* roboto-900 - vietnamese_latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 900; - src: local(''), - url('/_assets/fonts/roboto/roboto-all-900.woff2') format('woff2') -} diff --git a/ux/public/_assets/fonts/rubik/rubik-variable-cyrillic-ext.woff2 b/ux/public/_assets/fonts/rubik/rubik-variable-cyrillic-ext.woff2 deleted file mode 100644 index a5a8edc97..000000000 Binary files a/ux/public/_assets/fonts/rubik/rubik-variable-cyrillic-ext.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/rubik/rubik-variable-cyrillic.woff2 b/ux/public/_assets/fonts/rubik/rubik-variable-cyrillic.woff2 deleted file mode 100644 index fa2eee0c7..000000000 Binary files a/ux/public/_assets/fonts/rubik/rubik-variable-cyrillic.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/rubik/rubik-variable-hebrew.woff2 b/ux/public/_assets/fonts/rubik/rubik-variable-hebrew.woff2 deleted file mode 100644 index d51ce7386..000000000 Binary files a/ux/public/_assets/fonts/rubik/rubik-variable-hebrew.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/rubik/rubik-variable-latin-ext.woff2 b/ux/public/_assets/fonts/rubik/rubik-variable-latin-ext.woff2 deleted file mode 100644 index 9961a9b14..000000000 Binary files a/ux/public/_assets/fonts/rubik/rubik-variable-latin-ext.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/rubik/rubik-variable-latin.woff2 b/ux/public/_assets/fonts/rubik/rubik-variable-latin.woff2 deleted file mode 100644 index f9ec108bd..000000000 Binary files a/ux/public/_assets/fonts/rubik/rubik-variable-latin.woff2 and /dev/null differ diff --git a/ux/public/_assets/fonts/rubik/rubik.css b/ux/public/_assets/fonts/rubik/rubik.css deleted file mode 100644 index 243565505..000000000 --- a/ux/public/_assets/fonts/rubik/rubik.css +++ /dev/null @@ -1,39 +0,0 @@ -/* cyrillic-ext */ -@font-face { - font-family: 'Rubik'; - font-display: swap; - src: url(/_assets/fonts/rubik/rubik-variable-cyrillic-ext.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; -} -/* cyrillic */ -@font-face { - font-family: 'Rubik'; - font-display: swap; - src: url(/_assets/fonts/rubik/rubik-variable-cyrillic.woff2) format('woff2'); - unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* hebrew */ -@font-face { - font-family: 'Rubik'; - font-display: swap; - src: url(/_assets/fonts/rubik/rubik-variable-hebrew.woff2) format('woff2'); - unicode-range: U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F; -} -/* latin-ext */ -@font-face { - font-family: 'Rubik'; - font-display: swap; - src: url(/_assets/fonts/rubik/rubik-variable-latin-ext.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Rubik'; - font-display: swap; - src: url(/_assets/fonts/rubik/rubik-variable-latin.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} - -body.wiki-root { - font-family: 'Rubik', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; -} diff --git a/ux/public/_assets/icons/anim-book.png b/ux/public/_assets/icons/anim-book.png deleted file mode 100644 index 1da2dad43..000000000 Binary files a/ux/public/_assets/icons/anim-book.png and /dev/null differ diff --git a/ux/public/_assets/icons/carbon-copy-empty-box.svg b/ux/public/_assets/icons/carbon-copy-empty-box.svg deleted file mode 100644 index 2d018143c..000000000 --- a/ux/public/_assets/icons/carbon-copy-empty-box.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-7zip.svg b/ux/public/_assets/icons/color-7zip.svg deleted file mode 100644 index 8f2d93b6c..000000000 --- a/ux/public/_assets/icons/color-7zip.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-aac.svg b/ux/public/_assets/icons/color-aac.svg deleted file mode 100644 index 311754cc7..000000000 --- a/ux/public/_assets/icons/color-aac.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-ai.svg b/ux/public/_assets/icons/color-ai.svg deleted file mode 100644 index 8ed984d28..000000000 --- a/ux/public/_assets/icons/color-ai.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-apk.svg b/ux/public/_assets/icons/color-apk.svg deleted file mode 100644 index eff1bb8ff..000000000 --- a/ux/public/_assets/icons/color-apk.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-archive.svg b/ux/public/_assets/icons/color-archive.svg deleted file mode 100644 index 14b1316fa..000000000 --- a/ux/public/_assets/icons/color-archive.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-audio-file.svg b/ux/public/_assets/icons/color-audio-file.svg deleted file mode 100644 index a6850cc41..000000000 --- a/ux/public/_assets/icons/color-audio-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-avi.svg b/ux/public/_assets/icons/color-avi.svg deleted file mode 100644 index b071d54fb..000000000 --- a/ux/public/_assets/icons/color-avi.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-binary-file.svg b/ux/public/_assets/icons/color-binary-file.svg deleted file mode 100644 index 41763c9e8..000000000 --- a/ux/public/_assets/icons/color-binary-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-blog.svg b/ux/public/_assets/icons/color-blog.svg deleted file mode 100644 index 49f8cd0a8..000000000 --- a/ux/public/_assets/icons/color-blog.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-cd.svg b/ux/public/_assets/icons/color-cd.svg deleted file mode 100644 index 59fb44529..000000000 --- a/ux/public/_assets/icons/color-cd.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-code-file.svg b/ux/public/_assets/icons/color-code-file.svg deleted file mode 100644 index feaf0067d..000000000 --- a/ux/public/_assets/icons/color-code-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-css-filetype.svg b/ux/public/_assets/icons/color-css-filetype.svg deleted file mode 100644 index bf077d120..000000000 --- a/ux/public/_assets/icons/color-css-filetype.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-csv.svg b/ux/public/_assets/icons/color-csv.svg deleted file mode 100644 index a0746e4e8..000000000 --- a/ux/public/_assets/icons/color-csv.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-data-grid.svg b/ux/public/_assets/icons/color-data-grid.svg deleted file mode 100644 index a2fbd8abd..000000000 --- a/ux/public/_assets/icons/color-data-grid.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-data-pending.svg b/ux/public/_assets/icons/color-data-pending.svg deleted file mode 100644 index b6c205244..000000000 --- a/ux/public/_assets/icons/color-data-pending.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-dmg.svg b/ux/public/_assets/icons/color-dmg.svg deleted file mode 100644 index fbe3e0c26..000000000 --- a/ux/public/_assets/icons/color-dmg.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-doc.svg b/ux/public/_assets/icons/color-doc.svg deleted file mode 100644 index 1d31eeef3..000000000 --- a/ux/public/_assets/icons/color-doc.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-document.svg b/ux/public/_assets/icons/color-document.svg deleted file mode 100644 index 069015baa..000000000 --- a/ux/public/_assets/icons/color-document.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-documents.svg b/ux/public/_assets/icons/color-documents.svg deleted file mode 100644 index 3eda1e7cd..000000000 --- a/ux/public/_assets/icons/color-documents.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-exe.svg b/ux/public/_assets/icons/color-exe.svg deleted file mode 100644 index d3b0533c4..000000000 --- a/ux/public/_assets/icons/color-exe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-gif.svg b/ux/public/_assets/icons/color-gif.svg deleted file mode 100644 index 7ccf47d93..000000000 --- a/ux/public/_assets/icons/color-gif.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-image-file.svg b/ux/public/_assets/icons/color-image-file.svg deleted file mode 100644 index 72bd0f22c..000000000 --- a/ux/public/_assets/icons/color-image-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-jpg.svg b/ux/public/_assets/icons/color-jpg.svg deleted file mode 100644 index 244706ee7..000000000 --- a/ux/public/_assets/icons/color-jpg.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-json.svg b/ux/public/_assets/icons/color-json.svg deleted file mode 100644 index 7464b4422..000000000 --- a/ux/public/_assets/icons/color-json.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-mov.svg b/ux/public/_assets/icons/color-mov.svg deleted file mode 100644 index fec349f18..000000000 --- a/ux/public/_assets/icons/color-mov.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-mp3.svg b/ux/public/_assets/icons/color-mp3.svg deleted file mode 100644 index a6ae44853..000000000 --- a/ux/public/_assets/icons/color-mp3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-mpg.svg b/ux/public/_assets/icons/color-mpg.svg deleted file mode 100644 index 2f96faca4..000000000 --- a/ux/public/_assets/icons/color-mpg.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-nodejs.svg b/ux/public/_assets/icons/color-nodejs.svg deleted file mode 100644 index d7814ddbd..000000000 --- a/ux/public/_assets/icons/color-nodejs.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-ogg.svg b/ux/public/_assets/icons/color-ogg.svg deleted file mode 100644 index 10f084c16..000000000 --- a/ux/public/_assets/icons/color-ogg.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-otf.svg b/ux/public/_assets/icons/color-otf.svg deleted file mode 100644 index 8fd59e72e..000000000 --- a/ux/public/_assets/icons/color-otf.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-pdf.svg b/ux/public/_assets/icons/color-pdf.svg deleted file mode 100644 index 3c22eb0c0..000000000 --- a/ux/public/_assets/icons/color-pdf.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-png.svg b/ux/public/_assets/icons/color-png.svg deleted file mode 100644 index d84936912..000000000 --- a/ux/public/_assets/icons/color-png.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-postgresql.svg b/ux/public/_assets/icons/color-postgresql.svg deleted file mode 100644 index 1b8115742..000000000 --- a/ux/public/_assets/icons/color-postgresql.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-ppt.svg b/ux/public/_assets/icons/color-ppt.svg deleted file mode 100644 index 9d6234ab1..000000000 --- a/ux/public/_assets/icons/color-ppt.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-psd.svg b/ux/public/_assets/icons/color-psd.svg deleted file mode 100644 index 0ac657111..000000000 --- a/ux/public/_assets/icons/color-psd.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-rar.svg b/ux/public/_assets/icons/color-rar.svg deleted file mode 100644 index 091683f65..000000000 --- a/ux/public/_assets/icons/color-rar.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-schedule.svg b/ux/public/_assets/icons/color-schedule.svg deleted file mode 100644 index 68bbf5103..000000000 --- a/ux/public/_assets/icons/color-schedule.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-tar.svg b/ux/public/_assets/icons/color-tar.svg deleted file mode 100644 index a056b143a..000000000 --- a/ux/public/_assets/icons/color-tar.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-tif.svg b/ux/public/_assets/icons/color-tif.svg deleted file mode 100644 index 11bba8564..000000000 --- a/ux/public/_assets/icons/color-tif.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-ttf.svg b/ux/public/_assets/icons/color-ttf.svg deleted file mode 100644 index 2c3fd1c98..000000000 --- a/ux/public/_assets/icons/color-ttf.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-txt.svg b/ux/public/_assets/icons/color-txt.svg deleted file mode 100644 index 49b0e5f27..000000000 --- a/ux/public/_assets/icons/color-txt.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-video-file.svg b/ux/public/_assets/icons/color-video-file.svg deleted file mode 100644 index 963d94e71..000000000 --- a/ux/public/_assets/icons/color-video-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-wav.svg b/ux/public/_assets/icons/color-wav.svg deleted file mode 100644 index df2aa2301..000000000 --- a/ux/public/_assets/icons/color-wav.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-woff.svg b/ux/public/_assets/icons/color-woff.svg deleted file mode 100644 index f2653cc2c..000000000 --- a/ux/public/_assets/icons/color-woff.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-word.svg b/ux/public/_assets/icons/color-word.svg deleted file mode 100644 index a25df3397..000000000 --- a/ux/public/_assets/icons/color-word.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-xls.svg b/ux/public/_assets/icons/color-xls.svg deleted file mode 100644 index c2637d197..000000000 --- a/ux/public/_assets/icons/color-xls.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-xml-file.svg b/ux/public/_assets/icons/color-xml-file.svg deleted file mode 100644 index 7ba25788e..000000000 --- a/ux/public/_assets/icons/color-xml-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/color-zip.svg b/ux/public/_assets/icons/color-zip.svg deleted file mode 100644 index 194d12b94..000000000 --- a/ux/public/_assets/icons/color-zip.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-account.svg b/ux/public/_assets/icons/fluent-account.svg deleted file mode 100644 index eb2a574bc..000000000 --- a/ux/public/_assets/icons/fluent-account.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-add-key.svg b/ux/public/_assets/icons/fluent-add-key.svg deleted file mode 100644 index 9920976ad..000000000 --- a/ux/public/_assets/icons/fluent-add-key.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-advance.svg b/ux/public/_assets/icons/fluent-advance.svg deleted file mode 100644 index 14259474b..000000000 --- a/ux/public/_assets/icons/fluent-advance.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-api.svg b/ux/public/_assets/icons/fluent-api.svg deleted file mode 100644 index 247028a4b..000000000 --- a/ux/public/_assets/icons/fluent-api.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-apps-tab.svg b/ux/public/_assets/icons/fluent-apps-tab.svg deleted file mode 100644 index 468099478..000000000 --- a/ux/public/_assets/icons/fluent-apps-tab.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-bar-chart.svg b/ux/public/_assets/icons/fluent-bar-chart.svg deleted file mode 100644 index 361def4dc..000000000 --- a/ux/public/_assets/icons/fluent-bar-chart.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-bot-animated.svg b/ux/public/_assets/icons/fluent-bot-animated.svg deleted file mode 100644 index 5dca9ef45..000000000 --- a/ux/public/_assets/icons/fluent-bot-animated.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-bot.svg b/ux/public/_assets/icons/fluent-bot.svg deleted file mode 100644 index a623e223d..000000000 --- a/ux/public/_assets/icons/fluent-bot.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-bunch-of-keys.svg b/ux/public/_assets/icons/fluent-bunch-of-keys.svg deleted file mode 100644 index 733563983..000000000 --- a/ux/public/_assets/icons/fluent-bunch-of-keys.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-bursts.svg b/ux/public/_assets/icons/fluent-bursts.svg deleted file mode 100644 index 76c96fc02..000000000 --- a/ux/public/_assets/icons/fluent-bursts.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-cashbook.svg b/ux/public/_assets/icons/fluent-cashbook.svg deleted file mode 100644 index e2928a1b8..000000000 --- a/ux/public/_assets/icons/fluent-cashbook.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-change-theme.svg b/ux/public/_assets/icons/fluent-change-theme.svg deleted file mode 100644 index ae36332b6..000000000 --- a/ux/public/_assets/icons/fluent-change-theme.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-choose.svg b/ux/public/_assets/icons/fluent-choose.svg deleted file mode 100644 index c446c7520..000000000 --- a/ux/public/_assets/icons/fluent-choose.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-code.svg b/ux/public/_assets/icons/fluent-code.svg deleted file mode 100644 index 85a9ccc21..000000000 --- a/ux/public/_assets/icons/fluent-code.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-color-wheel.svg b/ux/public/_assets/icons/fluent-color-wheel.svg deleted file mode 100644 index 87410e469..000000000 --- a/ux/public/_assets/icons/fluent-color-wheel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-comments.svg b/ux/public/_assets/icons/fluent-comments.svg deleted file mode 100644 index 77be6513b..000000000 --- a/ux/public/_assets/icons/fluent-comments.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-database.svg b/ux/public/_assets/icons/fluent-database.svg deleted file mode 100644 index 78bf74539..000000000 --- a/ux/public/_assets/icons/fluent-database.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-delete-bin.svg b/ux/public/_assets/icons/fluent-delete-bin.svg deleted file mode 100644 index 252ee3037..000000000 --- a/ux/public/_assets/icons/fluent-delete-bin.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-down.svg b/ux/public/_assets/icons/fluent-down.svg deleted file mode 100644 index 7d4cb5c56..000000000 --- a/ux/public/_assets/icons/fluent-down.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-downloading-updates.svg b/ux/public/_assets/icons/fluent-downloading-updates.svg deleted file mode 100644 index 346e96808..000000000 --- a/ux/public/_assets/icons/fluent-downloading-updates.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-event-log.svg b/ux/public/_assets/icons/fluent-event-log.svg deleted file mode 100644 index bfad419b7..000000000 --- a/ux/public/_assets/icons/fluent-event-log.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-fantasy.svg b/ux/public/_assets/icons/fluent-fantasy.svg deleted file mode 100644 index d5e24ebee..000000000 --- a/ux/public/_assets/icons/fluent-fantasy.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-female-working-with-a-laptop.svg b/ux/public/_assets/icons/fluent-female-working-with-a-laptop.svg deleted file mode 100644 index 35a1ea264..000000000 --- a/ux/public/_assets/icons/fluent-female-working-with-a-laptop.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-find-and-replace.svg b/ux/public/_assets/icons/fluent-find-and-replace.svg deleted file mode 100644 index f74b10ac2..000000000 --- a/ux/public/_assets/icons/fluent-find-and-replace.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-fingerprint.svg b/ux/public/_assets/icons/fluent-fingerprint.svg deleted file mode 100644 index b335cd746..000000000 --- a/ux/public/_assets/icons/fluent-fingerprint.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-firewall.svg b/ux/public/_assets/icons/fluent-firewall.svg deleted file mode 100644 index 61a7502dd..000000000 --- a/ux/public/_assets/icons/fluent-firewall.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-folder-tree.svg b/ux/public/_assets/icons/fluent-folder-tree.svg deleted file mode 100644 index 4248e3089..000000000 --- a/ux/public/_assets/icons/fluent-folder-tree.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-folder.svg b/ux/public/_assets/icons/fluent-folder.svg deleted file mode 100644 index e899ab936..000000000 --- a/ux/public/_assets/icons/fluent-folder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-ftp.svg b/ux/public/_assets/icons/fluent-ftp.svg deleted file mode 100644 index 2ecc28545..000000000 --- a/ux/public/_assets/icons/fluent-ftp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-graph.svg b/ux/public/_assets/icons/fluent-graph.svg deleted file mode 100644 index ce8f29cf6..000000000 --- a/ux/public/_assets/icons/fluent-graph.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-inspection.svg b/ux/public/_assets/icons/fluent-inspection.svg deleted file mode 100644 index 214eb812d..000000000 --- a/ux/public/_assets/icons/fluent-inspection.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-key-2.svg b/ux/public/_assets/icons/fluent-key-2.svg deleted file mode 100644 index 44d16ad2f..000000000 --- a/ux/public/_assets/icons/fluent-key-2.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-language.svg b/ux/public/_assets/icons/fluent-language.svg deleted file mode 100644 index 05b1f8bf4..000000000 --- a/ux/public/_assets/icons/fluent-language.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-lightning-bolt.svg b/ux/public/_assets/icons/fluent-lightning-bolt.svg deleted file mode 100644 index 3ee3fcc36..000000000 --- a/ux/public/_assets/icons/fluent-lightning-bolt.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-linux-terminal-animated.svg b/ux/public/_assets/icons/fluent-linux-terminal-animated.svg deleted file mode 100644 index 770515eec..000000000 --- a/ux/public/_assets/icons/fluent-linux-terminal-animated.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-linux-terminal.svg b/ux/public/_assets/icons/fluent-linux-terminal.svg deleted file mode 100644 index fc1a6a65b..000000000 --- a/ux/public/_assets/icons/fluent-linux-terminal.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-markdown.svg b/ux/public/_assets/icons/fluent-markdown.svg deleted file mode 100644 index be0a381a0..000000000 --- a/ux/public/_assets/icons/fluent-markdown.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-message-settings-animated.svg b/ux/public/_assets/icons/fluent-message-settings-animated.svg deleted file mode 100644 index 2d8d25626..000000000 --- a/ux/public/_assets/icons/fluent-message-settings-animated.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-message-settings.svg b/ux/public/_assets/icons/fluent-message-settings.svg deleted file mode 100644 index ff180bfba..000000000 --- a/ux/public/_assets/icons/fluent-message-settings.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-module.svg b/ux/public/_assets/icons/fluent-module.svg deleted file mode 100644 index 5d78233e7..000000000 --- a/ux/public/_assets/icons/fluent-module.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-network.svg b/ux/public/_assets/icons/fluent-network.svg deleted file mode 100644 index e6c3227cd..000000000 --- a/ux/public/_assets/icons/fluent-network.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-open-file-under-cursor.svg b/ux/public/_assets/icons/fluent-open-file-under-cursor.svg deleted file mode 100644 index f98373717..000000000 --- a/ux/public/_assets/icons/fluent-open-file-under-cursor.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-opened-folder.svg b/ux/public/_assets/icons/fluent-opened-folder.svg deleted file mode 100644 index 0ed6914cf..000000000 --- a/ux/public/_assets/icons/fluent-opened-folder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-paint-roller-animated.svg b/ux/public/_assets/icons/fluent-paint-roller-animated.svg deleted file mode 100644 index 5a9370430..000000000 --- a/ux/public/_assets/icons/fluent-paint-roller-animated.svg +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-paint-roller.svg b/ux/public/_assets/icons/fluent-paint-roller.svg deleted file mode 100644 index 81b810ac3..000000000 --- a/ux/public/_assets/icons/fluent-paint-roller.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-password-reset.svg b/ux/public/_assets/icons/fluent-password-reset.svg deleted file mode 100644 index 865f02458..000000000 --- a/ux/public/_assets/icons/fluent-password-reset.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-pencil-drawing.svg b/ux/public/_assets/icons/fluent-pencil-drawing.svg deleted file mode 100644 index fdb425c7e..000000000 --- a/ux/public/_assets/icons/fluent-pencil-drawing.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-people.svg b/ux/public/_assets/icons/fluent-people.svg deleted file mode 100644 index 84563530a..000000000 --- a/ux/public/_assets/icons/fluent-people.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-plus-plus.svg b/ux/public/_assets/icons/fluent-plus-plus.svg deleted file mode 100644 index 03d530ac6..000000000 --- a/ux/public/_assets/icons/fluent-plus-plus.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-processor.svg b/ux/public/_assets/icons/fluent-processor.svg deleted file mode 100644 index 64b4becd6..000000000 --- a/ux/public/_assets/icons/fluent-processor.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-protect.svg b/ux/public/_assets/icons/fluent-protect.svg deleted file mode 100644 index 84c0bf672..000000000 --- a/ux/public/_assets/icons/fluent-protect.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-query.svg b/ux/public/_assets/icons/fluent-query.svg deleted file mode 100644 index a893f9b61..000000000 --- a/ux/public/_assets/icons/fluent-query.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-rename.svg b/ux/public/_assets/icons/fluent-rename.svg deleted file mode 100644 index e8edc77db..000000000 --- a/ux/public/_assets/icons/fluent-rename.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-rest-api-animated.svg b/ux/public/_assets/icons/fluent-rest-api-animated.svg deleted file mode 100644 index e684aa6aa..000000000 --- a/ux/public/_assets/icons/fluent-rest-api-animated.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-rest-api.svg b/ux/public/_assets/icons/fluent-rest-api.svg deleted file mode 100644 index 5afb29d5d..000000000 --- a/ux/public/_assets/icons/fluent-rest-api.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-rfid-tag.svg b/ux/public/_assets/icons/fluent-rfid-tag.svg deleted file mode 100644 index 2ec98bf71..000000000 --- a/ux/public/_assets/icons/fluent-rfid-tag.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-rich-text-converter.svg b/ux/public/_assets/icons/fluent-rich-text-converter.svg deleted file mode 100644 index 733836557..000000000 --- a/ux/public/_assets/icons/fluent-rich-text-converter.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-save-as.svg b/ux/public/_assets/icons/fluent-save-as.svg deleted file mode 100644 index 496f2ba0d..000000000 --- a/ux/public/_assets/icons/fluent-save-as.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-security-lock.svg b/ux/public/_assets/icons/fluent-security-lock.svg deleted file mode 100644 index b45228e44..000000000 --- a/ux/public/_assets/icons/fluent-security-lock.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-security-ssl.svg b/ux/public/_assets/icons/fluent-security-ssl.svg deleted file mode 100644 index e0c7dcbc3..000000000 --- a/ux/public/_assets/icons/fluent-security-ssl.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-shutdown.svg b/ux/public/_assets/icons/fluent-shutdown.svg deleted file mode 100644 index 5c384dff8..000000000 --- a/ux/public/_assets/icons/fluent-shutdown.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-sidebar-menu.svg b/ux/public/_assets/icons/fluent-sidebar-menu.svg deleted file mode 100644 index 2b7d00c76..000000000 --- a/ux/public/_assets/icons/fluent-sidebar-menu.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-spring.svg b/ux/public/_assets/icons/fluent-spring.svg deleted file mode 100644 index 52e0f0307..000000000 --- a/ux/public/_assets/icons/fluent-spring.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-ssd-animated.svg b/ux/public/_assets/icons/fluent-ssd-animated.svg deleted file mode 100644 index 43e1cb9d3..000000000 --- a/ux/public/_assets/icons/fluent-ssd-animated.svg +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-ssd.svg b/ux/public/_assets/icons/fluent-ssd.svg deleted file mode 100644 index 79baeaf3d..000000000 --- a/ux/public/_assets/icons/fluent-ssd.svg +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/fluent-swiss-army-knife.svg b/ux/public/_assets/icons/fluent-swiss-army-knife.svg deleted file mode 100644 index 1087649b9..000000000 --- a/ux/public/_assets/icons/fluent-swiss-army-knife.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-tag.svg b/ux/public/_assets/icons/fluent-tag.svg deleted file mode 100644 index 0d873492f..000000000 --- a/ux/public/_assets/icons/fluent-tag.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-template.svg b/ux/public/_assets/icons/fluent-template.svg deleted file mode 100644 index f7323f2fd..000000000 --- a/ux/public/_assets/icons/fluent-template.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-tree-structure.svg b/ux/public/_assets/icons/fluent-tree-structure.svg deleted file mode 100644 index 835a1f478..000000000 --- a/ux/public/_assets/icons/fluent-tree-structure.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-unavailable.svg b/ux/public/_assets/icons/fluent-unavailable.svg deleted file mode 100644 index 12e86013a..000000000 --- a/ux/public/_assets/icons/fluent-unavailable.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-upload.svg b/ux/public/_assets/icons/fluent-upload.svg deleted file mode 100644 index 0c4d998d8..000000000 --- a/ux/public/_assets/icons/fluent-upload.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-web.svg b/ux/public/_assets/icons/fluent-web.svg deleted file mode 100644 index 5f8ae0f5f..000000000 --- a/ux/public/_assets/icons/fluent-web.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/fluent-windsock.svg b/ux/public/_assets/icons/fluent-windsock.svg deleted file mode 100644 index eef7c8db6..000000000 --- a/ux/public/_assets/icons/fluent-windsock.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-3d-touch.svg b/ux/public/_assets/icons/ultraviolet-3d-touch.svg deleted file mode 100644 index 1e5307307..000000000 --- a/ux/public/_assets/icons/ultraviolet-3d-touch.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-access.svg b/ux/public/_assets/icons/ultraviolet-access.svg deleted file mode 100644 index 8dd18aa17..000000000 --- a/ux/public/_assets/icons/ultraviolet-access.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-add-folder.svg b/ux/public/_assets/icons/ultraviolet-add-folder.svg deleted file mode 100644 index 5c6cbbe22..000000000 --- a/ux/public/_assets/icons/ultraviolet-add-folder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-add-image.svg b/ux/public/_assets/icons/ultraviolet-add-image.svg deleted file mode 100644 index 47caa6d03..000000000 --- a/ux/public/_assets/icons/ultraviolet-add-image.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-address.svg b/ux/public/_assets/icons/ultraviolet-address.svg deleted file mode 100644 index 1d61c96a5..000000000 --- a/ux/public/_assets/icons/ultraviolet-address.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-administrative-tools.svg b/ux/public/_assets/icons/ultraviolet-administrative-tools.svg deleted file mode 100644 index 9c924a188..000000000 --- a/ux/public/_assets/icons/ultraviolet-administrative-tools.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-administrator-male.svg b/ux/public/_assets/icons/ultraviolet-administrator-male.svg deleted file mode 100644 index 42bd18701..000000000 --- a/ux/public/_assets/icons/ultraviolet-administrator-male.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-advance.svg b/ux/public/_assets/icons/ultraviolet-advance.svg deleted file mode 100644 index 8c48405a7..000000000 --- a/ux/public/_assets/icons/ultraviolet-advance.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-amazon-web-services.svg b/ux/public/_assets/icons/ultraviolet-amazon-web-services.svg deleted file mode 100644 index 5ebd14e97..000000000 --- a/ux/public/_assets/icons/ultraviolet-amazon-web-services.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-amazon.svg b/ux/public/_assets/icons/ultraviolet-amazon.svg deleted file mode 100644 index 798a682cf..000000000 --- a/ux/public/_assets/icons/ultraviolet-amazon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-api.svg b/ux/public/_assets/icons/ultraviolet-api.svg deleted file mode 100644 index 03ec242e3..000000000 --- a/ux/public/_assets/icons/ultraviolet-api.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-apple-logo.svg b/ux/public/_assets/icons/ultraviolet-apple-logo.svg deleted file mode 100644 index b243ef49b..000000000 --- a/ux/public/_assets/icons/ultraviolet-apple-logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-apply.svg b/ux/public/_assets/icons/ultraviolet-apply.svg deleted file mode 100644 index 75c8c5430..000000000 --- a/ux/public/_assets/icons/ultraviolet-apply.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-archive-folder.svg b/ux/public/_assets/icons/ultraviolet-archive-folder.svg deleted file mode 100644 index 4a25278c7..000000000 --- a/ux/public/_assets/icons/ultraviolet-archive-folder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-asciidoc.svg b/ux/public/_assets/icons/ultraviolet-asciidoc.svg deleted file mode 100644 index b423da0b9..000000000 --- a/ux/public/_assets/icons/ultraviolet-asciidoc.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-asterisk.svg b/ux/public/_assets/icons/ultraviolet-asterisk.svg deleted file mode 100644 index 8d8ce9b61..000000000 --- a/ux/public/_assets/icons/ultraviolet-asterisk.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-auth0.svg b/ux/public/_assets/icons/ultraviolet-auth0.svg deleted file mode 100644 index 801cbd267..000000000 --- a/ux/public/_assets/icons/ultraviolet-auth0.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-automation.svg b/ux/public/_assets/icons/ultraviolet-automation.svg deleted file mode 100644 index d75f01190..000000000 --- a/ux/public/_assets/icons/ultraviolet-automation.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-azure.svg b/ux/public/_assets/icons/ultraviolet-azure.svg deleted file mode 100644 index 250e2d799..000000000 --- a/ux/public/_assets/icons/ultraviolet-azure.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-back.svg b/ux/public/_assets/icons/ultraviolet-back.svg deleted file mode 100644 index 1a6c816b8..000000000 --- a/ux/public/_assets/icons/ultraviolet-back.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-binary-file.svg b/ux/public/_assets/icons/ultraviolet-binary-file.svg deleted file mode 100644 index bd613c8c7..000000000 --- a/ux/public/_assets/icons/ultraviolet-binary-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-bot.svg b/ux/public/_assets/icons/ultraviolet-bot.svg deleted file mode 100644 index 060f66de7..000000000 --- a/ux/public/_assets/icons/ultraviolet-bot.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-breakable.svg b/ux/public/_assets/icons/ultraviolet-breakable.svg deleted file mode 100644 index 4fc065535..000000000 --- a/ux/public/_assets/icons/ultraviolet-breakable.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-brick.svg b/ux/public/_assets/icons/ultraviolet-brick.svg deleted file mode 100644 index 521e18c3c..000000000 --- a/ux/public/_assets/icons/ultraviolet-brick.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-building.svg b/ux/public/_assets/icons/ultraviolet-building.svg deleted file mode 100644 index a8fddbc02..000000000 --- a/ux/public/_assets/icons/ultraviolet-building.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-butterfly.svg b/ux/public/_assets/icons/ultraviolet-butterfly.svg deleted file mode 100644 index 192912ec7..000000000 --- a/ux/public/_assets/icons/ultraviolet-butterfly.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-calendar-plus.svg b/ux/public/_assets/icons/ultraviolet-calendar-plus.svg deleted file mode 100644 index de8172195..000000000 --- a/ux/public/_assets/icons/ultraviolet-calendar-plus.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-calendar.svg b/ux/public/_assets/icons/ultraviolet-calendar.svg deleted file mode 100644 index ba53ca89f..000000000 --- a/ux/public/_assets/icons/ultraviolet-calendar.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-cellular-network.svg b/ux/public/_assets/icons/ultraviolet-cellular-network.svg deleted file mode 100644 index 03c3d5dbe..000000000 --- a/ux/public/_assets/icons/ultraviolet-cellular-network.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-chat.svg b/ux/public/_assets/icons/ultraviolet-chat.svg deleted file mode 100644 index 3a09f7a75..000000000 --- a/ux/public/_assets/icons/ultraviolet-chat.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-chevron-right.svg b/ux/public/_assets/icons/ultraviolet-chevron-right.svg deleted file mode 100644 index c06de1947..000000000 --- a/ux/public/_assets/icons/ultraviolet-chevron-right.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-clock.svg b/ux/public/_assets/icons/ultraviolet-clock.svg deleted file mode 100644 index bb75f4c89..000000000 --- a/ux/public/_assets/icons/ultraviolet-clock.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-close-pane.svg b/ux/public/_assets/icons/ultraviolet-close-pane.svg deleted file mode 100644 index 72c2f0e0b..000000000 --- a/ux/public/_assets/icons/ultraviolet-close-pane.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-cloud-checked.svg b/ux/public/_assets/icons/ultraviolet-cloud-checked.svg deleted file mode 100644 index c8714a69b..000000000 --- a/ux/public/_assets/icons/ultraviolet-cloud-checked.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-code-file.svg b/ux/public/_assets/icons/ultraviolet-code-file.svg deleted file mode 100644 index 022237dc3..000000000 --- a/ux/public/_assets/icons/ultraviolet-code-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-code-fork.svg b/ux/public/_assets/icons/ultraviolet-code-fork.svg deleted file mode 100644 index 7b029a677..000000000 --- a/ux/public/_assets/icons/ultraviolet-code-fork.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-code.svg b/ux/public/_assets/icons/ultraviolet-code.svg deleted file mode 100644 index 1db66db69..000000000 --- a/ux/public/_assets/icons/ultraviolet-code.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-comments.svg b/ux/public/_assets/icons/ultraviolet-comments.svg deleted file mode 100644 index af1119f14..000000000 --- a/ux/public/_assets/icons/ultraviolet-comments.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-computer.svg b/ux/public/_assets/icons/ultraviolet-computer.svg deleted file mode 100644 index 9061692d0..000000000 --- a/ux/public/_assets/icons/ultraviolet-computer.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-confusion.svg b/ux/public/_assets/icons/ultraviolet-confusion.svg deleted file mode 100644 index 458bf3bec..000000000 --- a/ux/public/_assets/icons/ultraviolet-confusion.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-contact.svg b/ux/public/_assets/icons/ultraviolet-contact.svg deleted file mode 100644 index 209bec4bc..000000000 --- a/ux/public/_assets/icons/ultraviolet-contact.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-cookies.svg b/ux/public/_assets/icons/ultraviolet-cookies.svg deleted file mode 100644 index c4a81e821..000000000 --- a/ux/public/_assets/icons/ultraviolet-cookies.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-copyright.svg b/ux/public/_assets/icons/ultraviolet-copyright.svg deleted file mode 100644 index 06796307f..000000000 --- a/ux/public/_assets/icons/ultraviolet-copyright.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-css.svg b/ux/public/_assets/icons/ultraviolet-css.svg deleted file mode 100644 index 7f5213a35..000000000 --- a/ux/public/_assets/icons/ultraviolet-css.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-curly-arrow.svg b/ux/public/_assets/icons/ultraviolet-curly-arrow.svg deleted file mode 100644 index 157530fc3..000000000 --- a/ux/public/_assets/icons/ultraviolet-curly-arrow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-customer.svg b/ux/public/_assets/icons/ultraviolet-customer.svg deleted file mode 100644 index 11bada100..000000000 --- a/ux/public/_assets/icons/ultraviolet-customer.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-data-protection.svg b/ux/public/_assets/icons/ultraviolet-data-protection.svg deleted file mode 100644 index 525cbe370..000000000 --- a/ux/public/_assets/icons/ultraviolet-data-protection.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-data-sheet.svg b/ux/public/_assets/icons/ultraviolet-data-sheet.svg deleted file mode 100644 index 6bc415335..000000000 --- a/ux/public/_assets/icons/ultraviolet-data-sheet.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-database-daily-export.svg b/ux/public/_assets/icons/ultraviolet-database-daily-export.svg deleted file mode 100644 index 5e3ed815f..000000000 --- a/ux/public/_assets/icons/ultraviolet-database-daily-export.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-database-daily-import.svg b/ux/public/_assets/icons/ultraviolet-database-daily-import.svg deleted file mode 100644 index 82225d636..000000000 --- a/ux/public/_assets/icons/ultraviolet-database-daily-import.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-database-export.svg b/ux/public/_assets/icons/ultraviolet-database-export.svg deleted file mode 100644 index a372e506c..000000000 --- a/ux/public/_assets/icons/ultraviolet-database-export.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-database-restore.svg b/ux/public/_assets/icons/ultraviolet-database-restore.svg deleted file mode 100644 index cd225db2b..000000000 --- a/ux/public/_assets/icons/ultraviolet-database-restore.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-database.svg b/ux/public/_assets/icons/ultraviolet-database.svg deleted file mode 100644 index e6183dab1..000000000 --- a/ux/public/_assets/icons/ultraviolet-database.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-datalake.svg b/ux/public/_assets/icons/ultraviolet-datalake.svg deleted file mode 100644 index 58398d9b0..000000000 --- a/ux/public/_assets/icons/ultraviolet-datalake.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-denied.svg b/ux/public/_assets/icons/ultraviolet-denied.svg deleted file mode 100644 index 83e809f49..000000000 --- a/ux/public/_assets/icons/ultraviolet-denied.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-depth.svg b/ux/public/_assets/icons/ultraviolet-depth.svg deleted file mode 100644 index 92a82d175..000000000 --- a/ux/public/_assets/icons/ultraviolet-depth.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-disconnected.svg b/ux/public/_assets/icons/ultraviolet-disconnected.svg deleted file mode 100644 index 47ed81fc6..000000000 --- a/ux/public/_assets/icons/ultraviolet-disconnected.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-discord.svg b/ux/public/_assets/icons/ultraviolet-discord.svg deleted file mode 100644 index 5f123ce86..000000000 --- a/ux/public/_assets/icons/ultraviolet-discord.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-discussion-forum.svg b/ux/public/_assets/icons/ultraviolet-discussion-forum.svg deleted file mode 100644 index 599903342..000000000 --- a/ux/public/_assets/icons/ultraviolet-discussion-forum.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-dns.svg b/ux/public/_assets/icons/ultraviolet-dns.svg deleted file mode 100644 index bc20cb427..000000000 --- a/ux/public/_assets/icons/ultraviolet-dns.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-do-not-touch.svg b/ux/public/_assets/icons/ultraviolet-do-not-touch.svg deleted file mode 100644 index aae9b6e35..000000000 --- a/ux/public/_assets/icons/ultraviolet-do-not-touch.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-docker-container.svg b/ux/public/_assets/icons/ultraviolet-docker-container.svg deleted file mode 100644 index 3820de095..000000000 --- a/ux/public/_assets/icons/ultraviolet-docker-container.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-door-sensor-alarmed.svg b/ux/public/_assets/icons/ultraviolet-door-sensor-alarmed.svg deleted file mode 100644 index 1b5234569..000000000 --- a/ux/public/_assets/icons/ultraviolet-door-sensor-alarmed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-double-right.svg b/ux/public/_assets/icons/ultraviolet-double-right.svg deleted file mode 100644 index 57f637d40..000000000 --- a/ux/public/_assets/icons/ultraviolet-double-right.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-download-from-cloud.svg b/ux/public/_assets/icons/ultraviolet-download-from-cloud.svg deleted file mode 100644 index 9d506238e..000000000 --- a/ux/public/_assets/icons/ultraviolet-download-from-cloud.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-downloads.svg b/ux/public/_assets/icons/ultraviolet-downloads.svg deleted file mode 100644 index e78ac223c..000000000 --- a/ux/public/_assets/icons/ultraviolet-downloads.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-dropbox.svg b/ux/public/_assets/icons/ultraviolet-dropbox.svg deleted file mode 100644 index fd9d5205d..000000000 --- a/ux/public/_assets/icons/ultraviolet-dropbox.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-duplicate.svg b/ux/public/_assets/icons/ultraviolet-duplicate.svg deleted file mode 100644 index d2697f4d0..000000000 --- a/ux/public/_assets/icons/ultraviolet-duplicate.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-email-open.svg b/ux/public/_assets/icons/ultraviolet-email-open.svg deleted file mode 100644 index 6cc6b6db5..000000000 --- a/ux/public/_assets/icons/ultraviolet-email-open.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-email.svg b/ux/public/_assets/icons/ultraviolet-email.svg deleted file mode 100644 index ccb35a504..000000000 --- a/ux/public/_assets/icons/ultraviolet-email.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-enter-key.svg b/ux/public/_assets/icons/ultraviolet-enter-key.svg deleted file mode 100644 index 94666e424..000000000 --- a/ux/public/_assets/icons/ultraviolet-enter-key.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-enter.svg b/ux/public/_assets/icons/ultraviolet-enter.svg deleted file mode 100644 index d46d59c5f..000000000 --- a/ux/public/_assets/icons/ultraviolet-enter.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-envelope.svg b/ux/public/_assets/icons/ultraviolet-envelope.svg deleted file mode 100644 index 93a65aaa9..000000000 --- a/ux/public/_assets/icons/ultraviolet-envelope.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-ethernet-off.svg b/ux/public/_assets/icons/ultraviolet-ethernet-off.svg deleted file mode 100644 index c4dc80231..000000000 --- a/ux/public/_assets/icons/ultraviolet-ethernet-off.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-exit.svg b/ux/public/_assets/icons/ultraviolet-exit.svg deleted file mode 100644 index e2d259d72..000000000 --- a/ux/public/_assets/icons/ultraviolet-exit.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-expired.svg b/ux/public/_assets/icons/ultraviolet-expired.svg deleted file mode 100644 index 7088ca8ae..000000000 --- a/ux/public/_assets/icons/ultraviolet-expired.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-explosion.svg b/ux/public/_assets/icons/ultraviolet-explosion.svg deleted file mode 100644 index db8b58d2e..000000000 --- a/ux/public/_assets/icons/ultraviolet-explosion.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-external-link.svg b/ux/public/_assets/icons/ultraviolet-external-link.svg deleted file mode 100644 index d763104ab..000000000 --- a/ux/public/_assets/icons/ultraviolet-external-link.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-facebook.svg b/ux/public/_assets/icons/ultraviolet-facebook.svg deleted file mode 100644 index d9aad53c9..000000000 --- a/ux/public/_assets/icons/ultraviolet-facebook.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-file-submodule.svg b/ux/public/_assets/icons/ultraviolet-file-submodule.svg deleted file mode 100644 index f2b4d87f7..000000000 --- a/ux/public/_assets/icons/ultraviolet-file-submodule.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-fill-color.svg b/ux/public/_assets/icons/ultraviolet-fill-color.svg deleted file mode 100644 index 1a84ac224..000000000 --- a/ux/public/_assets/icons/ultraviolet-fill-color.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-filtration.svg b/ux/public/_assets/icons/ultraviolet-filtration.svg deleted file mode 100644 index 2f33d9ca9..000000000 --- a/ux/public/_assets/icons/ultraviolet-filtration.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-fingerprint-scan.svg b/ux/public/_assets/icons/ultraviolet-fingerprint-scan.svg deleted file mode 100644 index 16d33d1b7..000000000 --- a/ux/public/_assets/icons/ultraviolet-fingerprint-scan.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-firewall.svg b/ux/public/_assets/icons/ultraviolet-firewall.svg deleted file mode 100644 index fb665978a..000000000 --- a/ux/public/_assets/icons/ultraviolet-firewall.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-flag-filled.svg b/ux/public/_assets/icons/ultraviolet-flag-filled.svg deleted file mode 100644 index ce3adc908..000000000 --- a/ux/public/_assets/icons/ultraviolet-flag-filled.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-folder.svg b/ux/public/_assets/icons/ultraviolet-folder.svg deleted file mode 100644 index 5326534ca..000000000 --- a/ux/public/_assets/icons/ultraviolet-folder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-fonts-app.svg b/ux/public/_assets/icons/ultraviolet-fonts-app.svg deleted file mode 100644 index fa45e6bf7..000000000 --- a/ux/public/_assets/icons/ultraviolet-fonts-app.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-full-image.svg b/ux/public/_assets/icons/ultraviolet-full-image.svg deleted file mode 100644 index c573a1489..000000000 --- a/ux/public/_assets/icons/ultraviolet-full-image.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-future.svg b/ux/public/_assets/icons/ultraviolet-future.svg deleted file mode 100644 index f0b59b7e9..000000000 --- a/ux/public/_assets/icons/ultraviolet-future.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-gender.svg b/ux/public/_assets/icons/ultraviolet-gender.svg deleted file mode 100644 index b5b04f0a7..000000000 --- a/ux/public/_assets/icons/ultraviolet-gender.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-genealogy.svg b/ux/public/_assets/icons/ultraviolet-genealogy.svg deleted file mode 100644 index ca54032e8..000000000 --- a/ux/public/_assets/icons/ultraviolet-genealogy.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-geography.svg b/ux/public/_assets/icons/ultraviolet-geography.svg deleted file mode 100644 index 3cee54e1b..000000000 --- a/ux/public/_assets/icons/ultraviolet-geography.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-git.svg b/ux/public/_assets/icons/ultraviolet-git.svg deleted file mode 100644 index 2310ddb14..000000000 --- a/ux/public/_assets/icons/ultraviolet-git.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-github.svg b/ux/public/_assets/icons/ultraviolet-github.svg deleted file mode 100644 index 25ae025fd..000000000 --- a/ux/public/_assets/icons/ultraviolet-github.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-gitlab.svg b/ux/public/_assets/icons/ultraviolet-gitlab.svg deleted file mode 100644 index c0fdee5ca..000000000 --- a/ux/public/_assets/icons/ultraviolet-gitlab.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-good-pincode.svg b/ux/public/_assets/icons/ultraviolet-good-pincode.svg deleted file mode 100644 index 04a4b2be6..000000000 --- a/ux/public/_assets/icons/ultraviolet-good-pincode.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-google-drive.svg b/ux/public/_assets/icons/ultraviolet-google-drive.svg deleted file mode 100644 index 63dd00a56..000000000 --- a/ux/public/_assets/icons/ultraviolet-google-drive.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-google-maps.svg b/ux/public/_assets/icons/ultraviolet-google-maps.svg deleted file mode 100644 index 4ed2e2473..000000000 --- a/ux/public/_assets/icons/ultraviolet-google-maps.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-google-presentation.svg b/ux/public/_assets/icons/ultraviolet-google-presentation.svg deleted file mode 100644 index 5fb85f70b..000000000 --- a/ux/public/_assets/icons/ultraviolet-google-presentation.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-google.svg b/ux/public/_assets/icons/ultraviolet-google.svg deleted file mode 100644 index bac7ed4bd..000000000 --- a/ux/public/_assets/icons/ultraviolet-google.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-grand-master-key.svg b/ux/public/_assets/icons/ultraviolet-grand-master-key.svg deleted file mode 100644 index 31bcefdc4..000000000 --- a/ux/public/_assets/icons/ultraviolet-grand-master-key.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-hdd.svg b/ux/public/_assets/icons/ultraviolet-hdd.svg deleted file mode 100644 index 9df08564c..000000000 --- a/ux/public/_assets/icons/ultraviolet-hdd.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-heart-outline.svg b/ux/public/_assets/icons/ultraviolet-heart-outline.svg deleted file mode 100644 index 1fddb0852..000000000 --- a/ux/public/_assets/icons/ultraviolet-heart-outline.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-hips.svg b/ux/public/_assets/icons/ultraviolet-hips.svg deleted file mode 100644 index b541fe5f0..000000000 --- a/ux/public/_assets/icons/ultraviolet-hips.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-historical.svg b/ux/public/_assets/icons/ultraviolet-historical.svg deleted file mode 100644 index 48b04f0cf..000000000 --- a/ux/public/_assets/icons/ultraviolet-historical.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-home.svg b/ux/public/_assets/icons/ultraviolet-home.svg deleted file mode 100644 index 71f5b7109..000000000 --- a/ux/public/_assets/icons/ultraviolet-home.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-html.svg b/ux/public/_assets/icons/ultraviolet-html.svg deleted file mode 100644 index 5d080f4a2..000000000 --- a/ux/public/_assets/icons/ultraviolet-html.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-image.svg b/ux/public/_assets/icons/ultraviolet-image.svg deleted file mode 100644 index c573a1489..000000000 --- a/ux/public/_assets/icons/ultraviolet-image.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-inbox.svg b/ux/public/_assets/icons/ultraviolet-inbox.svg deleted file mode 100644 index de260513b..000000000 --- a/ux/public/_assets/icons/ultraviolet-inbox.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-index.svg b/ux/public/_assets/icons/ultraviolet-index.svg deleted file mode 100644 index 3fb06c2f1..000000000 --- a/ux/public/_assets/icons/ultraviolet-index.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-info-popup.svg b/ux/public/_assets/icons/ultraviolet-info-popup.svg deleted file mode 100644 index 959d4c399..000000000 --- a/ux/public/_assets/icons/ultraviolet-info-popup.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-information.svg b/ux/public/_assets/icons/ultraviolet-information.svg deleted file mode 100644 index 9e6920ff6..000000000 --- a/ux/public/_assets/icons/ultraviolet-information.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-internet.svg b/ux/public/_assets/icons/ultraviolet-internet.svg deleted file mode 100644 index c31e8b616..000000000 --- a/ux/public/_assets/icons/ultraviolet-internet.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-join.svg b/ux/public/_assets/icons/ultraviolet-join.svg deleted file mode 100644 index 8f49222be..000000000 --- a/ux/public/_assets/icons/ultraviolet-join.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-key.svg b/ux/public/_assets/icons/ultraviolet-key.svg deleted file mode 100644 index 3fa8b0386..000000000 --- a/ux/public/_assets/icons/ultraviolet-key.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-keycloak.svg b/ux/public/_assets/icons/ultraviolet-keycloak.svg deleted file mode 100644 index eaa496c88..000000000 --- a/ux/public/_assets/icons/ultraviolet-keycloak.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-light-on.svg b/ux/public/_assets/icons/ultraviolet-light-on.svg deleted file mode 100644 index 6a9270be8..000000000 --- a/ux/public/_assets/icons/ultraviolet-light-on.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-lightning-bolt.svg b/ux/public/_assets/icons/ultraviolet-lightning-bolt.svg deleted file mode 100644 index 485911990..000000000 --- a/ux/public/_assets/icons/ultraviolet-lightning-bolt.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-link.svg b/ux/public/_assets/icons/ultraviolet-link.svg deleted file mode 100644 index eea342199..000000000 --- a/ux/public/_assets/icons/ultraviolet-link.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-linux.svg b/ux/public/_assets/icons/ultraviolet-linux.svg deleted file mode 100644 index b2f090923..000000000 --- a/ux/public/_assets/icons/ultraviolet-linux.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-lock.svg b/ux/public/_assets/icons/ultraviolet-lock.svg deleted file mode 100644 index 363d1f2d0..000000000 --- a/ux/public/_assets/icons/ultraviolet-lock.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-lowercase.svg b/ux/public/_assets/icons/ultraviolet-lowercase.svg deleted file mode 100644 index a0e4ef752..000000000 --- a/ux/public/_assets/icons/ultraviolet-lowercase.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-markdown.svg b/ux/public/_assets/icons/ultraviolet-markdown.svg deleted file mode 100644 index 17b1c7894..000000000 --- a/ux/public/_assets/icons/ultraviolet-markdown.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-matches.svg b/ux/public/_assets/icons/ultraviolet-matches.svg deleted file mode 100644 index 25a23f838..000000000 --- a/ux/public/_assets/icons/ultraviolet-matches.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-maximize-window.svg b/ux/public/_assets/icons/ultraviolet-maximize-window.svg deleted file mode 100644 index a11efd32e..000000000 --- a/ux/public/_assets/icons/ultraviolet-maximize-window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-memory-slot.svg b/ux/public/_assets/icons/ultraviolet-memory-slot.svg deleted file mode 100644 index 3f86b7546..000000000 --- a/ux/public/_assets/icons/ultraviolet-memory-slot.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-merge-files.svg b/ux/public/_assets/icons/ultraviolet-merge-files.svg deleted file mode 100644 index 3a86ba9a2..000000000 --- a/ux/public/_assets/icons/ultraviolet-merge-files.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-microchip.svg b/ux/public/_assets/icons/ultraviolet-microchip.svg deleted file mode 100644 index e687adba2..000000000 --- a/ux/public/_assets/icons/ultraviolet-microchip.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-microsoft.svg b/ux/public/_assets/icons/ultraviolet-microsoft.svg deleted file mode 100644 index 4cd92808f..000000000 --- a/ux/public/_assets/icons/ultraviolet-microsoft.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-module.svg b/ux/public/_assets/icons/ultraviolet-module.svg deleted file mode 100644 index 1c7f58b32..000000000 --- a/ux/public/_assets/icons/ultraviolet-module.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-nas.svg b/ux/public/_assets/icons/ultraviolet-nas.svg deleted file mode 100644 index 54ff72bfe..000000000 --- a/ux/public/_assets/icons/ultraviolet-nas.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-navigation-toolbar-top.svg b/ux/public/_assets/icons/ultraviolet-navigation-toolbar-top.svg deleted file mode 100644 index 3361cf63d..000000000 --- a/ux/public/_assets/icons/ultraviolet-navigation-toolbar-top.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-new-document.svg b/ux/public/_assets/icons/ultraviolet-new-document.svg deleted file mode 100644 index cda328d3f..000000000 --- a/ux/public/_assets/icons/ultraviolet-new-document.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-new-job.svg b/ux/public/_assets/icons/ultraviolet-new-job.svg deleted file mode 100644 index c8466eebf..000000000 --- a/ux/public/_assets/icons/ultraviolet-new-job.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-no-access.svg b/ux/public/_assets/icons/ultraviolet-no-access.svg deleted file mode 100644 index 3d6943dcc..000000000 --- a/ux/public/_assets/icons/ultraviolet-no-access.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-nodejs.svg b/ux/public/_assets/icons/ultraviolet-nodejs.svg deleted file mode 100644 index 537674c23..000000000 --- a/ux/public/_assets/icons/ultraviolet-nodejs.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-oauth2.svg b/ux/public/_assets/icons/ultraviolet-oauth2.svg deleted file mode 100644 index a85fa2f3c..000000000 --- a/ux/public/_assets/icons/ultraviolet-oauth2.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-okta.svg b/ux/public/_assets/icons/ultraviolet-okta.svg deleted file mode 100644 index 868851d78..000000000 --- a/ux/public/_assets/icons/ultraviolet-okta.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-open-box.svg b/ux/public/_assets/icons/ultraviolet-open-box.svg deleted file mode 100644 index d1ea06966..000000000 --- a/ux/public/_assets/icons/ultraviolet-open-box.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-opened-folder.svg b/ux/public/_assets/icons/ultraviolet-opened-folder.svg deleted file mode 100644 index 87558cb35..000000000 --- a/ux/public/_assets/icons/ultraviolet-opened-folder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-openid.svg b/ux/public/_assets/icons/ultraviolet-openid.svg deleted file mode 100644 index 82bf0459e..000000000 --- a/ux/public/_assets/icons/ultraviolet-openid.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-password-reset.svg b/ux/public/_assets/icons/ultraviolet-password-reset.svg deleted file mode 100644 index b8c862a27..000000000 --- a/ux/public/_assets/icons/ultraviolet-password-reset.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-password.svg b/ux/public/_assets/icons/ultraviolet-password.svg deleted file mode 100644 index 2e6ba2e92..000000000 --- a/ux/public/_assets/icons/ultraviolet-password.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-pen.svg b/ux/public/_assets/icons/ultraviolet-pen.svg deleted file mode 100644 index d5fca6a2f..000000000 --- a/ux/public/_assets/icons/ultraviolet-pen.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-person.svg b/ux/public/_assets/icons/ultraviolet-person.svg deleted file mode 100644 index 6de773370..000000000 --- a/ux/public/_assets/icons/ultraviolet-person.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-pin-pad.svg b/ux/public/_assets/icons/ultraviolet-pin-pad.svg deleted file mode 100644 index 85a41089a..000000000 --- a/ux/public/_assets/icons/ultraviolet-pin-pad.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-plugin.svg b/ux/public/_assets/icons/ultraviolet-plugin.svg deleted file mode 100644 index a41d6b0e5..000000000 --- a/ux/public/_assets/icons/ultraviolet-plugin.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-polyline.svg b/ux/public/_assets/icons/ultraviolet-polyline.svg deleted file mode 100644 index aa81c445a..000000000 --- a/ux/public/_assets/icons/ultraviolet-polyline.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-postgresql.svg b/ux/public/_assets/icons/ultraviolet-postgresql.svg deleted file mode 100644 index f55ba9cdd..000000000 --- a/ux/public/_assets/icons/ultraviolet-postgresql.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-print.svg b/ux/public/_assets/icons/ultraviolet-print.svg deleted file mode 100644 index bb9ff078f..000000000 --- a/ux/public/_assets/icons/ultraviolet-print.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-private.svg b/ux/public/_assets/icons/ultraviolet-private.svg deleted file mode 100644 index 87849d727..000000000 --- a/ux/public/_assets/icons/ultraviolet-private.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-processor.svg b/ux/public/_assets/icons/ultraviolet-processor.svg deleted file mode 100644 index 3849028cd..000000000 --- a/ux/public/_assets/icons/ultraviolet-processor.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-program.svg b/ux/public/_assets/icons/ultraviolet-program.svg deleted file mode 100644 index a8862c977..000000000 --- a/ux/public/_assets/icons/ultraviolet-program.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-quote-left.svg b/ux/public/_assets/icons/ultraviolet-quote-left.svg deleted file mode 100644 index 12d692262..000000000 --- a/ux/public/_assets/icons/ultraviolet-quote-left.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-received.svg b/ux/public/_assets/icons/ultraviolet-received.svg deleted file mode 100644 index 466ca4807..000000000 --- a/ux/public/_assets/icons/ultraviolet-received.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-register.svg b/ux/public/_assets/icons/ultraviolet-register.svg deleted file mode 100644 index c8cdf3f93..000000000 --- a/ux/public/_assets/icons/ultraviolet-register.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-rename.svg b/ux/public/_assets/icons/ultraviolet-rename.svg deleted file mode 100644 index d9e4bcb78..000000000 --- a/ux/public/_assets/icons/ultraviolet-rename.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-renew.svg b/ux/public/_assets/icons/ultraviolet-renew.svg deleted file mode 100644 index 6478f461f..000000000 --- a/ux/public/_assets/icons/ultraviolet-renew.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-rescan-document.svg b/ux/public/_assets/icons/ultraviolet-rescan-document.svg deleted file mode 100644 index 050153b58..000000000 --- a/ux/public/_assets/icons/ultraviolet-rescan-document.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-resume-template.svg b/ux/public/_assets/icons/ultraviolet-resume-template.svg deleted file mode 100644 index 02ca1a481..000000000 --- a/ux/public/_assets/icons/ultraviolet-resume-template.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-rfid-signal.svg b/ux/public/_assets/icons/ultraviolet-rfid-signal.svg deleted file mode 100644 index 853576cd6..000000000 --- a/ux/public/_assets/icons/ultraviolet-rfid-signal.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-right-navigation-toolbar.svg b/ux/public/_assets/icons/ultraviolet-right-navigation-toolbar.svg deleted file mode 100644 index 7371be283..000000000 --- a/ux/public/_assets/icons/ultraviolet-right-navigation-toolbar.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-rocketchat.svg b/ux/public/_assets/icons/ultraviolet-rocketchat.svg deleted file mode 100644 index 2381cf64b..000000000 --- a/ux/public/_assets/icons/ultraviolet-rocketchat.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-rules.svg b/ux/public/_assets/icons/ultraviolet-rules.svg deleted file mode 100644 index 7b92730b2..000000000 --- a/ux/public/_assets/icons/ultraviolet-rules.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-run-command.svg b/ux/public/_assets/icons/ultraviolet-run-command.svg deleted file mode 100644 index 78d1fcb93..000000000 --- a/ux/public/_assets/icons/ultraviolet-run-command.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-saml.svg b/ux/public/_assets/icons/ultraviolet-saml.svg deleted file mode 100644 index 69c8c8063..000000000 --- a/ux/public/_assets/icons/ultraviolet-saml.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-scan-stock.svg b/ux/public/_assets/icons/ultraviolet-scan-stock.svg deleted file mode 100644 index 9de31b216..000000000 --- a/ux/public/_assets/icons/ultraviolet-scan-stock.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-schedule.svg b/ux/public/_assets/icons/ultraviolet-schedule.svg deleted file mode 100644 index 0540c91a9..000000000 --- a/ux/public/_assets/icons/ultraviolet-schedule.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-search.svg b/ux/public/_assets/icons/ultraviolet-search.svg deleted file mode 100644 index 40e6b3467..000000000 --- a/ux/public/_assets/icons/ultraviolet-search.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-secure.svg b/ux/public/_assets/icons/ultraviolet-secure.svg deleted file mode 100644 index ebc533dfb..000000000 --- a/ux/public/_assets/icons/ultraviolet-secure.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-security-configuration.svg b/ux/public/_assets/icons/ultraviolet-security-configuration.svg deleted file mode 100644 index df1211382..000000000 --- a/ux/public/_assets/icons/ultraviolet-security-configuration.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-security-ssl.svg b/ux/public/_assets/icons/ultraviolet-security-ssl.svg deleted file mode 100644 index fcb674e1f..000000000 --- a/ux/public/_assets/icons/ultraviolet-security-ssl.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-select-all.svg b/ux/public/_assets/icons/ultraviolet-select-all.svg deleted file mode 100644 index 975c028d7..000000000 --- a/ux/public/_assets/icons/ultraviolet-select-all.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-server.svg b/ux/public/_assets/icons/ultraviolet-server.svg deleted file mode 100644 index 3b152857c..000000000 --- a/ux/public/_assets/icons/ultraviolet-server.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-share.svg b/ux/public/_assets/icons/ultraviolet-share.svg deleted file mode 100644 index e6b99c919..000000000 --- a/ux/public/_assets/icons/ultraviolet-share.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-shipping-container.svg b/ux/public/_assets/icons/ultraviolet-shipping-container.svg deleted file mode 100644 index df36ecddf..000000000 --- a/ux/public/_assets/icons/ultraviolet-shipping-container.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-shutdown.svg b/ux/public/_assets/icons/ultraviolet-shutdown.svg deleted file mode 100644 index 2c6cbdaa0..000000000 --- a/ux/public/_assets/icons/ultraviolet-shutdown.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-sigma.svg b/ux/public/_assets/icons/ultraviolet-sigma.svg deleted file mode 100644 index df85a30be..000000000 --- a/ux/public/_assets/icons/ultraviolet-sigma.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-skype.svg b/ux/public/_assets/icons/ultraviolet-skype.svg deleted file mode 100644 index f0574f159..000000000 --- a/ux/public/_assets/icons/ultraviolet-skype.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-slack.svg b/ux/public/_assets/icons/ultraviolet-slack.svg deleted file mode 100644 index a441c3abc..000000000 --- a/ux/public/_assets/icons/ultraviolet-slack.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-small-icons.svg b/ux/public/_assets/icons/ultraviolet-small-icons.svg deleted file mode 100644 index 10ff0d4e5..000000000 --- a/ux/public/_assets/icons/ultraviolet-small-icons.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-sort-by-follow-up-date.svg b/ux/public/_assets/icons/ultraviolet-sort-by-follow-up-date.svg deleted file mode 100644 index 2211d0810..000000000 --- a/ux/public/_assets/icons/ultraviolet-sort-by-follow-up-date.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-spring.svg b/ux/public/_assets/icons/ultraviolet-spring.svg deleted file mode 100644 index e89101752..000000000 --- a/ux/public/_assets/icons/ultraviolet-spring.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-ssd.svg b/ux/public/_assets/icons/ultraviolet-ssd.svg deleted file mode 100644 index 62f41e236..000000000 --- a/ux/public/_assets/icons/ultraviolet-ssd.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-star-half-empty.svg b/ux/public/_assets/icons/ultraviolet-star-half-empty.svg deleted file mode 100644 index adb87e08b..000000000 --- a/ux/public/_assets/icons/ultraviolet-star-half-empty.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-starfish.svg b/ux/public/_assets/icons/ultraviolet-starfish.svg deleted file mode 100644 index 356306a6f..000000000 --- a/ux/public/_assets/icons/ultraviolet-starfish.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-subtitles.svg b/ux/public/_assets/icons/ultraviolet-subtitles.svg deleted file mode 100644 index f2b6543f8..000000000 --- a/ux/public/_assets/icons/ultraviolet-subtitles.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-summertime.svg b/ux/public/_assets/icons/ultraviolet-summertime.svg deleted file mode 100644 index 1a44be56f..000000000 --- a/ux/public/_assets/icons/ultraviolet-summertime.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-swipe-right.svg b/ux/public/_assets/icons/ultraviolet-swipe-right.svg deleted file mode 100644 index 85cbab6f7..000000000 --- a/ux/public/_assets/icons/ultraviolet-swipe-right.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-symlink-directory.svg b/ux/public/_assets/icons/ultraviolet-symlink-directory.svg deleted file mode 100644 index a0ca1cec4..000000000 --- a/ux/public/_assets/icons/ultraviolet-symlink-directory.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-synchronize.svg b/ux/public/_assets/icons/ultraviolet-synchronize.svg deleted file mode 100644 index 8d3dd2db0..000000000 --- a/ux/public/_assets/icons/ultraviolet-synchronize.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-team.svg b/ux/public/_assets/icons/ultraviolet-team.svg deleted file mode 100644 index 9c4a0b262..000000000 --- a/ux/public/_assets/icons/ultraviolet-team.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-test-account.svg b/ux/public/_assets/icons/ultraviolet-test-account.svg deleted file mode 100644 index a5a30015b..000000000 --- a/ux/public/_assets/icons/ultraviolet-test-account.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-test-passed.svg b/ux/public/_assets/icons/ultraviolet-test-passed.svg deleted file mode 100644 index 08ec3a5d7..000000000 --- a/ux/public/_assets/icons/ultraviolet-test-passed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-this-way-up.svg b/ux/public/_assets/icons/ultraviolet-this-way-up.svg deleted file mode 100644 index c2848e21f..000000000 --- a/ux/public/_assets/icons/ultraviolet-this-way-up.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-ticket.svg b/ux/public/_assets/icons/ultraviolet-ticket.svg deleted file mode 100644 index 53c95eb04..000000000 --- a/ux/public/_assets/icons/ultraviolet-ticket.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-timer.svg b/ux/public/_assets/icons/ultraviolet-timer.svg deleted file mode 100644 index 6f7d514ae..000000000 --- a/ux/public/_assets/icons/ultraviolet-timer.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-timezone.svg b/ux/public/_assets/icons/ultraviolet-timezone.svg deleted file mode 100644 index daece1e1b..000000000 --- a/ux/public/_assets/icons/ultraviolet-timezone.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-todo-list.svg b/ux/public/_assets/icons/ultraviolet-todo-list.svg deleted file mode 100644 index a6ed7200d..000000000 --- a/ux/public/_assets/icons/ultraviolet-todo-list.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-translation.svg b/ux/public/_assets/icons/ultraviolet-translation.svg deleted file mode 100644 index 80051f10b..000000000 --- a/ux/public/_assets/icons/ultraviolet-translation.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-trash.svg b/ux/public/_assets/icons/ultraviolet-trash.svg deleted file mode 100644 index 9b26a12d3..000000000 --- a/ux/public/_assets/icons/ultraviolet-trash.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-tree-structure.svg b/ux/public/_assets/icons/ultraviolet-tree-structure.svg deleted file mode 100644 index 4548fd4ef..000000000 --- a/ux/public/_assets/icons/ultraviolet-tree-structure.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-tune.svg b/ux/public/_assets/icons/ultraviolet-tune.svg deleted file mode 100644 index 8fd6f1e27..000000000 --- a/ux/public/_assets/icons/ultraviolet-tune.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-twitch.svg b/ux/public/_assets/icons/ultraviolet-twitch.svg deleted file mode 100644 index 689aa92a5..000000000 --- a/ux/public/_assets/icons/ultraviolet-twitch.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-typewriter-with-paper.svg b/ux/public/_assets/icons/ultraviolet-typewriter-with-paper.svg deleted file mode 100644 index 6c21db45e..000000000 --- a/ux/public/_assets/icons/ultraviolet-typewriter-with-paper.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-typography.svg b/ux/public/_assets/icons/ultraviolet-typography.svg deleted file mode 100644 index 8c7d423fd..000000000 --- a/ux/public/_assets/icons/ultraviolet-typography.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-ubuntu.svg b/ux/public/_assets/icons/ultraviolet-ubuntu.svg deleted file mode 100644 index 5bc519a41..000000000 --- a/ux/public/_assets/icons/ultraviolet-ubuntu.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/icons/ultraviolet-underline.svg b/ux/public/_assets/icons/ultraviolet-underline.svg deleted file mode 100644 index 1f3fe0c03..000000000 --- a/ux/public/_assets/icons/ultraviolet-underline.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-unfriend.svg b/ux/public/_assets/icons/ultraviolet-unfriend.svg deleted file mode 100644 index 13c1f223b..000000000 --- a/ux/public/_assets/icons/ultraviolet-unfriend.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-unit.svg b/ux/public/_assets/icons/ultraviolet-unit.svg deleted file mode 100644 index 20e3c8cba..000000000 --- a/ux/public/_assets/icons/ultraviolet-unit.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-unknown-status.svg b/ux/public/_assets/icons/ultraviolet-unknown-status.svg deleted file mode 100644 index 56afba76e..000000000 --- a/ux/public/_assets/icons/ultraviolet-unknown-status.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-upload-to-ftp.svg b/ux/public/_assets/icons/ultraviolet-upload-to-ftp.svg deleted file mode 100644 index bf5a810f9..000000000 --- a/ux/public/_assets/icons/ultraviolet-upload-to-ftp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-upload-to-the-cloud.svg b/ux/public/_assets/icons/ultraviolet-upload-to-the-cloud.svg deleted file mode 100644 index 3cdfa9c98..000000000 --- a/ux/public/_assets/icons/ultraviolet-upload-to-the-cloud.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-user-groups.svg b/ux/public/_assets/icons/ultraviolet-user-groups.svg deleted file mode 100644 index 0a87dbcbd..000000000 --- a/ux/public/_assets/icons/ultraviolet-user-groups.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-user-typing-using-typewriter.svg b/ux/public/_assets/icons/ultraviolet-user-typing-using-typewriter.svg deleted file mode 100644 index 289c3a9c9..000000000 --- a/ux/public/_assets/icons/ultraviolet-user-typing-using-typewriter.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-validation.svg b/ux/public/_assets/icons/ultraviolet-validation.svg deleted file mode 100644 index bc9f1a2cd..000000000 --- a/ux/public/_assets/icons/ultraviolet-validation.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-visualy-impaired.svg b/ux/public/_assets/icons/ultraviolet-visualy-impaired.svg deleted file mode 100644 index 28778a944..000000000 --- a/ux/public/_assets/icons/ultraviolet-visualy-impaired.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-washing-machine.svg b/ux/public/_assets/icons/ultraviolet-washing-machine.svg deleted file mode 100644 index c8cfdaa36..000000000 --- a/ux/public/_assets/icons/ultraviolet-washing-machine.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-web-design.svg b/ux/public/_assets/icons/ultraviolet-web-design.svg deleted file mode 100644 index 6e598c60b..000000000 --- a/ux/public/_assets/icons/ultraviolet-web-design.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-website.svg b/ux/public/_assets/icons/ultraviolet-website.svg deleted file mode 100644 index 4c4fbac3c..000000000 --- a/ux/public/_assets/icons/ultraviolet-website.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-widescreen.svg b/ux/public/_assets/icons/ultraviolet-widescreen.svg deleted file mode 100644 index c5650fb95..000000000 --- a/ux/public/_assets/icons/ultraviolet-widescreen.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-width.svg b/ux/public/_assets/icons/ultraviolet-width.svg deleted file mode 100644 index a92fbec9d..000000000 --- a/ux/public/_assets/icons/ultraviolet-width.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-windows8.svg b/ux/public/_assets/icons/ultraviolet-windows8.svg deleted file mode 100644 index aea92c65a..000000000 --- a/ux/public/_assets/icons/ultraviolet-windows8.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/icons/ultraviolet-workflow.svg b/ux/public/_assets/icons/ultraviolet-workflow.svg deleted file mode 100644 index deae597c3..000000000 --- a/ux/public/_assets/icons/ultraviolet-workflow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/illustrations/fileman-failed.svg b/ux/public/_assets/illustrations/fileman-failed.svg deleted file mode 100644 index 0dc662009..000000000 --- a/ux/public/_assets/illustrations/fileman-failed.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/illustrations/fileman-page.svg b/ux/public/_assets/illustrations/fileman-page.svg deleted file mode 100644 index 9c83d4f57..000000000 --- a/ux/public/_assets/illustrations/fileman-page.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/ux/public/_assets/illustrations/fileman-pending.svg b/ux/public/_assets/illustrations/fileman-pending.svg deleted file mode 100644 index 69df0e58a..000000000 --- a/ux/public/_assets/illustrations/fileman-pending.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/illustrations/undraw_file_searching.svg b/ux/public/_assets/illustrations/undraw_file_searching.svg deleted file mode 100644 index 0cd2a0a9d..000000000 --- a/ux/public/_assets/illustrations/undraw_file_searching.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/illustrations/undraw_floating.svg b/ux/public/_assets/illustrations/undraw_floating.svg deleted file mode 100644 index d5aabe769..000000000 --- a/ux/public/_assets/illustrations/undraw_floating.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/illustrations/undraw_going_up.svg b/ux/public/_assets/illustrations/undraw_going_up.svg deleted file mode 100644 index b9dce042a..000000000 --- a/ux/public/_assets/illustrations/undraw_going_up.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/illustrations/undraw_icon_design.svg b/ux/public/_assets/illustrations/undraw_icon_design.svg deleted file mode 100644 index 2d5fdbbdd..000000000 --- a/ux/public/_assets/illustrations/undraw_icon_design.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/illustrations/undraw_settings.svg b/ux/public/_assets/illustrations/undraw_settings.svg deleted file mode 100644 index 2280f9afd..000000000 --- a/ux/public/_assets/illustrations/undraw_settings.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/illustrations/undraw_upload.svg b/ux/public/_assets/illustrations/undraw_upload.svg deleted file mode 100644 index b54240d43..000000000 --- a/ux/public/_assets/illustrations/undraw_upload.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/illustrations/undraw_walking_outside.svg b/ux/public/_assets/illustrations/undraw_walking_outside.svg deleted file mode 100644 index 72e42f2ea..000000000 --- a/ux/public/_assets/illustrations/undraw_walking_outside.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/illustrations/undraw_world.svg b/ux/public/_assets/illustrations/undraw_world.svg deleted file mode 100644 index d7b232a16..000000000 --- a/ux/public/_assets/illustrations/undraw_world.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ux/public/_assets/logo-wikijs-full.svg b/ux/public/_assets/logo-wikijs-full.svg deleted file mode 100644 index 1e8b120f3..000000000 --- a/ux/public/_assets/logo-wikijs-full.svg +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/logo-wikijs.svg b/ux/public/_assets/logo-wikijs.svg deleted file mode 100644 index 52c4a790b..000000000 --- a/ux/public/_assets/logo-wikijs.svg +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ux/public/_assets/storage/azure.jpg b/ux/public/_assets/storage/azure.jpg deleted file mode 100644 index 84c73ea0e..000000000 Binary files a/ux/public/_assets/storage/azure.jpg and /dev/null differ diff --git a/ux/public/_assets/storage/database.jpg b/ux/public/_assets/storage/database.jpg deleted file mode 100644 index e695a144d..000000000 Binary files a/ux/public/_assets/storage/database.jpg and /dev/null differ diff --git a/ux/public/_assets/storage/disk.jpg b/ux/public/_assets/storage/disk.jpg deleted file mode 100644 index 09c9b4a07..000000000 Binary files a/ux/public/_assets/storage/disk.jpg and /dev/null differ diff --git a/ux/public/_assets/storage/gcs.jpg b/ux/public/_assets/storage/gcs.jpg deleted file mode 100644 index 7871d509c..000000000 Binary files a/ux/public/_assets/storage/gcs.jpg and /dev/null differ diff --git a/ux/public/_assets/storage/git.jpg b/ux/public/_assets/storage/git.jpg deleted file mode 100644 index 214b49c84..000000000 Binary files a/ux/public/_assets/storage/git.jpg and /dev/null differ diff --git a/ux/public/_assets/storage/github.jpg b/ux/public/_assets/storage/github.jpg deleted file mode 100644 index 69754b3f5..000000000 Binary files a/ux/public/_assets/storage/github.jpg and /dev/null differ diff --git a/ux/public/_assets/storage/s3.jpg b/ux/public/_assets/storage/s3.jpg deleted file mode 100644 index 3d599e595..000000000 Binary files a/ux/public/_assets/storage/s3.jpg and /dev/null differ diff --git a/ux/public/_assets/storage/ssh.jpg b/ux/public/_assets/storage/ssh.jpg deleted file mode 100644 index 6269ce883..000000000 Binary files a/ux/public/_assets/storage/ssh.jpg and /dev/null differ diff --git a/ux/public/favicon.ico b/ux/public/favicon.ico deleted file mode 100644 index b69c4b6f2..000000000 Binary files a/ux/public/favicon.ico and /dev/null differ diff --git a/ux/src/App.vue b/ux/src/App.vue deleted file mode 100644 index 925bcdfd0..000000000 --- a/ux/src/App.vue +++ /dev/null @@ -1,185 +0,0 @@ - - - diff --git a/ux/src/assets/quasar-logo-vertical.svg b/ux/src/assets/quasar-logo-vertical.svg deleted file mode 100644 index 821083104..000000000 --- a/ux/src/assets/quasar-logo-vertical.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/ux/src/boot/.gitkeep b/ux/src/boot/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/ux/src/boot/apollo.js b/ux/src/boot/apollo.js deleted file mode 100644 index 91965219f..000000000 --- a/ux/src/boot/apollo.js +++ /dev/null @@ -1,104 +0,0 @@ -import { ApolloClient, HttpLink, InMemoryCache, from, split } from '@apollo/client/core' -import { setContext } from '@apollo/client/link/context' -import { BatchHttpLink } from '@apollo/client/link/batch-http' -import createUploadLink from 'apollo-upload-client/createUploadLink.mjs' - -import { useUserStore } from '@/stores/user' - -export function initializeApollo (store) { - const userStore = useUserStore(store) - - const defaultLinkOptions = { - uri: '/_graphql', - credentials: 'omit' - } - - let refreshPromise = null - let fetching = false - - // Authentication Link - const authLink = setContext(async (req, { headers }) => { - if (!userStore.token) { - return { - headers: { - ...headers, - Authorization: '' - } - } - } - - // -> Refresh Token - if (!userStore.isTokenValid({ minutes: 1 })) { - if (!fetching) { - refreshPromise = new Promise((resolve, reject) => { - (async () => { - fetching = true - try { - await userStore.refreshToken() - resolve() - } catch (err) { - reject(err) - } - fetching = false - })() - }) - } else { - // -> Another request is already executing, wait for it to complete - await refreshPromise - } - } - - return { - headers: { - ...headers, - Authorization: userStore.token ? `Bearer ${userStore.token}` : '' - } - } - }) - - // Upload / HTTP Link - const uploadLink = createUploadLink({ - ...defaultLinkOptions, - headers: { - 'Apollo-Require-Preflight': 'true' - } - }) - - // Directional Link - const link = split( - op => op.getContext().skipAuth, - new HttpLink(defaultLinkOptions), - from([ - authLink, - split( - op => op.getContext().uploadMode, - uploadLink, - new BatchHttpLink(defaultLinkOptions) - ) - ]) - ) - - // Cache - const cache = new InMemoryCache() - - // Restore SSR state - if (typeof window !== 'undefined') { - const state = window.__APOLLO_STATE__ - if (state) { - cache.restore(state.defaultClient) - } - } - - // Client - const client = new ApolloClient({ - cache, - link, - ssrForceFetchDelay: 100 - }) - - if (import.meta.env.SSR) { - global.APOLLO_CLIENT = client - } else { - window.APOLLO_CLIENT = client - } -} diff --git a/ux/src/boot/components.js b/ux/src/boot/components.js deleted file mode 100644 index 6204e731d..000000000 --- a/ux/src/boot/components.js +++ /dev/null @@ -1,11 +0,0 @@ -import BlueprintIcon from '@/components/BlueprintIcon.vue' -import StatusLight from '@/components/StatusLight.vue' -import LoadingGeneric from '@/components/LoadingGeneric.vue' -import VNetworkGraph from 'v-network-graph' - -export function initializeComponents (app) { - app.component('BlueprintIcon', BlueprintIcon) - app.component('LoadingGeneric', LoadingGeneric) - app.component('StatusLight', StatusLight) - app.use(VNetworkGraph) -} diff --git a/ux/src/boot/eventbus.js b/ux/src/boot/eventbus.js deleted file mode 100644 index db06892bb..000000000 --- a/ux/src/boot/eventbus.js +++ /dev/null @@ -1,11 +0,0 @@ -import mitt from 'mitt' - -export function initializeEventBus () { - const emitter = mitt() - - if (import.meta.env.SSR) { - global.EVENT_BUS = emitter - } else { - window.EVENT_BUS = emitter - } -} diff --git a/ux/src/boot/externals.js b/ux/src/boot/externals.js deleted file mode 100644 index 09d8f8a1a..000000000 --- a/ux/src/boot/externals.js +++ /dev/null @@ -1,21 +0,0 @@ -import { usePageStore } from '@/stores/page' -import { useSiteStore } from '@/stores/site' -import { useUserStore } from '@/stores/user' - -export function initializeExternals (router, store) { - if (import.meta.env.SSR) { - global.WIKI_STATE = { - page: usePageStore(store), - site: useSiteStore(store), - user: useUserStore(store) - } - global.WIKI_ROUTER = router - } else { - window.WIKI_STATE = { - page: usePageStore(store), - site: useSiteStore(store), - user: useUserStore(store) - } - window.WIKI_ROUTER = router - } -} diff --git a/ux/src/boot/i18n.js b/ux/src/boot/i18n.js deleted file mode 100644 index d975d03c8..000000000 --- a/ux/src/boot/i18n.js +++ /dev/null @@ -1,17 +0,0 @@ -import { createI18n } from 'vue-i18n' -import { useCommonStore } from '@/stores/common' - -export function initializeI18n (app, store) { - const commonStore = useCommonStore(store) - - const i18n = createI18n({ - legacy: false, - locale: commonStore.locale || 'en', - fallbackLocale: 'en', - fallbackWarn: false, - messages: {} - }) - - // Set i18n instance on app - app.use(i18n) -} diff --git a/ux/src/boot/monaco.js b/ux/src/boot/monaco.js deleted file mode 100644 index 140936307..000000000 --- a/ux/src/boot/monaco.js +++ /dev/null @@ -1,23 +0,0 @@ -import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' -import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' -import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' -import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker' -import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' - -self.MonacoEnvironment = { - getWorker (_, label) { - if (label === 'json') { - return new JsonWorker() - } - if (label === 'css' || label === 'scss' || label === 'less') { - return new CssWorker() - } - if (label === 'html' || label === 'handlebars' || label === 'razor') { - return new HtmlWorker() - } - if (label === 'typescript' || label === 'javascript') { - return new TsWorker() - } - return new EditorWorker() - } -} diff --git a/ux/src/components/AccountMenu.vue b/ux/src/components/AccountMenu.vue deleted file mode 100644 index 32b572f85..000000000 --- a/ux/src/components/AccountMenu.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/ux/src/components/ApiKeyCopyDialog.vue b/ux/src/components/ApiKeyCopyDialog.vue deleted file mode 100644 index 3cbb5cbec..000000000 --- a/ux/src/components/ApiKeyCopyDialog.vue +++ /dev/null @@ -1,63 +0,0 @@ - - - diff --git a/ux/src/components/ApiKeyCreateDialog.vue b/ux/src/components/ApiKeyCreateDialog.vue deleted file mode 100644 index 7e121b9af..000000000 --- a/ux/src/components/ApiKeyCreateDialog.vue +++ /dev/null @@ -1,253 +0,0 @@ - - - diff --git a/ux/src/components/ApiKeyRevokeDialog.vue b/ux/src/components/ApiKeyRevokeDialog.vue deleted file mode 100644 index a8c5b6793..000000000 --- a/ux/src/components/ApiKeyRevokeDialog.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - diff --git a/ux/src/components/AssetDeleteDialog.vue b/ux/src/components/AssetDeleteDialog.vue deleted file mode 100644 index 47d51bfe1..000000000 --- a/ux/src/components/AssetDeleteDialog.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - diff --git a/ux/src/components/AssetRenameDialog.vue b/ux/src/components/AssetRenameDialog.vue deleted file mode 100644 index a407cd5f3..000000000 --- a/ux/src/components/AssetRenameDialog.vue +++ /dev/null @@ -1,165 +0,0 @@ - - - diff --git a/ux/src/components/AuthLoginPanel.vue b/ux/src/components/AuthLoginPanel.vue deleted file mode 100644 index af55f8629..000000000 --- a/ux/src/components/AuthLoginPanel.vue +++ /dev/null @@ -1,1055 +0,0 @@ - - - - - diff --git a/ux/src/components/BlockVideoPlayer.vue b/ux/src/components/BlockVideoPlayer.vue deleted file mode 100644 index e3a58c974..000000000 --- a/ux/src/components/BlockVideoPlayer.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/ux/src/components/BlueprintIcon.vue b/ux/src/components/BlueprintIcon.vue deleted file mode 100644 index 1653d9814..000000000 --- a/ux/src/components/BlueprintIcon.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - diff --git a/ux/src/components/ChangePwdDialog.vue b/ux/src/components/ChangePwdDialog.vue deleted file mode 100644 index 29286f9c2..000000000 --- a/ux/src/components/ChangePwdDialog.vue +++ /dev/null @@ -1,248 +0,0 @@ - - - diff --git a/ux/src/components/CheckUpdateDialog.vue b/ux/src/components/CheckUpdateDialog.vue deleted file mode 100644 index 2548a48da..000000000 --- a/ux/src/components/CheckUpdateDialog.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - diff --git a/ux/src/components/EditorChannel.vue b/ux/src/components/EditorChannel.vue deleted file mode 100644 index 67769353b..000000000 --- a/ux/src/components/EditorChannel.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - - - diff --git a/ux/src/components/EditorMarkdown.vue b/ux/src/components/EditorMarkdown.vue deleted file mode 100644 index cbb7e6b87..000000000 --- a/ux/src/components/EditorMarkdown.vue +++ /dev/null @@ -1,913 +0,0 @@ - - - - - diff --git a/ux/src/components/EditorMarkdownConfigOverlay.vue b/ux/src/components/EditorMarkdownConfigOverlay.vue deleted file mode 100644 index c5c754d52..000000000 --- a/ux/src/components/EditorMarkdownConfigOverlay.vue +++ /dev/null @@ -1,416 +0,0 @@ - - - diff --git a/ux/src/components/EditorMarkdownUserSettingsOverlay.vue b/ux/src/components/EditorMarkdownUserSettingsOverlay.vue deleted file mode 100644 index f85c6ca5d..000000000 --- a/ux/src/components/EditorMarkdownUserSettingsOverlay.vue +++ /dev/null @@ -1,197 +0,0 @@ - - - diff --git a/ux/src/components/EditorWysiwyg.vue b/ux/src/components/EditorWysiwyg.vue deleted file mode 100644 index b7c62a49b..000000000 --- a/ux/src/components/EditorWysiwyg.vue +++ /dev/null @@ -1,910 +0,0 @@ - - - - - diff --git a/ux/src/components/FileManager.vue b/ux/src/components/FileManager.vue deleted file mode 100644 index 5e7043059..000000000 --- a/ux/src/components/FileManager.vue +++ /dev/null @@ -1,1287 +0,0 @@ - - - - - diff --git a/ux/src/components/FolderCreateDialog.vue b/ux/src/components/FolderCreateDialog.vue deleted file mode 100644 index 61ba2ee36..000000000 --- a/ux/src/components/FolderCreateDialog.vue +++ /dev/null @@ -1,190 +0,0 @@ - - - diff --git a/ux/src/components/FolderDeleteDialog.vue b/ux/src/components/FolderDeleteDialog.vue deleted file mode 100644 index 77ab31efa..000000000 --- a/ux/src/components/FolderDeleteDialog.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - diff --git a/ux/src/components/FolderRenameDialog.vue b/ux/src/components/FolderRenameDialog.vue deleted file mode 100644 index 28ce24865..000000000 --- a/ux/src/components/FolderRenameDialog.vue +++ /dev/null @@ -1,227 +0,0 @@ - - - diff --git a/ux/src/components/FooterNav.vue b/ux/src/components/FooterNav.vue deleted file mode 100644 index ec341d623..000000000 --- a/ux/src/components/FooterNav.vue +++ /dev/null @@ -1,93 +0,0 @@ - - - - - diff --git a/ux/src/components/GithubSetupInstallDialog.vue b/ux/src/components/GithubSetupInstallDialog.vue deleted file mode 100644 index 6d6b775a7..000000000 --- a/ux/src/components/GithubSetupInstallDialog.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/ux/src/components/GroupCreateDialog.vue b/ux/src/components/GroupCreateDialog.vue deleted file mode 100644 index 727ac1bd5..000000000 --- a/ux/src/components/GroupCreateDialog.vue +++ /dev/null @@ -1,125 +0,0 @@ - - - diff --git a/ux/src/components/GroupDeleteDialog.vue b/ux/src/components/GroupDeleteDialog.vue deleted file mode 100644 index 4123ca3b2..000000000 --- a/ux/src/components/GroupDeleteDialog.vue +++ /dev/null @@ -1,96 +0,0 @@ - - - diff --git a/ux/src/components/GroupEditOverlay.vue b/ux/src/components/GroupEditOverlay.vue deleted file mode 100644 index 1c110ee26..000000000 --- a/ux/src/components/GroupEditOverlay.vue +++ /dev/null @@ -1,1205 +0,0 @@ - - - - - diff --git a/ux/src/components/HeaderNav.vue b/ux/src/components/HeaderNav.vue deleted file mode 100644 index 13d585f5b..000000000 --- a/ux/src/components/HeaderNav.vue +++ /dev/null @@ -1,127 +0,0 @@ - - - diff --git a/ux/src/components/HeaderSearch.vue b/ux/src/components/HeaderSearch.vue deleted file mode 100644 index f45073fb3..000000000 --- a/ux/src/components/HeaderSearch.vue +++ /dev/null @@ -1,229 +0,0 @@ - - - - - diff --git a/ux/src/components/IconPickerDialog.vue b/ux/src/components/IconPickerDialog.vue deleted file mode 100644 index f7aa21300..000000000 --- a/ux/src/components/IconPickerDialog.vue +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - diff --git a/ux/src/components/LoadingGeneric.vue b/ux/src/components/LoadingGeneric.vue deleted file mode 100644 index 1d96376a3..000000000 --- a/ux/src/components/LoadingGeneric.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/ux/src/components/LocaleSelectorMenu.vue b/ux/src/components/LocaleSelectorMenu.vue deleted file mode 100644 index d9aa61268..000000000 --- a/ux/src/components/LocaleSelectorMenu.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - diff --git a/ux/src/components/MailTemplateEditorOverlay.vue b/ux/src/components/MailTemplateEditorOverlay.vue deleted file mode 100644 index b1f2be4e3..000000000 --- a/ux/src/components/MailTemplateEditorOverlay.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - diff --git a/ux/src/components/MainOverlayDialog.vue b/ux/src/components/MainOverlayDialog.vue deleted file mode 100644 index 09dcc4cbe..000000000 --- a/ux/src/components/MainOverlayDialog.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - diff --git a/ux/src/components/NavEditMenu.vue b/ux/src/components/NavEditMenu.vue deleted file mode 100644 index 724a3bf8b..000000000 --- a/ux/src/components/NavEditMenu.vue +++ /dev/null @@ -1,210 +0,0 @@ - - - diff --git a/ux/src/components/NavEditOverlay.vue b/ux/src/components/NavEditOverlay.vue deleted file mode 100644 index 0ad557c03..000000000 --- a/ux/src/components/NavEditOverlay.vue +++ /dev/null @@ -1,783 +0,0 @@ - - - - - diff --git a/ux/src/components/NavSidebar.vue b/ux/src/components/NavSidebar.vue deleted file mode 100644 index 72f4e3ae7..000000000 --- a/ux/src/components/NavSidebar.vue +++ /dev/null @@ -1,184 +0,0 @@ - - - - - diff --git a/ux/src/components/PageActionsCol.vue b/ux/src/components/PageActionsCol.vue deleted file mode 100644 index bb7ea2fac..000000000 --- a/ux/src/components/PageActionsCol.vue +++ /dev/null @@ -1,343 +0,0 @@ - - - - - diff --git a/ux/src/components/PageDataDialog.vue b/ux/src/components/PageDataDialog.vue deleted file mode 100644 index e644cb705..000000000 --- a/ux/src/components/PageDataDialog.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - - - diff --git a/ux/src/components/PageDataTemplateDialog.vue b/ux/src/components/PageDataTemplateDialog.vue deleted file mode 100644 index 40365786f..000000000 --- a/ux/src/components/PageDataTemplateDialog.vue +++ /dev/null @@ -1,446 +0,0 @@ - - - - - diff --git a/ux/src/components/PageDeleteDialog.vue b/ux/src/components/PageDeleteDialog.vue deleted file mode 100644 index 9e3e4100e..000000000 --- a/ux/src/components/PageDeleteDialog.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - diff --git a/ux/src/components/PageHeader.vue b/ux/src/components/PageHeader.vue deleted file mode 100644 index 4bb373334..000000000 --- a/ux/src/components/PageHeader.vue +++ /dev/null @@ -1,409 +0,0 @@ - - - diff --git a/ux/src/components/PageNewMenu.vue b/ux/src/components/PageNewMenu.vue deleted file mode 100644 index 969d80c40..000000000 --- a/ux/src/components/PageNewMenu.vue +++ /dev/null @@ -1,133 +0,0 @@ - - - diff --git a/ux/src/components/PagePropertiesDialog.vue b/ux/src/components/PagePropertiesDialog.vue deleted file mode 100644 index 9b8ab1beb..000000000 --- a/ux/src/components/PagePropertiesDialog.vue +++ /dev/null @@ -1,436 +0,0 @@ - - - diff --git a/ux/src/components/PageReasonForChangeDialog.vue b/ux/src/components/PageReasonForChangeDialog.vue deleted file mode 100644 index 407ad39e3..000000000 --- a/ux/src/components/PageReasonForChangeDialog.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - diff --git a/ux/src/components/PageRelationDialog.vue b/ux/src/components/PageRelationDialog.vue deleted file mode 100644 index a82a573f7..000000000 --- a/ux/src/components/PageRelationDialog.vue +++ /dev/null @@ -1,238 +0,0 @@ - - - diff --git a/ux/src/components/PageScriptsDialog.vue b/ux/src/components/PageScriptsDialog.vue deleted file mode 100644 index 3a284190f..000000000 --- a/ux/src/components/PageScriptsDialog.vue +++ /dev/null @@ -1,132 +0,0 @@ - - - - - diff --git a/ux/src/components/PageSourceOverlay.vue b/ux/src/components/PageSourceOverlay.vue deleted file mode 100644 index d7fe90482..000000000 --- a/ux/src/components/PageSourceOverlay.vue +++ /dev/null @@ -1,161 +0,0 @@ - - - - - diff --git a/ux/src/components/PageTags.vue b/ux/src/components/PageTags.vue deleted file mode 100644 index 42ce6b69c..000000000 --- a/ux/src/components/PageTags.vue +++ /dev/null @@ -1,139 +0,0 @@ - - - diff --git a/ux/src/components/PasskeyCreateDialog.vue b/ux/src/components/PasskeyCreateDialog.vue deleted file mode 100644 index 4bed60121..000000000 --- a/ux/src/components/PasskeyCreateDialog.vue +++ /dev/null @@ -1,83 +0,0 @@ - - - diff --git a/ux/src/components/RerenderPageDialog.vue b/ux/src/components/RerenderPageDialog.vue deleted file mode 100644 index 0e3e441a4..000000000 --- a/ux/src/components/RerenderPageDialog.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/ux/src/components/SetupTfaDialog.vue b/ux/src/components/SetupTfaDialog.vue deleted file mode 100644 index 9ebfd9040..000000000 --- a/ux/src/components/SetupTfaDialog.vue +++ /dev/null @@ -1,235 +0,0 @@ - - - - - diff --git a/ux/src/components/SideDialog.vue b/ux/src/components/SideDialog.vue deleted file mode 100644 index 4dd0e47cb..000000000 --- a/ux/src/components/SideDialog.vue +++ /dev/null @@ -1,130 +0,0 @@ - - - - - diff --git a/ux/src/components/SiteActivateDialog.vue b/ux/src/components/SiteActivateDialog.vue deleted file mode 100644 index b7f8c5cdd..000000000 --- a/ux/src/components/SiteActivateDialog.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - diff --git a/ux/src/components/SiteCreateDialog.vue b/ux/src/components/SiteCreateDialog.vue deleted file mode 100644 index b99210f49..000000000 --- a/ux/src/components/SiteCreateDialog.vue +++ /dev/null @@ -1,154 +0,0 @@ - - - diff --git a/ux/src/components/SiteDeleteDialog.vue b/ux/src/components/SiteDeleteDialog.vue deleted file mode 100644 index 8bff62c72..000000000 --- a/ux/src/components/SiteDeleteDialog.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/ux/src/components/SocialSharingMenu.vue b/ux/src/components/SocialSharingMenu.vue deleted file mode 100644 index 7f77d4d20..000000000 --- a/ux/src/components/SocialSharingMenu.vue +++ /dev/null @@ -1,124 +0,0 @@ - - - diff --git a/ux/src/components/StatusLight.vue b/ux/src/components/StatusLight.vue deleted file mode 100644 index 530ff06d0..000000000 --- a/ux/src/components/StatusLight.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - - - diff --git a/ux/src/components/TableEditorOverlay.vue b/ux/src/components/TableEditorOverlay.vue deleted file mode 100644 index 59184843a..000000000 --- a/ux/src/components/TableEditorOverlay.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - diff --git a/ux/src/components/TreeBrowserDialog.vue b/ux/src/components/TreeBrowserDialog.vue deleted file mode 100644 index f4a22977f..000000000 --- a/ux/src/components/TreeBrowserDialog.vue +++ /dev/null @@ -1,506 +0,0 @@ - - - - - diff --git a/ux/src/components/TreeLevel.vue b/ux/src/components/TreeLevel.vue deleted file mode 100644 index 08f1452c9..000000000 --- a/ux/src/components/TreeLevel.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - diff --git a/ux/src/components/TreeNav.vue b/ux/src/components/TreeNav.vue deleted file mode 100644 index 656feb5c5..000000000 --- a/ux/src/components/TreeNav.vue +++ /dev/null @@ -1,240 +0,0 @@ - - - - - diff --git a/ux/src/components/TreeNode.vue b/ux/src/components/TreeNode.vue deleted file mode 100644 index 36872af4b..000000000 --- a/ux/src/components/TreeNode.vue +++ /dev/null @@ -1,140 +0,0 @@ - - - diff --git a/ux/src/components/UploadPendingAssetsDialog.vue b/ux/src/components/UploadPendingAssetsDialog.vue deleted file mode 100644 index 4d2bae05b..000000000 --- a/ux/src/components/UploadPendingAssetsDialog.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/ux/src/components/UserChangePwdDialog.vue b/ux/src/components/UserChangePwdDialog.vue deleted file mode 100644 index 5d4e5253d..000000000 --- a/ux/src/components/UserChangePwdDialog.vue +++ /dev/null @@ -1,219 +0,0 @@ - - - diff --git a/ux/src/components/UserCreateDialog.vue b/ux/src/components/UserCreateDialog.vue deleted file mode 100644 index e7c5545d8..000000000 --- a/ux/src/components/UserCreateDialog.vue +++ /dev/null @@ -1,398 +0,0 @@ - - - diff --git a/ux/src/components/UserDefaultsMenu.vue b/ux/src/components/UserDefaultsMenu.vue deleted file mode 100644 index 5d8149131..000000000 --- a/ux/src/components/UserDefaultsMenu.vue +++ /dev/null @@ -1,211 +0,0 @@ - - - diff --git a/ux/src/components/UserEditOverlay.vue b/ux/src/components/UserEditOverlay.vue deleted file mode 100644 index a481a9f54..000000000 --- a/ux/src/components/UserEditOverlay.vue +++ /dev/null @@ -1,871 +0,0 @@ - - - - - diff --git a/ux/src/components/UtilCodeEditor.vue b/ux/src/components/UtilCodeEditor.vue deleted file mode 100644 index 845be83f1..000000000 --- a/ux/src/components/UtilCodeEditor.vue +++ /dev/null @@ -1,133 +0,0 @@ - - - - - diff --git a/ux/src/components/WebhookDeleteDialog.vue b/ux/src/components/WebhookDeleteDialog.vue deleted file mode 100644 index 1858c9188..000000000 --- a/ux/src/components/WebhookDeleteDialog.vue +++ /dev/null @@ -1,106 +0,0 @@ - - - diff --git a/ux/src/components/WebhookEditDialog.vue b/ux/src/components/WebhookEditDialog.vue deleted file mode 100644 index 5a7785dd2..000000000 --- a/ux/src/components/WebhookEditDialog.vue +++ /dev/null @@ -1,440 +0,0 @@ - - - diff --git a/ux/src/components/WelcomeOverlay.vue b/ux/src/components/WelcomeOverlay.vue deleted file mode 100644 index bb7dcac93..000000000 --- a/ux/src/components/WelcomeOverlay.vue +++ /dev/null @@ -1,184 +0,0 @@ - - - - - diff --git a/ux/src/css/_animation.scss b/ux/src/css/_animation.scss deleted file mode 100644 index 654fd0dee..000000000 --- a/ux/src/css/_animation.scss +++ /dev/null @@ -1,157 +0,0 @@ -// ------------------------------------------------------------------ -// ANIMATION -// ------------------------------------------------------------------ - -:root { - --animate-duration: .6s; - --animate-delay: 1s; - --animate-repeat: 1; -} - -.animated { - animation-duration: var(--animate-duration); - animation-fill-mode: both; - - &.infinite { - animation-iteration-count: infinite; - } -} - -@for $i from 1 to 12 { - .wait-p#{$i}s { - animation-delay: $i * .1s !important; - } -} - -// -> Fade Transition - -.fade-enter-active, -.fade-leave-active { - transition-duration: 0.3s; - transition-property: opacity; - transition-timing-function: ease; -} - -.fade-enter, -.fade-leave-active { - opacity: 0 -} - -// -> Slide Up Transition - -.slide-up-enter-active, -.slide-up-leave-active { - transition: all 0.25s ease-out; -} - -.slide-up-enter-from { - opacity: 0; - transform: translateY(15px); -} - -.slide-up-leave-to { - opacity: 0; - transform: translateY(-15px); -} - -// -> fadeIn - -@keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -.fadeIn { - animation-name: fadeIn; -} - -// -> fadeInDown - -@keyframes fadeInDown { - from { - opacity: 0; - transform: translate3d(0, -10px, 0); - } - - to { - opacity: 1; - transform: translate3d(0, 0, 0); - } -} - -.fadeInDown { - animation-name: fadeInDown; -} - -// -> fadeInLeft - -@keyframes fadeInLeft { - from { - opacity: 0; - transform: translate3d(-10px, 0, 0); - } - - to { - opacity: 1; - transform: translate3d(0, 0, 0); - } -} - -.fadeInLeft { - animation-name: fadeInLeft; -} - -// -> fadeInRight - -@keyframes fadeInRight { - from { - opacity: 0; - transform: translate3d(10px, 0, 0); - } - - to { - opacity: 1; - transform: translate3d(0, 0, 0); - } -} - -.fadeInRight { - animation-name: fadeInRight; -} - -// -> fadeInUp - -@keyframes fadeInUp { - from { - opacity: 0; - transform: translate3d(0, 10px, 0); - } - - to { - opacity: 1; - transform: translate3d(0, 0, 0); - } -} - -.fadeInUp { - animation-name: fadeInUp; -} - -// -> Print + Reduce Motion - -@media print, (prefers-reduced-motion: reduce) { - .animated { - animation-duration: 1ms !important; - transition-duration: 1ms !important; - animation-iteration-count: 1 !important; - } - - .animated[class*='Out'] { - opacity: 0; - } -} diff --git a/ux/src/css/_base.scss b/ux/src/css/_base.scss deleted file mode 100644 index d1d7df6e2..000000000 --- a/ux/src/css/_base.scss +++ /dev/null @@ -1,269 +0,0 @@ -@use 'sass:color'; -@use '../../node_modules/quasar/src/css/variables.sass' as quasar; -@use 'theme'; - -// app global css in SCSS form -// ------------------------------------------------------------------ -// SCROLLBAR -// ------------------------------------------------------------------ - -html { - --scrollbarBG: #CCC; - --thumbBG: #999; -} -body::-webkit-scrollbar { - width: 7px; -} -body { - scrollbar-width: thin; - scrollbar-color: var(--thumbBG) var(--scrollbarBG); -} -body::-webkit-scrollbar-track { - background: var(--scrollbarBG); -} -body::-webkit-scrollbar-thumb { - background-color: var(--thumbBG); - border-radius: 6px; - border: 1px solid var(--scrollbarBG); -} - -// ------------------------------------------------------------------ -// FONTS -// ------------------------------------------------------------------ - -@font-face { - font-family: 'Roboto Mono'; - src: url(/_assets/fonts/roboto-mono/roboto-mono.woff2); -} - -.font-robotomono { - font-family: 'Roboto Mono', Consolas, "Liberation Mono", Courier, monospace; -} - -.text-wordbreak-all { - word-break: break-all; -} - -// ------------------------------------------------------------------ -// THEME COLORS -// ------------------------------------------------------------------ - -:root { - --q-header: #000; - --q-sidebar: #1976D2; -} - -.header, .bg-header { - background: #000; - background: var(--q-header); -} -.sidebar, .bg-sidebar { - background: #1976D2; - background: var(--q-sidebar); -} - -.bg-dark-6 { background-color: #070a0d; } -.bg-dark-5 { background-color: #0d1117; } -.bg-dark-4 { background-color: #161b22; } -.bg-dark-3 { background-color: #1e232a; } -.bg-dark-2 { background-color: #292f39; } -.bg-dark-1 { background-color: #343b48; } - -// ------------------------------------------------------------------ -// FORMS -// ------------------------------------------------------------------ - -.v-textarea.is-monospaced textarea { - font-family: 'Roboto Mono', 'Courier New', Courier, monospace; - font-size: 13px; - font-weight: 600; - line-height: 1.4; -} - -.q-field.denser .q-field__control { - height: 36px; - - .q-field__prepend { - height: 36px; - } -} - -.q-field.fill-outline .q-field__control { - background-color: #FFF; - - @at-root .body--light & { - background-color: #FFF; - } - @at-root .body--dark & { - background-color: theme.$dark; - } -} - -.q-field--dark .q-field__control:before { - background-color: theme.$dark-5; - border-color: rgba(255,255,255,.25); -} - -// ------------------------------------------------------------------ -// ICONS SIZE FIX -// ------------------------------------------------------------------ - -.q-btn .q-icon { - &.fa-solid, - &.fa-regular { - font-size: 1.3em; - } -} - -.q-select__dropdown-icon { - font-size: 16px; -} - -// ------------------------------------------------------------------ -// BUTTONS -// ------------------------------------------------------------------ - -.q-btn.acrylic-btn { - .q-focus-helper { - background-color: currentColor; - opacity: .1; - } - - &:hover .q-focus-helper { - opacity: .3 !important; - } -} - -// ------------------------------------------------------------------ -// ICONS -// ------------------------------------------------------------------ - -.blueprint-icon { - &-alt { - filter: hue-rotate(100); - } -} - -// ------------------------------------------------------------------ -// DIALOGS -// ------------------------------------------------------------------ - -.card-header { - display: flex; - align-items: center; - font-weight: 500; - font-size: .9rem; - background-color: theme.$dark-3; - background-image: radial-gradient(at bottom right, theme.$dark-3, theme.$dark-5); - color: #FFF; - - @at-root .body--light & { - border-bottom: 1px solid theme.$dark-3; - box-shadow: 0 1px 0 0 theme.$dark-6; - } - @at-root .body--dark & { - border-bottom: 1px solid #000; - box-shadow: 0 1px 0 0 color.adjust(theme.$dark-3, $lightness: 2%); - } -} - -.card-negative { - display: flex; - align-items: center; - font-size: .9rem; - - @at-root .body--light & { - background-color: quasar.$red-1; - background-image: radial-gradient(at bottom center, color.adjust(quasar.$red-1, $lightness: 2%), color.adjust(quasar.$red-2, $lightness: 2%)); - border-bottom: 1px solid quasar.$red-3; - text-shadow: 0 0 4px #FFF; - color: quasar.$red-9; - } - @at-root .body--dark & { - background-color: quasar.$red-9; - background-image: radial-gradient(at bottom center, quasar.$red-7, quasar.$red-9); - border-bottom: 1px solid quasar.$red-7; - text-shadow: 0 0 4px color.adjust(quasar.$red-9, $lightness: -10%); - color: #FFF; - } -} - -.card-actions { - @at-root .body--light & { - background-color: #FAFAFA; - background-image: linear-gradient(to bottom, #FCFCFC, #F0F0F0); - color: theme.$dark-3; - border-top: 1px solid #EEE; - box-shadow: inset 0 1px 0 0 #FFF; - } - @at-root .body--dark & { - background-color: theme.$dark-3; - background-image: radial-gradient(at top left, theme.$dark-3, theme.$dark-5); - border-top: 1px solid #000; - box-shadow: 0 -1px 0 0 color.adjust(theme.$dark-3, $lightness: 2%); - } -} - -// ------------------------------------------------------------------ -// CARDS -// ------------------------------------------------------------------ - -.q-card { - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12); - - &.q-card--dark { - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12); - } - - .q-separator--dark { - background-color: rgba(0,0,0,.7); - } -} - -// ------------------------------------------------------------------ -// DROPDOWN MENUS -// ------------------------------------------------------------------ - -.translucent-menu { - backdrop-filter: blur(10px) saturate(180%); - - @at-root .body--light & { - background-color: rgba(255,255,255,.8); - } - @at-root .body--dark & { - background-color: rgba(theme.$dark,.7); - } - - > .q-card { - background-color: transparent !important; - } -} - -.q-menu--dark { - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12); -} - -// ------------------------------------------------------------------ -// LOADING ANIMATIONS -// ------------------------------------------------------------------ - -.syncing-enter-active { - animation: syncing-anim .1s; -} -.syncing-leave-active { - animation: syncing-anim 1s reverse; -} -@keyframes syncing-anim { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -.loading-darker { - .q-loading__backdrop { - opacity: .75; - } -} diff --git a/ux/src/css/_page-contents.scss b/ux/src/css/_page-contents.scss deleted file mode 100644 index 44befe174..000000000 --- a/ux/src/css/_page-contents.scss +++ /dev/null @@ -1,597 +0,0 @@ -@use 'sass:color'; -@use '../../node_modules/quasar/src/css/variables.sass' as quasar; -@use 'theme'; - -.page-contents { - color: #424242; - font-size: 16px; - - > *:first-child { - margin-top: 0; - } - - @at-root .body--dark & { - color: #FFF; - } - - // --------------------------------- - // LINKS - // --------------------------------- - - a { - color: var(--q-primary); - - &.is-internal-link.is-invalid-page { - color: quasar.$red-8; - - @at-root .body--dark & { - color: quasar.$red-2; - } - } - - &.is-external-link { - padding-right: 3px; - - &::after { - font-family: 'Line Awesome Free'; - font-size: 24px/1; - padding-left: 3px; - display: inline-block; - content: "\f35d"; - color: quasar.$grey-5; - text-decoration: none; - } - } - - @at-root .body--dark & { - color: quasar.$blue-4; - } - } - - // --------------------------------- - // HEADERS - // --------------------------------- - - h1, h2, h3, h4, h5, h6 { - padding: 0; - margin: 0; - font-weight: 400; - position: relative; - line-height: normal; - - &:first-child { - padding-top: 0; - } - - &:hover { - .toc-anchor { - display: block; - } - } - } - - h1 { - font-size: 3em; - font-weight: 500; - padding: 12px 0; - // color: var(--q-primary); - } - h2 { - font-size: 2.4em; - padding: 12px 0; - } - h3 { - font-size: 2em; - padding: 12px 0; - } - h4 { - font-size: 1.75em; - } - h5 { - font-size: 1.5em; - } - h6 { - font-size: 1.25em; - } - - * + h1 { - margin-top: .5em; - padding-top: .5em; - // border-top: 2px solid var(--q-primary); - position: relative; - - &::before { - position: absolute; - width: 100%; - height: 1px; - content: ' '; - background: linear-gradient(to right, var(--q-primary), transparent); - top: 0; - left: -16px; - } - } - - *:not(h1) + h2 { - margin-top: .5em; - padding-top: .5em; - border-top: 1px dotted #CCC; - } - - .toc-anchor { - display: none; - position: absolute; - right: 1rem; - bottom: .5rem; - font-size: 1.25rem; - text-decoration: none; - color: #666; - } - - // --------------------------------- - // PARAGRAPHS - // --------------------------------- - - p { - padding: 0; - margin: .3em 0 1em 0; - } - - // --------------------------------- - // BLOCKQUOTES - // --------------------------------- - - blockquote { - padding: 1em 1em .3em 1em; - background-color: quasar.$blue-grey-1; - border-left: 55px solid quasar.$blue-grey-5; - border-radius: .5rem; - margin: 1rem 0; - position: relative; - - @at-root .body--dark & { - background-color: quasar.$blue-grey-9; - } - - &::before { - display: inline-block; - font: normal normal normal 24px/1 "Material Design Icons", sans-serif; - position: absolute; - margin-top: -12px; - top: 50%; - left: -38px; - color: rgba(255, 255, 255, .7); - content: "\F0757"; - } - - > p:first-child .emoji { - margin-right: .5rem; - } - - &.valign-center > p { - display: flex; - align-items: center; - } - - &.is-info { - background-color: quasar.$blue-1; - border-color: quasar.$blue-3; - color: quasar.$blue-9; - - &::before { - content: "\F02FC"; - } - - code { - background-color: quasar.$blue-1; - color: quasar.$blue-8; - } - - @at-root .body--dark & { - background-color: quasar.$blue-9; - color: quasar.$blue-5; - border-color: quasar.$blue-5; - } - } - &.is-warning { - background-color: quasar.$orange-1; - border-color: quasar.$orange-3; - color: color.adjust(quasar.$orange-9, $lightness: -10%); - - &::before { - content: "\F0026"; - } - - code { - background-color: quasar.$orange-1; - color: quasar.$orange-8; - } - - @at-root .body--dark & { - background-color: color.adjust(quasar.$orange-9, $lightness: -5%); - color: quasar.$orange-1; - border-color: quasar.$orange-5; - box-shadow: 0 0 2px 0 quasar.$grey-9; - } - } - &.is-danger { - background-color: quasar.$red-1; - border-color: quasar.$red-3; - color: quasar.$red-9; - - &::before { - content: "\F0159"; - } - - code { - background-color: quasar.$red-1; - color: quasar.$red-8; - } - - @at-root .body--dark & { - background-color: quasar.$red-9; - color: quasar.$red-1; - border-color: quasar.$red-5; - } - } - &.is-success { - background-color: quasar.$green-1; - border-color: quasar.$green-3; - color: quasar.$green-9; - - &::before { - content: "\F0E1E"; - } - - code { - background-color: quasar.$green-1; - color: quasar.$green-8; - } - - @at-root .body--dark & { - background-color: quasar.$green-9; - color: quasar.$green-5; - border-color: quasar.$green-5; - } - } - - .codeblock > code { - background-color: inherit; - color: inherit; - } - } - - // --------------------------------- - // LISTS - // --------------------------------- - - ol, ul:not(.tabset-tabs) { - width: 100%; - - li > p { - &:first-child { - margin-top: 0; - } - &:last-child { - margin-bottom: 0; - } - } - - @at-root .is-rtl & { - padding-left: 0; - padding-right: 1em; - } - - li > ul, li > ol { - padding-top: .5rem; - padding-left: 1em; - - @at-root .is-rtl & { - padding-left: 0; - padding-right: 1em; - } - } - - li + li { - margin-top: .5rem; - } - - &.links-list { - padding-left: 0; - list-style-type: none; - - @at-root .is-rtl & { - padding-right: 0; - } - - li { - background-color: quasar.$grey-1; - background-image: linear-gradient(to bottom, #FFF, quasar.$grey-1); - border-right: 1px solid quasar.$grey-3; - border-bottom: 1px solid quasar.$grey-3; - border-left: 5px solid quasar.$grey-4; - box-shadow: 0 3px 8px 0 rgba(116, 129, 141, 0.1); - padding: 1rem; - border-radius: 5px; - font-weight: 500; - - @at-root .is-rtl & { - border-left-width: 1px; - border-right-width: 5px; - } - - &:hover { - background-image: linear-gradient(to bottom, #FFF, color.adjust(quasar.$blue-1, $lightness: 4%)); - border-left-color: quasar.$blue-5; - cursor: pointer; - - @at-root .is-rtl & { - border-left-color: quasar.$grey-3; - border-right-width: quasar.$blue-5; - } - } - - &::before { - content: ''; - display: none; - } - - > a { - display: block; - text-decoration: none; - margin: -1rem; - padding: 1rem; - - > em { - font-weight: 400; - font-style: normal; - color: quasar.$grey-7; - display: inline-block; - padding-left: .5rem; - border-left: 1px solid quasar.$grey-4; - margin-left: .5rem; - - &.is-block { - display: block; - padding-left: 0; - margin-left: 0; - border-left: none; - } - } - } - - > em { - font-weight: 400; - font-style: normal; - } - - @at-root .body--dark & { - background-color: quasar.$grey-1; - background-image: linear-gradient(to bottom, color.adjust(quasar.$grey-9, $lightness: 5%), quasar.$grey-9); - border-right: 1px solid quasar.$grey-9; - border-bottom: 1px solid quasar.$grey-9; - border-left: 5px solid quasar.$grey-7; - box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.1); - - @at-root .body--dark.is-rtl & { - border-left-width: 1px; - border-right-width: 5px; - } - - &:hover { - background-image: linear-gradient(to bottom, color.adjust(quasar.$grey-9, $lightness: 2%), color.adjust(quasar.$grey-9, $lightness: -3%)); - border-left-color: mc('indigo', '300'); - cursor: pointer; - - @at-root .body--dark.is-rtl & { - border-left-color: quasar.$grey-9; - border-right-width: mc('indigo', '300'); - } - } - } - } - } - - &.grid-list { - margin: 1rem 0 0 0; - background-color: #FFF; - border: 1px solid quasar.$grey-3; - padding: 1px; - display: inline-block; - list-style-type: none; - - @at-root .body--dark & { - background-color: #000; - border: 1px solid mc('grey', '800'); - } - - li { - background-color: quasar.$grey-1; - padding: .6rem 1rem; - display: block; - - &:nth-child(odd) { - background-color: mc('grey', '100'); - } - - & + li { - margin-top: 0; - } - - &::before { - content: ''; - display: none; - } - - @at-root .body--dark & { - background-color: quasar.$grey-9; - - &:nth-child(odd) { - background-color: color.adjust(quasar.$grey-9, $lightness: -5%); - } - } - } - } - } - - ul:not(.tabset-tabs):not(.contains-task-list) { - list-style: square; - } - ol, ul:not(.tabset-tabs) { - > li { - position: relative; - > p { - display:inline-block; - vertical-align:top; - padding-top:0; - } - } - } - - // --------------------------------- - // TASK LISTS - // --------------------------------- - - .contains-task-list { - padding-left: 1em; - } - - .task-list-item { - position: relative; - list-style-type: none; - - &-checkbox[disabled] { - width: 1.1rem; - height: 1.1rem; - top: 2px; - position: relative; - margin-right: .4em; - background-color: theme.$dark-5; - border-width: 0; - - &::after { - position: absolute; - left: 0; - top: 0; - font-family: "Material Design Icons"; - font-size: 1.25em; - font-weight: normal; - content: '\F0131'; - color: quasar.$grey-10; - display: block; - border: none; - background-color: #FFF; - line-height: 1em; - cursor: default; - - @at-root .body--dark & { - color: #FFF; - background-color: theme.$dark-6; - } - } - - &[checked]::after { - content: '\F0C52'; - } - } - - .contains-task-list { - padding: .5rem 0 0 1.5rem; - } - } - - // --------------------------------- - // CODE - // --------------------------------- - - // code { - // background-color: mc('indigo', '50'); - // padding: 0 5px; - // color: mc('indigo', '800'); - // font-family: 'Roboto Mono', monospace; - // font-weight: normal; - // font-size: 1rem; - // box-shadow: none; - - // &::before, &::after { - // display: none; - // } - - // @at-root .theme--dark & { - // background-color: color.adjust(mc('grey', '900'), $lightness: -5%); - // color: mc('indigo', '100'); - // } - // } - - pre.codeblock { - border: 1px solid rgba(0,0,0,.2); - border-radius: 5px; - box-shadow: initial; - padding: 1rem; - margin: 1rem 0; - overflow: auto; - - > code { - // background-color: transparent; - padding: 0; - // color: #FFF; - box-shadow: initial; - display: block; - font-size: .85rem; - font-family: 'Roboto Mono', monospace; - - &:after, &:before { - content: initial; - letter-spacing: initial; - } - } - - &.line-numbers { - counter-reset: linenumber; - padding-left: 3rem; - - > code { - position: relative; - white-space: inherit; - } - - .line-numbers-rows { - position: absolute; - pointer-events: none; - top: 0; - font-size: 100%; - left: -3.8em; - width: 3em; - letter-spacing: -1px; - border-right: 1px solid #999; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - - & > span { - display: block; - counter-increment: linenumber; - - &:before { - content: counter(linenumber); - color: #999; - display: block; - padding-right: .8em; - text-align: right; - } - } - } - } - } - - // --------------------------------- - // LEGACY - // --------------------------------- - - .align-abstopright { - width: 100px; - max-height: 100px; - border: 2px dashed quasar.$red; - border-radius: 5px; - padding: 5px; - } -} diff --git a/ux/src/css/_theme.scss b/ux/src/css/_theme.scss deleted file mode 100644 index 5de0086d9..000000000 --- a/ux/src/css/_theme.scss +++ /dev/null @@ -1,34 +0,0 @@ -// Quasar SCSS (& Sass) Variables -// -------------------------------------------------- -// To customize the look and feel of this app, you can override -// the Sass/SCSS variables found in Quasar's source Sass/SCSS files. - -// Check documentation for full list of Quasar variables - -// Your own variables (that are declared here) and Quasar's own -// ones will be available out of the box in your .vue/.scss/.sass files - -// It's highly recommended to change the default colors -// to match your app's branding. -// Tip: Use the "Theme Builder" on Quasar's documentation website. - -$primary : #1976D2; -$secondary : #02C39A; -$accent : #f03a47; - -$dark : #0d1117; - -$positive : #02C39A; -$negative : #f03a47; -$info : #3e6990; -$warning : #f99d4d; - -$header : #000; -$sidebar: $primary; - -$dark-6: #070a0d; -$dark-5: #0d1117; -$dark-4: #161b22; -$dark-3: #1e232a; -$dark-2: #292f39; -$dark-1: #343b48; diff --git a/ux/src/css/app.scss b/ux/src/css/app.scss deleted file mode 100644 index 36a8a4f10..000000000 --- a/ux/src/css/app.scss +++ /dev/null @@ -1,5 +0,0 @@ -@use 'base'; -@use 'animation'; -@use 'page-contents'; - -@import 'v-network-graph/lib/style.css'; diff --git a/ux/src/helpers/accessibility.js b/ux/src/helpers/accessibility.js deleted file mode 100644 index 3c4338ce0..000000000 --- a/ux/src/helpers/accessibility.js +++ /dev/null @@ -1,33 +0,0 @@ -const protanopia = { - negative: '#fb8c00', - positive: '#2196f3', - primary: '#1976D2', - secondary: '#2196f3' -} - -const deuteranopia = { - negative: '#ef6c00', - positive: '#2196f3', - primary: '#1976D2', - secondary: '#2196f3' -} - -const tritanopia = { - primary: '#e91e63', - secondary: '#02C39A' -} - -export function getAccessibleColor (name, base, cvd) { - switch (cvd) { - case 'protanopia': { - return protanopia[name] ?? base - } - case 'deuteranopia': { - return deuteranopia[name] ?? base - } - case 'tritanopia': { - return tritanopia[name] ?? base - } - } - return base -} diff --git a/ux/src/helpers/fileTypes.js b/ux/src/helpers/fileTypes.js deleted file mode 100644 index 75712df45..000000000 --- a/ux/src/helpers/fileTypes.js +++ /dev/null @@ -1,173 +0,0 @@ -export default { - '7z': { - icon: 'img:/_assets/icons/color-7zip.svg' - }, - aac: { - icon: 'img:/_assets/icons/color-aac.svg' - }, - ai: { - icon: 'img:/_assets/icons/color-ai.svg' - }, - aif: { - icon: 'img:/_assets/icons/color-audio-file.svg' - }, - apk: { - icon: 'img:/_assets/icons/color-apk.svg' - }, - avi: { - icon: 'img:/_assets/icons/color-avi.svg' - }, - bin: { - icon: 'img:/_assets/icons/color-binary-file.svg' - }, - bz2: { - icon: 'img:/_assets/icons/color-archive.svg' - }, - css: { - icon: 'img:/_assets/icons/color-css-filetype.svg' - }, - csv: { - icon: 'img:/_assets/icons/color-csv.svg' - }, - dat: { - icon: 'img:/_assets/icons/color-binary-file.svg' - }, - dmg: { - icon: 'img:/_assets/icons/color-dmg.svg' - }, - docx: { - icon: 'img:/_assets/icons/color-word.svg' - }, - eps: { - icon: 'img:/_assets/icons/color-image-file.svg' - }, - exe: { - icon: 'img:/_assets/icons/color-exe.svg' - }, - flac: { - icon: 'img:/_assets/icons/color-audio-file.svg' - }, - folder: { - icon: 'img:/_assets/icons/fluent-folder.svg' - }, - gif: { - icon: 'img:/_assets/icons/color-gif.svg' - }, - gz: { - icon: 'img:/_assets/icons/color-archive.svg' - }, - heic: { - icon: 'img:/_assets/icons/color-image-file.svg' - }, - ico: { - icon: 'img:/_assets/icons/color-image-file.svg' - }, - ics: { - icon: 'img:/_assets/icons/color-schedule.svg' - }, - iso: { - icon: 'img:/_assets/icons/color-cd.svg' - }, - jpg: { - icon: 'img:/_assets/icons/color-jpg.svg', - imageEdit: true - }, - jpeg: { - icon: 'img:/_assets/icons/color-jpg.svg', - imageEdit: true - }, - json: { - icon: 'img:/_assets/icons/color-json.svg' - }, - m4a: { - icon: 'img:/_assets/icons/color-audio-file.svg' - }, - mid: { - icon: 'img:/_assets/icons/color-audio-file.svg' - }, - mov: { - icon: 'img:/_assets/icons/color-mov.svg' - }, - mp3: { - icon: 'img:/_assets/icons/color-mp3.svg' - }, - mp4: { - icon: 'img:/_assets/icons/color-mpg.svg' - }, - mpg: { - icon: 'img:/_assets/icons/color-mpg.svg' - }, - mpeg: { - icon: 'img:/_assets/icons/color-mpg.svg' - }, - ogg: { - icon: 'img:/_assets/icons/color-ogg.svg' - }, - otf: { - icon: 'img:/_assets/icons/color-otf.svg' - }, - page: { - icon: 'img:/_assets/icons/color-document.svg' - }, - pdf: { - icon: 'img:/_assets/icons/color-pdf.svg' - }, - png: { - icon: 'img:/_assets/icons/color-png.svg', - imageEdit: true - }, - pptx: { - icon: 'img:/_assets/icons/color-ppt.svg' - }, - psd: { - icon: 'img:/_assets/icons/color-psd.svg' - }, - rar: { - icon: 'img:/_assets/icons/color-rar.svg' - }, - svg: { - icon: 'img:/_assets/icons/color-image-file.svg' - }, - tar: { - icon: 'img:/_assets/icons/color-tar.svg' - }, - tgz: { - icon: 'img:/_assets/icons/color-archive.svg' - }, - tif: { - icon: 'img:/_assets/icons/color-tif.svg' - }, - ttf: { - icon: 'img:/_assets/icons/color-ttf.svg' - }, - txt: { - icon: 'img:/_assets/icons/color-txt.svg' - }, - wav: { - icon: 'img:/_assets/icons/color-wav.svg' - }, - wma: { - icon: 'img:/_assets/icons/color-audio-file.svg' - }, - wmv: { - icon: 'img:/_assets/icons/color-video-file.svg' - }, - woff: { - icon: 'img:/_assets/icons/color-woff.svg' - }, - woff2: { - icon: 'img:/_assets/icons/color-woff.svg' - }, - xlst: { - icon: 'img:/_assets/icons/color-xls.svg' - }, - xml: { - icon: 'img:/_assets/icons/color-xml-file.svg' - }, - xz: { - icon: 'img:/_assets/icons/color-archive.svg' - }, - zip: { - icon: 'img:/_assets/icons/color-zip.svg' - } -} diff --git a/ux/src/helpers/localization.js b/ux/src/helpers/localization.js deleted file mode 100644 index 8f127d514..000000000 --- a/ux/src/helpers/localization.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Parse an error message for an error code and translate - * - * @param {String} val Value to parse - * @param {Function} t vue-i18n translation method - */ -export function localizeError (val, t) { - if (val?.startsWith('ERR_')) { - return t(`error.${val}`) - } else { - return val - } -} diff --git a/ux/src/helpers/monacoTypes.js b/ux/src/helpers/monacoTypes.js deleted file mode 100644 index b10f40655..000000000 --- a/ux/src/helpers/monacoTypes.js +++ /dev/null @@ -1,621 +0,0 @@ -// Adapted from https://github.com/trofimander/monaco-markdown/blob/master/src/ts/extHostTypes.ts -// by https://github.com/trofimander -// MIT Licensed - -// export function values(set: Set): V[]; -// export function values(map: Map): V[]; -export function values (forEachable) { - const result = [] - forEachable.forEach(value => result.push(value)) - return result -} - -export class Position { - static Min (...positions) { - if (positions.length === 0) { - throw new TypeError() - } - let result = positions[0] - for (let i = 1; i < positions.length; i++) { - const p = positions[i] - if (p.isBefore(result)) { - result = p - } - } - return result - } - - static Max (...positions) { - if (positions.length === 0) { - throw new TypeError() - } - let result = positions[0] - for (let i = 1; i < positions.length; i++) { - const p = positions[i] - if (p.isAfter(result)) { - result = p - } - } - return result - } - - static isPosition (other) { - if (!other) { - return false - } - if (other instanceof Position) { - return true - } - const { line, character } = other - if (typeof line === 'number' && typeof character === 'number') { - return true - } - return false - } - - get line () { - return this._line - } - - get character () { - return this._character - } - - constructor (line, character) { - if (line < 0) { - throw new Error('line must be non-negative') - } - if (character < 0) { - throw new Error('character must be non-negative') - } - this._line = line - this._character = character - } - - isBefore (other) { - if (this._line < other._line) { - return true - } - if (other._line < this._line) { - return false - } - return this._character < other._character - } - - isBeforeOrEqual (other) { - if (this._line < other._line) { - return true - } - if (other._line < this._line) { - return false - } - return this._character <= other._character - } - - isAfter (other) { - return !this.isBeforeOrEqual(other) - } - - isAfterOrEqual (other) { - return !this.isBefore(other) - } - - isEqual (other) { - return this._line === other._line && this._character === other._character - } - - compareTo (other) { - if (this._line < other._line) { - return -1 - } else if (this._line > other.line) { - return 1 - } else { - // equal line - if (this._character < other._character) { - return -1 - } else if (this._character > other._character) { - return 1 - } else { - // equal line and character - return 0 - } - } - } - - translate (lineDeltaOrChange, characterDelta = 0) { - if (lineDeltaOrChange === null || characterDelta === null) { - throw new Error() - } - - let lineDelta - if (typeof lineDeltaOrChange === 'undefined') { - lineDelta = 0 - } else if (typeof lineDeltaOrChange === 'number') { - lineDelta = lineDeltaOrChange - } else { - lineDelta = typeof lineDeltaOrChange.lineDelta === 'number' ? lineDeltaOrChange.lineDelta : 0 - characterDelta = typeof lineDeltaOrChange.characterDelta === 'number' ? lineDeltaOrChange.characterDelta : 0 - } - - if (lineDelta === 0 && characterDelta === 0) { - return this - } - return new Position(this.line + lineDelta, this.character + characterDelta) - } - - with (lineOrChange, character = this.character) { - if (lineOrChange === null || character === null) { - throw new Error() - } - - let line - if (typeof lineOrChange === 'undefined') { - line = this.line - } else if (typeof lineOrChange === 'number') { - line = lineOrChange - } else { - line = typeof lineOrChange.line === 'number' ? lineOrChange.line : this.line - character = typeof lineOrChange.character === 'number' ? lineOrChange.character : this.character - } - - if (line === this.line && character === this.character) { - return this - } - return new Position(line, character) - } - - toJSON () { - return { line: this.line, character: this.character } - } -} - -export class Range { - static isRange (thing) { - if (thing instanceof Range) { - return true - } - if (!thing) { - return false - } - return Position.isPosition(thing.start) && Position.isPosition(thing.end) - } - - get start () { - return this._start - } - - get end () { - return this._end - } - - constructor (startLineOrStart, startColumnOrEnd, endLine, endColumn) { - let start - let end - - if (typeof startLineOrStart === 'number' && typeof startColumnOrEnd === 'number' && typeof endLine === 'number' && typeof endColumn === 'number') { - start = new Position(startLineOrStart, startColumnOrEnd) - end = new Position(endLine, endColumn) - } else if (startLineOrStart instanceof Position && startColumnOrEnd instanceof Position) { - start = startLineOrStart - end = startColumnOrEnd - } - - if (!start || !end) { - throw new Error('Invalid arguments') - } - - if (start.isBefore(end)) { - this._start = start - this._end = end - } else { - this._start = end - this._end = start - } - } - - contains (positionOrRange) { - if (positionOrRange instanceof Range) { - return this.contains(positionOrRange._start) && - this.contains(positionOrRange._end) - } else if (positionOrRange instanceof Position) { - if (positionOrRange.isBefore(this._start)) { - return false - } - if (this._end.isBefore(positionOrRange)) { - return false - } - return true - } - return false - } - - isEqual (other) { - return this._start.isEqual(other._start) && this._end.isEqual(other._end) - } - - intersection (other) { - const start = Position.Max(other.start, this._start) - const end = Position.Min(other.end, this._end) - if (start.isAfter(end)) { - // this happens when there is no overlap: - // |-----| - // |----| - return undefined - } - return new Range(start, end) - } - - union (other) { - if (this.contains(other)) { - return this - } else if (other.contains(this)) { - return other - } - const start = Position.Min(other.start, this._start) - const end = Position.Max(other.end, this.end) - return new Range(start, end) - } - - get isEmpty () { - return this._start.isEqual(this._end) - } - - get isSingleLine () { - return this._start.line === this._end.line - } - - with (startOrChange, end = this.end) { - if (startOrChange === null || end === null) { - throw new Error() - } - - let start - if (!startOrChange) { - start = this.start - } else if (Position.isPosition(startOrChange)) { - start = startOrChange - } else { - start = startOrChange.start || this.start - end = startOrChange.end || this.end - } - - if (start.isEqual(this._start) && end.isEqual(this.end)) { - return this - } - return new Range(start, end) - } - - toJSON () { - return [this.start, this.end] - } -} - -export class Selection extends Range { - static isSelection (thing) { - if (thing instanceof Selection) { - return true - } - if (!thing) { - return false - } - return Range.isRange(thing) && - Position.isPosition(thing.anchor) && - Position.isPosition(thing.active) && - typeof thing.isReversed === 'boolean' - } - - get anchor () { - return this._anchor - } - - get active () { - return this._active - } - - constructor (anchorLineOrAnchor, anchorColumnOrActive, activeLine, activeColumn) { - let anchor - let active - - if (typeof anchorLineOrAnchor === 'number' && typeof anchorColumnOrActive === 'number' && typeof activeLine === 'number' && typeof activeColumn === 'number') { - anchor = new Position(anchorLineOrAnchor, anchorColumnOrActive) - active = new Position(activeLine, activeColumn) - } else if (anchorLineOrAnchor instanceof Position && anchorColumnOrActive instanceof Position) { - anchor = anchorLineOrAnchor - active = anchorColumnOrActive - } - - if (!anchor || !active) { - throw new Error('Invalid arguments') - } - - super(anchor, active) - - this._anchor = anchor - this._active = active - } - - get isReversed () { - return this._anchor === this._end - } - - toJSON () { - return { - start: this.start, - end: this.end, - active: this.active, - anchor: this.anchor - } - } -} - -export const EndOfLine = { - LF: 1, - CRLF: 2 -} - -export class TextEdit { - static isTextEdit (thing) { - if (thing instanceof TextEdit) { - return true - } - if (!thing) { - return false - } - return Range.isRange(thing) && typeof thing.newText === 'string' - } - - static replace (range, newText) { - return new TextEdit(range, newText) - } - - static insert (position, newText) { - return TextEdit.replace(new Range(position, position), newText) - } - - static delete (range) { - return TextEdit.replace(range, '') - } - - static setEndOfLine (eol) { - const ret = new TextEdit(new Range(new Position(0, 0), new Position(0, 0)), '') - ret.newEol = eol - return ret - } - - get range () { - return this._range - } - - set range (value) { - if (value && !Range.isRange(value)) { - throw new Error('range') - } - this._range = value - } - - get newText () { - return this._newText || '' - } - - set newText (value) { - if (value && typeof value !== 'string') { - throw new Error('newText') - } - this._newText = value - } - - get newEol () { - return this._newEol - } - - set newEol (value) { - if (value && typeof value !== 'number') { - throw new Error('newEol') - } - this._newEol = value - } - - constructor (range, newText) { - this.range = range - this._newText = newText - } - - toJSON () { - return { - range: this.range, - newText: this.newText, - newEol: this._newEol - } - } -} - -export class WorkspaceEdit { - constructor () { - this._edits = [] - } - - renameFile (from, to, options) { - this._edits.push({ _type: 1, from, to, options }) - } - - createFile (uri, options) { - this._edits.push({ _type: 1, from: undefined, to: uri, options }) - } - - deleteFile (uri, options) { - this._edits.push({ _type: 1, from: uri, to: undefined, options }) - } - - replace (uri, range, newText) { - this._edits.push({ _type: 2, uri, edit: new TextEdit(range, newText) }) - } - - insert (resource, position, newText) { - this.replace(resource, new Range(position, position), newText) - } - - delete (resource, range) { - this.replace(resource, range, '') - } - - has (uri) { - for (const edit of this._edits) { - if (edit._type === 2 && edit.uri.toString() === uri.toString()) { - return true - } - } - return false - } - - set (uri, edits) { - if (!edits) { - // remove all text edits for `uri` - for (let i = 0; i < this._edits.length; i++) { - const element = this._edits[i] - if (element._type === 2 && element.uri.toString() === uri.toString()) { - this._edits[i] = undefined // will be coalesced down below - } - } - // this._edits = coalesce(this._edits); TODO - } else { - // append edit to the end - for (const edit of edits) { - if (edit) { - this._edits.push({ _type: 2, uri, edit }) - } - } - } - } - - get (uri) { - const res = [] - for (const candidate of this._edits) { - if (candidate._type === 2 && candidate.uri.toString() === uri.toString()) { - res.push(candidate.edit) - } - } - return res - } - - entries () { - const textEdits = new Map() - for (const candidate of this._edits) { - if (candidate._type === 2) { - let textEdit = textEdits.get(candidate.uri.toString()) - if (!textEdit) { - textEdit = [candidate.uri, []] - textEdits.set(candidate.uri.toString(), textEdit) - } - textEdit[1].push(candidate.edit) - } - } - return values(textEdits) - } - - _allEntries () { - const res = [] - for (const edit of this._edits) { - if (edit._type === 1) { - res.push([edit.from, edit.to, edit.options]) - } else { - res.push([edit.uri, [edit.edit]]) - } - } - return res - } - - get size () { - return this.entries().length - } - - toJSON () { - return this.entries() - } -} - -export const TextEditorRevealType = { - Default: 0, - InCenter: 1, - InCenterIfOutsideViewport: 2, - AtTop: 3 -} - -export const TextEditorSelectionChangeKind = { - Keyboard: 1, - Mouse: 2, - Command: 3 -} - -export class SnippetString { - static isSnippetString (thing) { - if (thing instanceof SnippetString) { - return true - } - if (!thing) { - return false - } - return typeof thing.value === 'string' - } - - static _escape (value) { - return value.replace(/\$|}|\\/g, '\\$&') - } - - constructor (value) { - this._tabstop = 1 - this.value = value || '' - } - - appendText (string) { - this.value += SnippetString._escape(string) - return this - } - - appendTabstop (number = this._tabstop++) { - this.value += '$' - this.value += number - return this - } - - appendPlaceholder (value, number = this._tabstop++) { - if (typeof value === 'function') { - const nested = new SnippetString() - nested._tabstop = this._tabstop - value(nested) - this._tabstop = nested._tabstop - value = nested.value - } else { - value = SnippetString._escape(value) - } - - this.value += '${' - this.value += number - this.value += ':' - this.value += value - this.value += '}' - - return this - } - - appendVariable (name, defaultValue) { - if (typeof defaultValue === 'function') { - const nested = new SnippetString() - nested._tabstop = this._tabstop - defaultValue(nested) - this._tabstop = nested._tabstop - defaultValue = nested.value - } else if (typeof defaultValue === 'string') { - defaultValue = defaultValue.replace(/\$|}/g, '\\$&') - } - - this.value += '${' - this.value += name - if (defaultValue) { - this.value += ':' - this.value += defaultValue - } - this.value += '}' - - return this - } -} diff --git a/ux/src/layouts/AdminLayout.vue b/ux/src/layouts/AdminLayout.vue deleted file mode 100644 index e00447e91..000000000 --- a/ux/src/layouts/AdminLayout.vue +++ /dev/null @@ -1,454 +0,0 @@ - - - - - diff --git a/ux/src/layouts/AuthLayout.vue b/ux/src/layouts/AuthLayout.vue deleted file mode 100644 index 4cb6cf4d3..000000000 --- a/ux/src/layouts/AuthLayout.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/ux/src/layouts/MainLayout.vue b/ux/src/layouts/MainLayout.vue deleted file mode 100644 index ecb97a5bc..000000000 --- a/ux/src/layouts/MainLayout.vue +++ /dev/null @@ -1,275 +0,0 @@ - - - - - diff --git a/ux/src/layouts/ProfileLayout.vue b/ux/src/layouts/ProfileLayout.vue deleted file mode 100644 index ef3a726f6..000000000 --- a/ux/src/layouts/ProfileLayout.vue +++ /dev/null @@ -1,330 +0,0 @@ - - - - - diff --git a/ux/src/main.js b/ux/src/main.js deleted file mode 100644 index 5fc6c9834..000000000 --- a/ux/src/main.js +++ /dev/null @@ -1,80 +0,0 @@ -import { createApp } from 'vue' -import { Quasar, Dialog, Loading, LoadingBar, Meta, Notify } from 'quasar' -import { initializeRouter } from './router' -import { initializeStore } from './stores' -import { initializeApollo } from './boot/apollo' -import { initializeComponents } from './boot/components' -import { initializeEventBus } from './boot/eventbus' -import { initializeExternals } from './boot/externals' -import { initializeI18n } from './boot/i18n' -import quasarIconSet from 'quasar/icon-set/mdi-v7' - -// Import icon libraries -import '@quasar/extras/roboto-font/roboto-font.css' -import '@mdi/font/css/materialdesignicons.css' -import '@quasar/extras/line-awesome/line-awesome.css' - -// Import Quasar css -import 'quasar/src/css/index.sass' -import './css/app.scss' - -import RootApp from './App.vue' - -const router = initializeRouter() -const store = initializeStore(router) - -const app = createApp(RootApp) -app.use(store) -app.use(router) - -initializeApollo(store) -initializeComponents(app) -initializeEventBus() -initializeExternals(router, store) -initializeI18n(app, store) - -app.use(Quasar, { - plugins: { - Dialog, - Loading, - LoadingBar, - Meta, - Notify - }, - iconSet: quasarIconSet, - config: { - brand: { - header: '#000', - sidebar: '#1976D2' - }, - loading: { - delay: 500, - spinner: 'QSpinnerGrid', - spinnerSize: 32, - spinnerColor: 'white', - customClass: 'loading-darker' - }, - loadingBar: { - color: 'primary', - size: '1px', - position: 'top' - }, - notify: { - position: 'top', - progress: true, - color: 'green', - icon: 'las la-check', - actions: [ - { - icon: 'las la-times', - color: 'white', - size: 'sm', - round: true, - handler: () => {} - } - ] - } - } -}) - -app.mount('#app') diff --git a/ux/src/pages/AdminAnalytics.vue b/ux/src/pages/AdminAnalytics.vue deleted file mode 100644 index 337960a62..000000000 --- a/ux/src/pages/AdminAnalytics.vue +++ /dev/null @@ -1,181 +0,0 @@ - - - diff --git a/ux/src/pages/AdminApi.vue b/ux/src/pages/AdminApi.vue deleted file mode 100644 index 9048b3e3e..000000000 --- a/ux/src/pages/AdminApi.vue +++ /dev/null @@ -1,246 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminAuth.vue b/ux/src/pages/AdminAuth.vue deleted file mode 100644 index ca5eca092..000000000 --- a/ux/src/pages/AdminAuth.vue +++ /dev/null @@ -1,671 +0,0 @@ - - - diff --git a/ux/src/pages/AdminBlocks.vue b/ux/src/pages/AdminBlocks.vue deleted file mode 100644 index 2d56caeea..000000000 --- a/ux/src/pages/AdminBlocks.vue +++ /dev/null @@ -1,236 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminComments.vue b/ux/src/pages/AdminComments.vue deleted file mode 100644 index e5cd139ee..000000000 --- a/ux/src/pages/AdminComments.vue +++ /dev/null @@ -1,206 +0,0 @@ - - - diff --git a/ux/src/pages/AdminDashboard.vue b/ux/src/pages/AdminDashboard.vue deleted file mode 100644 index e1e12d75a..000000000 --- a/ux/src/pages/AdminDashboard.vue +++ /dev/null @@ -1,271 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminEditors.vue b/ux/src/pages/AdminEditors.vue deleted file mode 100644 index df015f0d9..000000000 --- a/ux/src/pages/AdminEditors.vue +++ /dev/null @@ -1,309 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminExtensions.vue b/ux/src/pages/AdminExtensions.vue deleted file mode 100644 index 504849078..000000000 --- a/ux/src/pages/AdminExtensions.vue +++ /dev/null @@ -1,229 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminFlags.vue b/ux/src/pages/AdminFlags.vue deleted file mode 100644 index 3e44a094b..000000000 --- a/ux/src/pages/AdminFlags.vue +++ /dev/null @@ -1,257 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminGeneral.vue b/ux/src/pages/AdminGeneral.vue deleted file mode 100644 index 82cb1a887..000000000 --- a/ux/src/pages/AdminGeneral.vue +++ /dev/null @@ -1,916 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminGroups.vue b/ux/src/pages/AdminGroups.vue deleted file mode 100644 index 07f181416..000000000 --- a/ux/src/pages/AdminGroups.vue +++ /dev/null @@ -1,276 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminIcons.vue b/ux/src/pages/AdminIcons.vue deleted file mode 100644 index ef5b23831..000000000 --- a/ux/src/pages/AdminIcons.vue +++ /dev/null @@ -1,254 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminInstances.vue b/ux/src/pages/AdminInstances.vue deleted file mode 100644 index 989df4554..000000000 --- a/ux/src/pages/AdminInstances.vue +++ /dev/null @@ -1,212 +0,0 @@ - - - diff --git a/ux/src/pages/AdminLocale.vue b/ux/src/pages/AdminLocale.vue deleted file mode 100644 index 0be2fb579..000000000 --- a/ux/src/pages/AdminLocale.vue +++ /dev/null @@ -1,267 +0,0 @@ - - - diff --git a/ux/src/pages/AdminLogin.vue b/ux/src/pages/AdminLogin.vue deleted file mode 100644 index c3f58dd1b..000000000 --- a/ux/src/pages/AdminLogin.vue +++ /dev/null @@ -1,407 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminMail.vue b/ux/src/pages/AdminMail.vue deleted file mode 100644 index ac46168a2..000000000 --- a/ux/src/pages/AdminMail.vue +++ /dev/null @@ -1,548 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminMetrics.vue b/ux/src/pages/AdminMetrics.vue deleted file mode 100644 index 119189890..000000000 --- a/ux/src/pages/AdminMetrics.vue +++ /dev/null @@ -1,188 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminNavigation.vue b/ux/src/pages/AdminNavigation.vue deleted file mode 100644 index 19a30f6d5..000000000 --- a/ux/src/pages/AdminNavigation.vue +++ /dev/null @@ -1,619 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminPages.vue b/ux/src/pages/AdminPages.vue deleted file mode 100644 index 4bd5958c9..000000000 --- a/ux/src/pages/AdminPages.vue +++ /dev/null @@ -1,170 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminPagesEdit.vue b/ux/src/pages/AdminPagesEdit.vue deleted file mode 100644 index ef29082cd..000000000 --- a/ux/src/pages/AdminPagesEdit.vue +++ /dev/null @@ -1,235 +0,0 @@ - - - - diff --git a/ux/src/pages/AdminPagesVisualize.vue b/ux/src/pages/AdminPagesVisualize.vue deleted file mode 100644 index 116b38a97..000000000 --- a/ux/src/pages/AdminPagesVisualize.vue +++ /dev/null @@ -1,405 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminRendering.vue b/ux/src/pages/AdminRendering.vue deleted file mode 100644 index 0ebad537c..000000000 --- a/ux/src/pages/AdminRendering.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - diff --git a/ux/src/pages/AdminScheduler.vue b/ux/src/pages/AdminScheduler.vue deleted file mode 100644 index 4a87fd8af..000000000 --- a/ux/src/pages/AdminScheduler.vue +++ /dev/null @@ -1,644 +0,0 @@ - - - diff --git a/ux/src/pages/AdminSearch.vue b/ux/src/pages/AdminSearch.vue deleted file mode 100644 index 941391948..000000000 --- a/ux/src/pages/AdminSearch.vue +++ /dev/null @@ -1,241 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminSecurity.vue b/ux/src/pages/AdminSecurity.vue deleted file mode 100644 index 38b9a87ca..000000000 --- a/ux/src/pages/AdminSecurity.vue +++ /dev/null @@ -1,524 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminSites.vue b/ux/src/pages/AdminSites.vue deleted file mode 100644 index 7ecaf70d5..000000000 --- a/ux/src/pages/AdminSites.vue +++ /dev/null @@ -1,189 +0,0 @@ - - - diff --git a/ux/src/pages/AdminSsl.vue b/ux/src/pages/AdminSsl.vue deleted file mode 100644 index 7da9443ae..000000000 --- a/ux/src/pages/AdminSsl.vue +++ /dev/null @@ -1,269 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminStats.vue b/ux/src/pages/AdminStats.vue deleted file mode 100644 index cbfd09a3e..000000000 --- a/ux/src/pages/AdminStats.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminStorage.vue b/ux/src/pages/AdminStorage.vue deleted file mode 100644 index f7e1af480..000000000 --- a/ux/src/pages/AdminStorage.vue +++ /dev/null @@ -1,1262 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminSystem.vue b/ux/src/pages/AdminSystem.vue deleted file mode 100644 index 1006bab94..000000000 --- a/ux/src/pages/AdminSystem.vue +++ /dev/null @@ -1,383 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminTags.vue b/ux/src/pages/AdminTags.vue deleted file mode 100644 index 35742d899..000000000 --- a/ux/src/pages/AdminTags.vue +++ /dev/null @@ -1,248 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminTerminal.vue b/ux/src/pages/AdminTerminal.vue deleted file mode 100644 index e39228b3e..000000000 --- a/ux/src/pages/AdminTerminal.vue +++ /dev/null @@ -1,171 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminTheme.vue b/ux/src/pages/AdminTheme.vue deleted file mode 100644 index 6d8c6f1d4..000000000 --- a/ux/src/pages/AdminTheme.vue +++ /dev/null @@ -1,812 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminUsers.vue b/ux/src/pages/AdminUsers.vue deleted file mode 100644 index 34af910ef..000000000 --- a/ux/src/pages/AdminUsers.vue +++ /dev/null @@ -1,334 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminUtilities.vue b/ux/src/pages/AdminUtilities.vue deleted file mode 100644 index 665fb4305..000000000 --- a/ux/src/pages/AdminUtilities.vue +++ /dev/null @@ -1,205 +0,0 @@ - - - - - diff --git a/ux/src/pages/AdminWebhooks.vue b/ux/src/pages/AdminWebhooks.vue deleted file mode 100644 index b27e76052..000000000 --- a/ux/src/pages/AdminWebhooks.vue +++ /dev/null @@ -1,202 +0,0 @@ - - - - - diff --git a/ux/src/pages/ErrorGeneric.vue b/ux/src/pages/ErrorGeneric.vue deleted file mode 100644 index b09b206ec..000000000 --- a/ux/src/pages/ErrorGeneric.vue +++ /dev/null @@ -1,144 +0,0 @@ - - - - - diff --git a/ux/src/pages/Index.vue b/ux/src/pages/Index.vue deleted file mode 100644 index a13a68c3e..000000000 --- a/ux/src/pages/Index.vue +++ /dev/null @@ -1,499 +0,0 @@ - - - - - diff --git a/ux/src/pages/Login.vue b/ux/src/pages/Login.vue deleted file mode 100644 index 42e814021..000000000 --- a/ux/src/pages/Login.vue +++ /dev/null @@ -1,486 +0,0 @@ - - - - - diff --git a/ux/src/pages/ProfileAuth.vue b/ux/src/pages/ProfileAuth.vue deleted file mode 100644 index f48b45d84..000000000 --- a/ux/src/pages/ProfileAuth.vue +++ /dev/null @@ -1,418 +0,0 @@ - - - diff --git a/ux/src/pages/ProfileAvatar.vue b/ux/src/pages/ProfileAvatar.vue deleted file mode 100644 index 7d8c062e3..000000000 --- a/ux/src/pages/ProfileAvatar.vue +++ /dev/null @@ -1,203 +0,0 @@ - - - - - diff --git a/ux/src/pages/ProfileGroups.vue b/ux/src/pages/ProfileGroups.vue deleted file mode 100644 index 146af8799..000000000 --- a/ux/src/pages/ProfileGroups.vue +++ /dev/null @@ -1,114 +0,0 @@ - - - diff --git a/ux/src/pages/ProfileInfo.vue b/ux/src/pages/ProfileInfo.vue deleted file mode 100644 index 8608b115d..000000000 --- a/ux/src/pages/ProfileInfo.vue +++ /dev/null @@ -1,327 +0,0 @@ - - - diff --git a/ux/src/pages/Search.vue b/ux/src/pages/Search.vue deleted file mode 100644 index 5647b61dc..000000000 --- a/ux/src/pages/Search.vue +++ /dev/null @@ -1,578 +0,0 @@ - - - - - diff --git a/ux/src/renderers/markdown.js b/ux/src/renderers/markdown.js deleted file mode 100644 index 4559e89fd..000000000 --- a/ux/src/renderers/markdown.js +++ /dev/null @@ -1,186 +0,0 @@ -import MarkdownIt from 'markdown-it' -import mdAttrs from 'markdown-it-attrs' -import mdDecorate from 'markdown-it-decorate' -import { full as mdEmoji } from 'markdown-it-emoji' -import mdTaskLists from 'markdown-it-task-lists' -import mdExpandTabs from 'markdown-it-expand-tabs' -import mdAbbr from 'markdown-it-abbr' -import mdSup from 'markdown-it-sup' -import mdSub from 'markdown-it-sub' -import mdMark from 'markdown-it-mark' -import mdMultiTable from 'markdown-it-multimd-table' -import mdFootnote from 'markdown-it-footnote' -import mdMdc from 'markdown-it-mdc' -import katex from 'katex' -import mdUnderline from './modules/markdown-it-underline' -import mdImsize from './modules/markdown-it-imsize' -import 'katex/dist/contrib/mhchem' -import twemoji from 'twemoji' -import plantuml from './modules/plantuml' -import kroki from './modules/kroki.mjs' -import katexHelper from './modules/katex' - -import hljs from 'highlight.js' - -import { escape, findLast, times } from 'lodash-es' - -const quoteStyles = { - chinese: '””‘’', - english: '“”‘’', - french: ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'], - german: '„“‚‘', - greek: '«»‘’', - japanese: '「」「」', - hungarian: '„”’’', - polish: '„”‚‘', - portuguese: '«»‘’', - russian: '«»„“', - spanish: '«»‘’', - swedish: '””’’' -} - -export class MarkdownRenderer { - constructor (config = {}) { - this.md = new MarkdownIt({ - html: config.allowHTML, - breaks: config.lineBreaks, - linkify: config.linkify, - typography: config.typographer, - quotes: quoteStyles[config.quotes] ?? quoteStyles.english, - highlight (str, lang) { - if (lang === 'diagram') { - return `
    ${Buffer.from(str, 'base64').toString()}
    ` - } else if (['mermaid', 'plantuml'].includes(lang)) { - return `
    ${escape(str)}
    ` - } else { - const highlighted = lang ? hljs.highlight(str, { language: lang, ignoreIllegals: true }) : { value: str } - const lineCount = highlighted.value.match(/\n/g).length - const lineNums = lineCount > 1 ? `` : '' - return `
    ${highlighted.value}${lineNums}
    ` - } - } - }) - .use(mdMdc) - .use(mdAttrs, { - allowedAttributes: ['id', 'class', 'target'] - }) - .use(mdDecorate) - .use(mdEmoji) - .use(mdTaskLists, { label: false, labelAfter: false }) - .use(mdExpandTabs, { tabWidth: config.tabWidth }) - .use(mdAbbr) - .use(mdSup) - .use(mdSub) - .use(mdMark) - .use(mdFootnote) - .use(mdImsize) - - if (config.underline) { - this.md.use(mdUnderline) - } - - if (config.mdmultiTable) { - this.md.use(mdMultiTable, { multiline: true, rowspan: true, headerless: true }) - } - - // -------------------------------- - // PLANTUML - // -------------------------------- - - if (config.plantuml) { - plantuml.init(this.md, { server: config.plantumlServerUrl }) - } - - // -------------------------------- - // KROKI - // -------------------------------- - - if (config.kroki) { - kroki.init(this.md, { server: config.krokiServerUrl }) - } - - // -------------------------------- - // KATEX - // -------------------------------- - - const macros = {} - - // TODO: Add mhchem (needs esm conversion) - // Add \ce, \pu, and \tripledash to the KaTeX macros. - // katex.__defineMacro('\\ce', function (context) { - // return chemParse(context.consumeArgs(1)[0], 'ce') - // }) - // katex.__defineMacro('\\pu', function (context) { - // return chemParse(context.consumeArgs(1)[0], 'pu') - // }) - - // Needed for \bond for the ~ forms - // Raise by 2.56mu, not 2mu. We're raising a hyphen-minus, U+002D, not - // a mathematical minus, U+2212. So we need that extra 0.56. - katex.__defineMacro('\\tripledash', '{\\vphantom{-}\\raisebox{2.56mu}{$\\mkern2mu' + '\\tiny\\text{-}\\mkern1mu\\text{-}\\mkern1mu\\text{-}\\mkern2mu$}}') - this.md.inline.ruler.after('escape', 'katex_inline', katexHelper.katexInline) - this.md.renderer.rules.katex_inline = (tokens, idx) => { - try { - return katex.renderToString(tokens[idx].content, { - displayMode: false, macros - }) - } catch (err) { - console.warn(err) - return tokens[idx].content - } - } - this.md.block.ruler.after('blockquote', 'katex_block', katexHelper.katexBlock, { - alt: ['paragraph', 'reference', 'blockquote', 'list'] - }) - this.md.renderer.rules.katex_block = (tokens, idx) => { - try { - return '

    ' + katex.renderToString(tokens[idx].content, { - displayMode: true, macros - }) + '

    ' - } catch (err) { - console.warn(err) - return tokens[idx].content - } - } - - // -------------------------------- - // TWEMOJI - // -------------------------------- - - this.md.renderer.rules.emoji = (token, idx) => { - return twemoji.parse(token[idx].content, { - callback (icon, opts) { - return `/_assets/svg/twemoji/${icon}.svg` - } - }) - } - - // -------------------------------- - // Inject line numbers for preview scroll sync - // -------------------------------- - - this.linesMap = [] - const injectLineNumbers = (tokens, idx, options, env, slf) => { - let line - if (tokens[idx].map && tokens[idx].level === 0) { - line = tokens[idx].map[0] + 1 - tokens[idx].attrJoin('class', 'line') - tokens[idx].attrSet('data-line', String(line)) - this.linesMap.push(line) - } - return slf.renderToken(tokens, idx, options, env, slf) - } - this.md.renderer.rules.paragraph_open = injectLineNumbers - this.md.renderer.rules.heading_open = injectLineNumbers - this.md.renderer.rules.blockquote_open = injectLineNumbers - } - - render (src) { - this.linesMap = [] - return this.md.render(src) - } - - getClosestPreviewLine (line) { - return findLast(this.linesMap, n => n <= line) - } -} diff --git a/ux/src/renderers/modules/katex.js b/ux/src/renderers/modules/katex.js deleted file mode 100644 index 74a096dbc..000000000 --- a/ux/src/renderers/modules/katex.js +++ /dev/null @@ -1,145 +0,0 @@ -// Test if potential opening or closing delimieter -// Assumes that there is a "$" at state.src[pos] -function isValidDelim (state, pos) { - const max = state.posMax - let canOpen = true - let canClose = true - - const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1 - const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1 - - // Check non-whitespace conditions for opening and closing, and - // check that closing delimeter isn't followed by a number - if (prevChar === 0x20/* " " */ || prevChar === 0x09/* \t */ || - (nextChar >= 0x30/* "0" */ && nextChar <= 0x39/* "9" */)) { - canClose = false - } - if (nextChar === 0x20/* " " */ || nextChar === 0x09/* \t */) { - canOpen = false - } - - return { - canOpen, - canClose - } -} - -export default { - katexInline (state, silent) { - let match, token, res, pos - - if (state.src[state.pos] !== '$') { return false } - - res = isValidDelim(state, state.pos) - if (!res.canOpen) { - if (!silent) { state.pending += '$' } - state.pos += 1 - return true - } - - // First check for and bypass all properly escaped delimieters - // This loop will assume that the first leading backtick can not - // be the first character in state.src, which is known since - // we have found an opening delimieter already. - const start = state.pos + 1 - match = start - while ((match = state.src.indexOf('$', match)) !== -1) { - // Found potential $, look for escapes, pos will point to - // first non escape when complete - pos = match - 1 - while (state.src[pos] === '\\') { pos -= 1 } - - // Even number of escapes, potential closing delimiter found - if (((match - pos) % 2) === 1) { break } - match += 1 - } - - // No closing delimter found. Consume $ and continue. - if (match === -1) { - if (!silent) { state.pending += '$' } - state.pos = start - return true - } - - // Check if we have empty content, ie: $$. Do not parse. - if (match - start === 0) { - if (!silent) { state.pending += '$$' } - state.pos = start + 1 - return true - } - - // Check for valid closing delimiter - res = isValidDelim(state, match) - if (!res.canClose) { - if (!silent) { state.pending += '$' } - state.pos = start - return true - } - - if (!silent) { - token = state.push('katex_inline', 'math', 0) - token.markup = '$' - token.content = state.src - // Extract the math part without the $ - .slice(start, match) - // Escape the curly braces since they will be interpreted as - // attributes by markdown-it-attrs (the "curly_attributes" - // core rule) - .replaceAll('{', '{{') - .replaceAll('}', '}}') - } - - state.pos = match + 1 - return true - }, - - katexBlock (state, start, end, silent) { - let firstLine; let lastLine; let next; let lastPos; let found = false - let pos = state.bMarks[start] + state.tShift[start] - let max = state.eMarks[start] - - if (pos + 2 > max) { return false } - if (state.src.slice(pos, pos + 2) !== '$$') { return false } - - pos += 2 - firstLine = state.src.slice(pos, max) - - if (silent) { return true } - if (firstLine.trim().slice(-2) === '$$') { - // Single line expression - firstLine = firstLine.trim().slice(0, -2) - found = true - } - - for (next = start; !found;) { - next++ - - if (next >= end) { break } - - pos = state.bMarks[next] + state.tShift[next] - max = state.eMarks[next] - - if (pos < max && state.tShift[next] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - break - } - - if (state.src.slice(pos, max).trim().slice(-2) === '$$') { - lastPos = state.src.slice(0, max).lastIndexOf('$$') - lastLine = state.src.slice(pos, lastPos) - found = true - } - } - - state.line = next + 1 - - const token = state.push('katex_block', 'math', 0) - token.block = true - token.content = (firstLine && firstLine.trim() ? firstLine + '\n' : '') + - state.getLines(start + 1, next, state.tShift[start], true) + - (lastLine && lastLine.trim() ? lastLine : '') - token.map = [start, state.line] - token.markup = '$$' - return true - } -} diff --git a/ux/src/renderers/modules/kroki.mjs b/ux/src/renderers/modules/kroki.mjs deleted file mode 100644 index 43e102bc7..000000000 --- a/ux/src/renderers/modules/kroki.mjs +++ /dev/null @@ -1,143 +0,0 @@ -import pako from 'pako' - -// ------------------------------------ -// Markdown - PlantUML Preprocessor -// ------------------------------------ - -export default { - init (mdinst, conf) { - mdinst.use((md, opts) => { - const openMarker = opts.openMarker || '```kroki' - const openChar = openMarker.charCodeAt(0) - const closeMarker = opts.closeMarker || '```' - const closeChar = closeMarker.charCodeAt(0) - const server = opts.server || 'https://kroki.io' - - md.block.ruler.before('fence', 'kroki', (state, startLine, endLine, silent) => { - let nextLine - let markup - let params - let token - let i - let autoClosed = false - let start = state.bMarks[startLine] + state.tShift[startLine] - let max = state.eMarks[startLine] - - // Check out the first character quickly, - // this should filter out most of non-uml blocks - // - if (openChar !== state.src.charCodeAt(start)) { return false } - - // Check out the rest of the marker string - // - for (i = 0; i < openMarker.length; ++i) { - if (openMarker[i] !== state.src[start + i]) { return false } - } - - markup = state.src.slice(start, start + i) - params = state.src.slice(start + i, max) - - // Since start is found, we can report success here in validation mode - // - if (silent) { return true } - - // Search for the end of the block - // - nextLine = startLine - - for (;;) { - nextLine++ - if (nextLine >= endLine) { - // unclosed block should be autoclosed by end of document. - // also block seems to be autoclosed by end of parent - break - } - - start = state.bMarks[nextLine] + state.tShift[nextLine] - max = state.eMarks[nextLine] - - if (start < max && state.sCount[nextLine] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - // - ``` - // test - break - } - - if (closeChar !== state.src.charCodeAt(start)) { - // didn't find the closing fence - continue - } - - if (state.sCount[nextLine] > state.sCount[startLine]) { - // closing fence should not be indented with respect of opening fence - continue - } - - let closeMarkerMatched = true - for (i = 0; i < closeMarker.length; ++i) { - if (closeMarker[i] !== state.src[start + i]) { - closeMarkerMatched = false - break - } - } - - if (!closeMarkerMatched) { - continue - } - - // make sure tail has spaces only - if (state.skipSpaces(start + i) < max) { - continue - } - - // found! - autoClosed = true - break - } - - let contents = state.src - .split('\n') - .slice(startLine + 1, nextLine) - .join('\n') - - // We generate a token list for the alt property, to mimic what the image parser does. - let altToken = [] - // Remove leading space if any. - let alt = params ? params.slice(1) : 'uml diagram' - state.md.inline.parse( - alt, - state.md, - state.env, - altToken - ) - - let firstlf = contents.indexOf('\n') - if (firstlf === -1) firstlf = undefined - let diagramType = contents.substring(0, firstlf) - contents = contents.substring(firstlf + 1) - - const result = pako.deflate(contents).toString('base64').replace(/\+/g, '-').replace(/\//g, '_') - - token = state.push('kroki', 'img', 0) - // alt is constructed from children. No point in populating it here. - token.attrs = [ [ 'src', `${server}/${diagramType}/svg/${result}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ] - token.block = true - token.children = altToken - token.info = params - token.map = [ startLine, nextLine ] - token.markup = markup - - state.line = nextLine + (autoClosed ? 1 : 0) - - return true - }, { - alt: [ 'paragraph', 'reference', 'blockquote', 'list' ] - }) - md.renderer.rules.kroki = md.renderer.rules.image - }, { - openMarker: conf.openMarker, - closeMarker: conf.closeMarker, - server: conf.server - }) - } -} diff --git a/ux/src/renderers/modules/markdown-it-imsize.js b/ux/src/renderers/modules/markdown-it-imsize.js deleted file mode 100644 index 6b6b30e6c..000000000 --- a/ux/src/renderers/modules/markdown-it-imsize.js +++ /dev/null @@ -1,259 +0,0 @@ -// Adapted from markdown-it-imsize plugin by @tatsy -// Original source https://github.com/tatsy/markdown-it-imsize/blob/master/lib/index.js - -function renderImSize (state, silent) { - let attrs - let code - let label - let pos - let ref - let res - let title - let width = '' - let height = '' - let token - let tokens - let start - let href = '' - const oldPos = state.pos - const max = state.posMax - - if (state.src.charCodeAt(state.pos) !== 0x21/* ! */) { return false } - if (state.src.charCodeAt(state.pos + 1) !== 0x5B/* [ */) { return false } - - const labelStart = state.pos + 2 - const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false) - - // parser failed to find ']', so it's not a valid link - if (labelEnd < 0) { return false } - - pos = labelEnd + 1 - if (pos < max && state.src.charCodeAt(pos) === 0x28/* ( */) { - // - // Inline link - // - - // [link]( "title" ) - // ^^ skipping these spaces - pos++ - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - if (pos >= max) { return false } - - // [link]( "title" ) - // ^^^^^^ parsing link destination - start = pos - res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax) - if (res.ok) { - href = state.md.normalizeLink(res.str) - if (state.md.validateLink(href)) { - pos = res.pos - } else { - href = '' - } - } - - // [link]( "title" ) - // ^^ skipping these spaces - start = pos - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - - // [link]( "title" ) - // ^^^^^^^ parsing link title - res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax) - if (pos < max && start !== pos && res.ok) { - title = res.str - pos = res.pos - - // [link]( "title" ) - // ^^ skipping these spaces - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - } else { - title = '' - } - - // [link]( "title" =WxH ) - // ^^^^ parsing image size - if (pos - 1 >= 0) { - code = state.src.charCodeAt(pos - 1) - - // there must be at least one white spaces - // between previous field and the size - if (code === 0x20) { - res = parseImageSize(state.src, pos, state.posMax) - if (res.ok) { - width = res.width - height = res.height - pos = res.pos - - // [link]( "title" =WxH ) - // ^^ skipping these spaces - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - } - } - } - - if (pos >= max || state.src.charCodeAt(pos) !== 0x29/* ) */) { - state.pos = oldPos - return false - } - pos++ - } else { - // - // Link reference - // - if (typeof state.env.references === 'undefined') { return false } - - // [foo] [bar] - // ^^ optional whitespace (can include newlines) - for (; pos < max; pos++) { - code = state.src.charCodeAt(pos) - if (code !== 0x20 && code !== 0x0A) { break } - } - - if (pos < max && state.src.charCodeAt(pos) === 0x5B/* [ */) { - start = pos + 1 - pos = state.md.helpers.parseLinkLabel(state, pos) - if (pos >= 0) { - label = state.src.slice(start, pos++) - } else { - pos = labelEnd + 1 - } - } else { - pos = labelEnd + 1 - } - - // covers label === '' and label === undefined - // (collapsed reference link and shortcut reference link respectively) - if (!label) { label = state.src.slice(labelStart, labelEnd) } - - ref = state.env.references[state.md.utils.normalizeReference(label)] - if (!ref) { - state.pos = oldPos - return false - } - href = ref.href - title = ref.title - } - - // - // We found the end of the link, and know for a fact it's a valid link; - // so all that's left to do is to call tokenizer. - // - if (!silent) { - state.pos = labelStart - state.posMax = labelEnd - - const newState = new state.md.inline.State( - state.src.slice(labelStart, labelEnd), - state.md, - state.env, - tokens = [] - ) - newState.md.inline.tokenize(newState) - - token = state.push('image', 'img', 0) - token.attrs = attrs = [['src', href], - ['alt', '']] - token.children = tokens - if (title) { - attrs.push(['title', title]) - } - - if (width !== '') { - attrs.push(['width', width]) - } - - if (height !== '') { - attrs.push(['height', height]) - } - } - - state.pos = pos - state.posMax = max - return true -} - -function parseNextNumber (str, pos, max) { - let code - const start = pos - const result = { - ok: false, - pos, - value: '' - } - - code = str.charCodeAt(pos) - - while ((pos < max && (code >= 0x30 /* 0 */ && code <= 0x39 /* 9 */)) || code === 0x25 /* % */) { - code = str.charCodeAt(++pos) - } - - result.ok = true - result.pos = pos - result.value = str.slice(start, pos) - - return result -} - -function parseImageSize (str, pos, max) { - let code - const result = { - ok: false, - pos: 0, - width: '', - height: '' - } - - if (pos >= max) { return result } - - code = str.charCodeAt(pos) - - if (code !== 0x3d /* = */) { return result } - - pos++ - - // size must follow = without any white spaces as follows - // (1) =300x200 - // (2) =300x - // (3) =x200 - code = str.charCodeAt(pos) - if (code !== 0x78 /* x */ && (code < 0x30 || code > 0x39) /* [0-9] */) { - return result - } - - // parse width - const resultW = parseNextNumber(str, pos, max) - pos = resultW.pos - - // next charactor must be 'x' - code = str.charCodeAt(pos) - if (code !== 0x78 /* x */) { return result } - - pos++ - - // parse height - const resultH = parseNextNumber(str, pos, max) - pos = resultH.pos - - result.width = resultW.value - result.height = resultH.value - result.pos = pos - result.ok = true - return result -} - -export default (md) => { - md.inline.ruler.before('emphasis', 'image', renderImSize) -} diff --git a/ux/src/renderers/modules/markdown-it-underline.js b/ux/src/renderers/modules/markdown-it-underline.js deleted file mode 100644 index b898d1ce0..000000000 --- a/ux/src/renderers/modules/markdown-it-underline.js +++ /dev/null @@ -1,12 +0,0 @@ -function renderEm (tokens, idx, opts, env, slf) { - const token = tokens[idx] - if (token.markup === '_') { - token.tag = 'u' - } - return slf.renderToken(tokens, idx, opts) -} - -export default (md) => { - md.renderer.rules.em_open = renderEm - md.renderer.rules.em_close = renderEm -} diff --git a/ux/src/renderers/modules/plantuml.js b/ux/src/renderers/modules/plantuml.js deleted file mode 100644 index 9d5e3ea58..000000000 --- a/ux/src/renderers/modules/plantuml.js +++ /dev/null @@ -1,187 +0,0 @@ -import pako from 'pako' - -// ------------------------------------ -// Markdown - PlantUML Preprocessor -// ------------------------------------ - -export default { - init (mdinst, conf) { - mdinst.use((md, opts) => { - const openMarker = opts.openMarker || '```plantuml' - const openChar = openMarker.charCodeAt(0) - const closeMarker = opts.closeMarker || '```' - const closeChar = closeMarker.charCodeAt(0) - const imageFormat = opts.imageFormat || 'svg' - const server = opts.server || 'https://plantuml.requarks.io' - - md.block.ruler.before('fence', 'uml_diagram', (state, startLine, endLine, silent) => { - let nextLine - let i - let autoClosed = false - let start = state.bMarks[startLine] + state.tShift[startLine] - let max = state.eMarks[startLine] - - // Check out the first character quickly, - // this should filter out most of non-uml blocks - // - if (openChar !== state.src.charCodeAt(start)) { return false } - - // Check out the rest of the marker string - // - for (i = 0; i < openMarker.length; ++i) { - if (openMarker[i] !== state.src[start + i]) { return false } - } - - const markup = state.src.slice(start, start + i) - const params = state.src.slice(start + i, max) - - // Since start is found, we can report success here in validation mode - // - if (silent) { return true } - - // Search for the end of the block - // - nextLine = startLine - - for (;;) { - nextLine++ - if (nextLine >= endLine) { - // unclosed block should be autoclosed by end of document. - // also block seems to be autoclosed by end of parent - break - } - - start = state.bMarks[nextLine] + state.tShift[nextLine] - max = state.eMarks[nextLine] - - if (start < max && state.sCount[nextLine] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - // - ``` - // test - break - } - - if (closeChar !== state.src.charCodeAt(start)) { - // didn't find the closing fence - continue - } - - if (state.sCount[nextLine] > state.sCount[startLine]) { - // closing fence should not be indented with respect of opening fence - continue - } - - let closeMarkerMatched = true - for (i = 0; i < closeMarker.length; ++i) { - if (closeMarker[i] !== state.src[start + i]) { - closeMarkerMatched = false - break - } - } - - if (!closeMarkerMatched) { - continue - } - - // make sure tail has spaces only - if (state.skipSpaces(start + i) < max) { - continue - } - - // found! - autoClosed = true - break - } - - const contents = state.src - .split('\n') - .slice(startLine + 1, nextLine) - .join('\n') - - // We generate a token list for the alt property, to mimic what the image parser does. - const altToken = [] - // Remove leading space if any. - const alt = params ? params.slice(1) : 'uml diagram' - state.md.inline.parse( - alt, - state.md, - state.env, - altToken - ) - - const zippedCode = encode64(pako.deflate('@startuml\n' + contents + '\n@enduml', { to: 'string' })) - - const token = state.push('uml_diagram', 'img', 0) - // alt is constructed from children. No point in populating it here. - token.attrs = [['src', `${server}/${imageFormat}/${zippedCode}`], ['alt', ''], ['class', 'uml-diagram']] - token.block = true - token.children = altToken - token.info = params - token.map = [startLine, nextLine] - token.markup = markup - - state.line = nextLine + (autoClosed ? 1 : 0) - - return true - }, { - alt: ['paragraph', 'reference', 'blockquote', 'list'] - }) - md.renderer.rules.uml_diagram = md.renderer.rules.image - }, { - openMarker: conf.openMarker, - closeMarker: conf.closeMarker, - imageFormat: conf.imageFormat, - server: conf.server - }) - } -} - -function encode64 (data) { - let r = '' - for (let i = 0; i < data.length; i += 3) { - if (i + 2 === data.length) { - r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), 0) - } else if (i + 1 === data.length) { - r += append3bytes(data.charCodeAt(i), 0, 0) - } else { - r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), data.charCodeAt(i + 2)) - } - } - return r -} - -function append3bytes (b1, b2, b3) { - const c1 = b1 >> 2 - const c2 = ((b1 & 0x3) << 4) | (b2 >> 4) - const c3 = ((b2 & 0xF) << 2) | (b3 >> 6) - const c4 = b3 & 0x3F - let r = '' - r += encode6bit(c1 & 0x3F) - r += encode6bit(c2 & 0x3F) - r += encode6bit(c3 & 0x3F) - r += encode6bit(c4 & 0x3F) - return r -} - -function encode6bit (raw) { - let b = raw - if (b < 10) { - return String.fromCharCode(48 + b) - } - b -= 10 - if (b < 26) { - return String.fromCharCode(65 + b) - } - b -= 26 - if (b < 26) { - return String.fromCharCode(97 + b) - } - b -= 26 - if (b === 0) { - return '-' - } - if (b === 1) { - return '_' - } - return '?' -} diff --git a/ux/src/router/index.js b/ux/src/router/index.js deleted file mode 100644 index fb5526605..000000000 --- a/ux/src/router/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import { createRouter, createMemoryHistory, createWebHistory } from 'vue-router' -import routes from './routes' - -export function initializeRouter () { - const createHistory = import.meta.env.SSR - ? createMemoryHistory - : createWebHistory - - const router = createRouter({ - scrollBehavior: () => ({ left: 0, top: 0 }), - routes, - history: createHistory(import.meta.env.BASE_URL) - }) - - return router -} diff --git a/ux/src/router/routes.js b/ux/src/router/routes.js deleted file mode 100644 index 0cf5d40a2..000000000 --- a/ux/src/router/routes.js +++ /dev/null @@ -1,118 +0,0 @@ -import { usePageStore } from '@/stores/page' - -const routes = [ - { - path: '/login', - component: () => import('@/layouts/AuthLayout.vue'), - children: [ - { path: '', component: () => import('@/pages/Login.vue') } - ] - }, - { - path: '/a/:alias', - component: () => import('@/layouts/MainLayout.vue'), - beforeEnter: async (to, from) => { - const pageStore = usePageStore() - try { - const pathPath = await pageStore.pageAlias(to.params.alias) - return `/${pathPath}` - } catch (err) { - return '/_error/notfound' - } - } - }, - { - path: '/_profile', - component: () => import('@/layouts/ProfileLayout.vue'), - children: [ - { path: '', redirect: '/_profile/info' }, - { path: 'info', component: () => import('@/pages/ProfileInfo.vue') }, - { path: 'avatar', component: () => import('@/pages/ProfileAvatar.vue') }, - { path: 'auth', component: () => import('@/pages/ProfileAuth.vue') }, - { path: 'groups', component: () => import('@/pages/ProfileGroups.vue') } - ] - }, - { - path: '/_search', - component: () => import('@/pages/Search.vue') - }, - { - path: '/_admin', - component: () => import('@/layouts/AdminLayout.vue'), - children: [ - { path: '', redirect: '/_admin/dashboard' }, - { path: 'dashboard', component: () => import('@/pages/AdminDashboard.vue') }, - { path: 'sites', component: () => import('@/pages/AdminSites.vue') }, - // -> Site - { path: ':siteid/general', component: () => import('@/pages/AdminGeneral.vue') }, - { path: ':siteid/blocks', component: () => import('@/pages/AdminBlocks.vue') }, - { path: ':siteid/editors', component: () => import('@/pages/AdminEditors.vue') }, - { path: ':siteid/locale', component: () => import('@/pages/AdminLocale.vue') }, - { path: ':siteid/login', component: () => import('@/pages/AdminLogin.vue') }, - { path: ':siteid/navigation', component: () => import('@/pages/AdminNavigation.vue') }, - { path: ':siteid/storage/:id?', component: () => import('@/pages/AdminStorage.vue') }, - { path: ':siteid/theme', component: () => import('@/pages/AdminTheme.vue') }, - // -> Users - { path: 'auth', component: () => import('@/pages/AdminAuth.vue') }, - { path: 'groups/:id?/:section?', component: () => import('@/pages/AdminGroups.vue') }, - { path: 'users/:id?/:section?', component: () => import('@/pages/AdminUsers.vue') }, - // -> System - { path: 'api', component: () => import('@/pages/AdminApi.vue') }, - { path: 'extensions', component: () => import('@/pages/AdminExtensions.vue') }, - { path: 'icons', component: () => import('@/pages/AdminIcons.vue') }, - { path: 'instances', component: () => import('@/pages/AdminInstances.vue') }, - { path: 'mail', component: () => import('@/pages/AdminMail.vue') }, - { path: 'metrics', component: () => import('@/pages/AdminMetrics.vue') }, - { path: 'rendering', component: () => import('@/pages/AdminRendering.vue') }, - { path: 'scheduler', component: () => import('@/pages/AdminScheduler.vue') }, - { path: 'search', component: () => import('@/pages/AdminSearch.vue') }, - { path: 'security', component: () => import('@/pages/AdminSecurity.vue') }, - { path: 'system', component: () => import('@/pages/AdminSystem.vue') }, - { path: 'terminal', component: () => import('@/pages/AdminTerminal.vue') }, - { path: 'utilities', component: () => import('@/pages/AdminUtilities.vue') }, - { path: 'webhooks', component: () => import('@/pages/AdminWebhooks.vue') }, - { path: 'flags', component: () => import('@/pages/AdminFlags.vue') } - ] - }, - { - path: '/_error/:action?', - component: () => import('@/pages/ErrorGeneric.vue') - }, - // { - // path: '/_unknown-site', - // component: () => import('../pages/UnknownSite.vue') - // }, - - // -------------------------------- - // CREATE - // -------------------------------- - { - path: '/_create/:editor?', - component: () => import('../layouts/MainLayout.vue'), - children: [ - { path: '', component: () => import('../pages/Index.vue') } - ] - }, - // -------------------------------- - // EDIT - // -------------------------------- - { - path: '/_edit/:pagePath?', - component: () => import('../layouts/MainLayout.vue'), - children: [ - { path: '', component: () => import('../pages/Index.vue') } - ] - }, - // ----------------------- - // STANDARD PAGE CATCH-ALL - // ----------------------- - { - path: '/:catchAll(.*)*', - component: () => import('../layouts/MainLayout.vue'), - children: [ - { path: '', component: () => import('../pages/Index.vue') } - ] - } -] - -export default routes diff --git a/ux/src/stores/admin.js b/ux/src/stores/admin.js deleted file mode 100644 index 4a6c2e03a..000000000 --- a/ux/src/stores/admin.js +++ /dev/null @@ -1,105 +0,0 @@ -import { defineStore } from 'pinia' -import gql from 'graphql-tag' -import { clone, cloneDeep, sortBy } from 'lodash-es' -import semverGte from 'semver/functions/gte' - -/* global APOLLO_CLIENT */ - -export const useAdminStore = defineStore('admin', { - state: () => ({ - currentSiteId: null, - info: { - currentVersion: 'n/a', - latestVersion: 'n/a', - groupsTotal: 0, - pagesTotal: 0, - tagsTotal: 0, - usersTotal: 0, - loginsPastDay: 0, - isApiEnabled: false, - isMailConfigured: false, - isSchedulerHealthy: false - }, - overlay: null, - overlayOpts: {}, - sites: [], - locales: [ - { code: 'en', name: 'English' } - ] - }), - getters: { - isVersionLatest: (state) => { - if (!state.info.currentVersion || !state.info.latestVersion || state.info.currentVersion === 'n/a' || state.info.latestVersion === 'n/a') { - return false - } - return semverGte(state.info.currentVersion, state.info.latestVersion) - } - }, - actions: { - async fetchLocales () { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query getAdminLocales { - locales { - code - language - name - nativeName - } - } - ` - }) - this.locales = sortBy(cloneDeep(resp?.data?.locales ?? []), ['nativeName', 'name']) - }, - async fetchInfo () { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query getAdminInfo { - apiState - metricsState - systemInfo { - groupsTotal - tagsTotal - usersTotal - loginsPastDay - currentVersion - latestVersion - isMailConfigured - isSchedulerHealthy - } - } - `, - fetchPolicy: 'network-only' - }) - this.info.groupsTotal = clone(resp?.data?.systemInfo?.groupsTotal ?? 0) - this.info.tagsTotal = clone(resp?.data?.systemInfo?.tagsTotal ?? 0) - this.info.usersTotal = clone(resp?.data?.systemInfo?.usersTotal ?? 0) - this.info.loginsPastDay = clone(resp?.data?.systemInfo?.loginsPastDay ?? 0) - this.info.currentVersion = clone(resp?.data?.systemInfo?.currentVersion ?? 'n/a') - this.info.latestVersion = clone(resp?.data?.systemInfo?.latestVersion ?? 'n/a') - this.info.isApiEnabled = clone(resp?.data?.apiState ?? false) - this.info.isMetricsEnabled = clone(resp?.data?.metricsState ?? false) - this.info.isMailConfigured = clone(resp?.data?.systemInfo?.isMailConfigured ?? false) - this.info.isSchedulerHealthy = clone(resp?.data?.systemInfo?.isSchedulerHealthy ?? false) - }, - async fetchSites () { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query getSites { - sites { - id - hostname - isEnabled - title - } - } - `, - fetchPolicy: 'network-only' - }) - this.sites = cloneDeep(resp?.data?.sites ?? []) - if (!this.currentSiteId) { - this.currentSiteId = this.sites[0].id - } - } - } -}) diff --git a/ux/src/stores/common.js b/ux/src/stores/common.js deleted file mode 100644 index d537f35a7..000000000 --- a/ux/src/stores/common.js +++ /dev/null @@ -1,56 +0,0 @@ -import { defineStore } from 'pinia' -import gql from 'graphql-tag' -import { difference } from 'lodash-es' - -export const useCommonStore = defineStore('common', { - state: () => ({ - routerLoading: false, - locale: localStorage.getItem('locale') || 'en', - desiredLocale: localStorage.getItem('locale'), - blocksLoaded: [] - }), - getters: {}, - actions: { - async fetchLocaleStrings (locale) { - try { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query fetchLocaleStrings ( - $locale: String! - ) { - localeStrings ( - locale: $locale - ) - } - `, - fetchPolicy: 'cache-first', - variables: { - locale - } - }) - return resp?.data?.localeStrings - } catch (err) { - console.warn(err) - throw err - } - }, - setLocale (locale) { - this.$patch({ - locale, - desiredLocale: locale - }) - localStorage.setItem('locale', locale) - }, - async loadBlocks (blocks = []) { - const toLoad = difference(blocks, this.blocksLoaded) - for (const block of toLoad) { - try { - await import(/* @vite-ignore */ `/_blocks/${block}.js`) - this.blocksLoaded.push(block) - } catch (err) { - console.warn(`Failed to load ${block}: ${err.message}`) - } - } - } - } -}) diff --git a/ux/src/stores/editor.js b/ux/src/stores/editor.js deleted file mode 100644 index 7374a0ea5..000000000 --- a/ux/src/stores/editor.js +++ /dev/null @@ -1,120 +0,0 @@ -import { defineStore } from 'pinia' -import gql from 'graphql-tag' -import { clone } from 'lodash-es' -import { v4 as uuid } from 'uuid' - -import { useSiteStore } from './site' - -const imgMimeExt = { - 'image/jpeg': 'jpg', - 'image/gif': 'gif', - 'image/png': 'png', - 'image/webp': 'webp', - 'image/svg+xml': 'svg', - 'image/tiff': 'tif' -} - -export const useEditorStore = defineStore('editor', { - state: () => ({ - isActive: false, - editor: '', - originPageId: '', - mode: 'edit', - activeModal: '', - activeModalData: null, - hideSideNav: false, - media: { - folderTree: [], - currentFolderId: 0, - currentFileId: null - }, - checkoutDateActive: '', - lastSaveTimestamp: null, - lastChangeTimestamp: null, - editors: {}, - configIsLoaded: false, - reasonForChange: '', - ignoreRouteChange: false, - pendingAssets: [] - }), - getters: { - hasPendingChanges: (state) => { - return state.lastSaveTimestamp && state.lastSaveTimestamp !== state.lastChangeTimestamp - } - }, - actions: { - addPendingAsset (data) { - const blobUrl = URL.createObjectURL(data) - if (data instanceof File) { - this.pendingAssets.push({ - id: uuid(), - kind: 'file', - file: data, - fileName: data.name, - blobUrl - }) - } else { - const fileId = uuid() - const fileName = `${fileId}.${imgMimeExt[data.type] || 'dat'}` - this.pendingAssets.push({ - id: fileId, - kind: 'blob', - file: new File(data, fileName, { type: data.type }), - fileName, - blobUrl - }) - } - return blobUrl - }, - async fetchConfigs () { - const siteStore = useSiteStore() - try { - if (!siteStore.id) { - throw new Error('Cannot fetch editors config: Missing Site ID') - } - const resp = await APOLLO_CLIENT.query({ - query: gql` - query fetchEditorConfigs ( - $id: UUID! - ) { - siteById( - id: $id - ) { - id - editors { - asciidoc { - isActive - config - } - markdown { - isActive - config - } - wysiwyg { - isActive - config - } - } - } - } - `, - variables: { - id: siteStore.id - }, - fetchPolicy: 'network-only' - }) - this.$patch({ - editors: { - asciidoc: resp?.data?.siteById?.editors?.asciidoc?.config, - markdown: resp?.data?.siteById?.editors?.markdown?.config, - wysiwyg: resp?.data?.siteById?.editors?.wysiwyg?.config - }, - configIsLoaded: true - }) - } catch (err) { - console.warn(err) - throw err - } - } - } -}) diff --git a/ux/src/stores/flags.js b/ux/src/stores/flags.js deleted file mode 100644 index d7414558f..000000000 --- a/ux/src/stores/flags.js +++ /dev/null @@ -1,36 +0,0 @@ -import { defineStore } from 'pinia' -import gql from 'graphql-tag' - -export const useFlagsStore = defineStore('flags', { - state: () => ({ - loaded: false, - experimental: false - }), - getters: {}, - actions: { - async load () { - try { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query getFlag { - systemFlags - } - `, - fetchPolicy: 'network-only' - }) - const systemFlags = resp.data.systemFlags - if (systemFlags) { - this.$patch({ - ...systemFlags, - loaded: true - }) - } else { - throw new Error('Could not fetch system flags.') - } - } catch (err) { - console.warn(err.networkError?.result ?? err.message) - throw err - } - } - } -}) diff --git a/ux/src/stores/index.js b/ux/src/stores/index.js deleted file mode 100644 index e44b46d19..000000000 --- a/ux/src/stores/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import { createPinia } from 'pinia' -import { markRaw } from 'vue' - -export function initializeStore (router) { - const pinia = createPinia() - - // You can add Pinia plugins here - // pinia.use(SomePiniaPlugin) - - pinia.use(({ store }) => { - store.router = markRaw(router) - }) - - return pinia -} diff --git a/ux/src/stores/page.js b/ux/src/stores/page.js deleted file mode 100644 index 83e93a2e3..000000000 --- a/ux/src/stores/page.js +++ /dev/null @@ -1,670 +0,0 @@ -import { defineStore } from 'pinia' -import gql from 'graphql-tag' -import { cloneDeep, dropRight, initial, last, pick, transform } from 'lodash-es' -import { DateTime } from 'luxon' - -import { useSiteStore } from './site' -import { useEditorStore } from './editor' - -const pagePropsFragment = gql` - fragment PageRead on Page { - alias - allowComments - allowContributions - allowRatings - contentType - createdAt - description - editor - icon - id - isBrowsable - isSearchable - locale - navigationId - navigationMode - password - path - publishEndDate - publishStartDate - publishState - relations { - id - position - label - caption - icon - target - } - render - scriptJsLoad - scriptJsUnload - scriptCss - showSidebar - showTags - showToc - tags - title - toc - tocDepth { - min - max - } - updatedAt - } -` -const gqlQueries = { - pageById: gql` - query loadPage ( - $id: UUID! - ) { - pageById( - id: $id - ) { - ...PageRead - } - } - ${pagePropsFragment} - `, - pageByPath: gql` - query loadPage ( - $siteId: UUID! - $path: String! - ) { - pageByPath( - siteId: $siteId - path: $path - ) { - ...PageRead - } - } - ${pagePropsFragment} - `, - pageByIdWithContent: gql` - query loadPageWithContent ( - $id: UUID! - ) { - pageById( - id: $id - ) { - ...PageRead, - content - } - } - ${pagePropsFragment} - `, - pageByPathWithContent: gql` - query loadPageWithContent ( - $siteId: UUID! - $path: String! - ) { - pageByPath( - siteId: $siteId - path: $path - ) { - ...PageRead, - content - } - } - ${pagePropsFragment} - ` -} - -const gqlMutations = { - createPage: gql` - mutation createPage ( - $alias: String - $allowComments: Boolean - $allowContributions: Boolean - $allowRatings: Boolean - $content: String! - $description: String! - $editor: String! - $icon: String - $isBrowsable: Boolean - $isSearchable: Boolean - $locale: String! - $path: String! - $publishState: PagePublishState! - $publishEndDate: Date - $publishStartDate: Date - $relations: [PageRelationInput!] - $scriptCss: String - $scriptJsLoad: String - $scriptJsUnload: String - $showSidebar: Boolean - $showTags: Boolean - $showToc: Boolean - $siteId: UUID! - $tags: [String!] - $title: String! - $tocDepth: PageTocDepthInput - ) { - createPage ( - alias: $alias - allowComments: $allowComments - allowContributions: $allowContributions - allowRatings: $allowRatings - content: $content - description: $description - editor: $editor - icon: $icon - isBrowsable: $isBrowsable - isSearchable: $isSearchable - locale: $locale - path: $path - publishState: $publishState - publishEndDate: $publishEndDate - publishStartDate: $publishStartDate - relations: $relations - scriptCss: $scriptCss - scriptJsLoad: $scriptJsLoad - scriptJsUnload: $scriptJsUnload - showSidebar: $showSidebar - showTags: $showTags - showToc: $showToc - siteId: $siteId - tags: $tags - title: $title - tocDepth: $tocDepth - ) { - operation { - succeeded - message - } - page { - ...PageRead - } - } - } - ${pagePropsFragment} - ` -} - -export const usePageStore = defineStore('page', { - state: () => ({ - alias: '', - allowComments: false, - allowContributions: true, - allowRatings: true, - authorId: 0, - authorName: '', - commentsCount: 0, - content: '', - createdAt: '', - description: '', - editor: '', - icon: 'las la-file-alt', - id: '', - isBrowsable: true, - isSearchable: true, - locale: 'en', - navigationId: null, - navigationMode: 'inherit', - password: '', - path: '', - publishEndDate: '', - publishStartDate: '', - publishState: '', - relations: [], - render: '', - scriptJsLoad: '', - scriptJsUnload: '', - scriptCss: '', - showSidebar: true, - showTags: true, - showToc: true, - tags: [], - title: '', - toc: [], - tocDepth: { - min: 1, - max: 2 - }, - updatedAt: '' - }), - getters: { - breadcrumbs: (state) => { - const siteStore = useSiteStore() - const pathPrefix = siteStore.useLocales ? `/${state.locale}` : '' - return transform(state.path.split('/'), (result, value, key) => { - result.push({ - id: key, - title: value, - icon: 'las la-file-alt', - locale: 'en', - path: (last(result)?.path || pathPrefix) + `/${value}` - }) - }, []) - }, - folderPath: (state) => { - return initial(state.path.split('/')).join('/') - }, - isHome: (state) => { - return ['', 'home'].includes(state.path) - } - }, - actions: { - /** - * PAGE - LOAD - */ - async pageLoad ({ path, id, withContent = false }) { - const editorStore = useEditorStore() - const siteStore = useSiteStore() - try { - let query - if (withContent) { - query = id ? gqlQueries.pageByIdWithContent : gqlQueries.pageByPathWithContent - } else { - query = id ? gqlQueries.pageById : gqlQueries.pageByPath - } - const resp = await APOLLO_CLIENT.query({ - query, - variables: id ? { id } : { siteId: siteStore.id, path }, - fetchPolicy: 'network-only' - }) - const pageData = cloneDeep((id ? resp?.data?.pageById : resp?.data?.pageByPath) ?? {}) - if (!pageData?.id) { - throw new Error('ERR_PAGE_NOT_FOUND') - } - // Update page store - this.$patch({ - ...pageData, - relations: pageData.relations.map(r => pick(r, ['id', 'position', 'label', 'caption', 'icon', 'target'])), - tocDepth: pick(pageData.tocDepth, ['min', 'max']) - }) - // Update editor state timestamps - const curDate = DateTime.utc() - editorStore.$patch({ - lastChangeTimestamp: curDate, - lastSaveTimestamp: curDate - }) - } catch (err) { - console.warn(err) - throw err - } - }, - /** - * PAGE - GET PATH FROM ALIAS - */ - async pageAlias (alias) { - const siteStore = useSiteStore() - try { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query fetchPathFromAlias ( - $siteId: UUID! - $alias: String! - ) { - pathFromAlias ( - siteId: $siteId - alias: $alias - ) { - id - path - } - } - `, - variables: { siteId: siteStore.id, alias }, - fetchPolicy: 'cache-first' - }) - const pagePath = cloneDeep(resp?.data?.pathFromAlias) - if (!pagePath?.id) { - throw new Error('ERR_PAGE_NOT_FOUND') - } - return pagePath.path - } catch (err) { - console.warn(err) - throw err - } - }, - /** - * PAGE - CREATE - */ - async pageCreate ({ editor, locale, path, basePath, title = '', description = '', content = '', fromNavigate = false } = {}) { - const editorStore = useEditorStore() - - // -> Load editor config - if (!editorStore.configIsLoaded) { - await editorStore.fetchConfigs() - } - - // -> Path normalization - if (path?.startsWith('/')) { - path = path.substring(1) - } - if (basePath?.startsWith('/')) { - basePath = basePath.substring(1) - } - if (basePath?.endsWith('/')) { - basePath = basePath.substring(0, basePath.length - 1) - } - - // -> Redirect if not at /_create path - if (!this.router.currentRoute.value.path.startsWith('/_create/') && !fromNavigate) { - editorStore.$patch({ ignoreRouteChange: true }) - this.router.push(`/_create/${editor}`) - } - - // -> Init editor - editorStore.$patch({ - originPageId: editorStore.isActive ? editorStore.originPageId : this.id, // Don't replace if already in edit mode - isActive: true, - mode: 'create', - editor - }) - - // -> Default Page Path - let newPath = path - if (!path && path !== '') { - const parentPath = basePath || basePath === '' ? basePath : dropRight(this.path.split('/'), 1).join('/') - newPath = parentPath ? `${parentPath}/new-page` : 'new-page' - } - - // -> Set Default Page Data - this.$patch({ - id: 0, - locale: locale || this.locale, - path: newPath, - title: title ?? '', - description: description ?? '', - icon: 'las la-file-alt', - alias: '', - publishState: 'published', - relations: [], - tags: [], - content: content ?? '', - render: '', - isBrowsable: true, - isSearchable: true, - mode: 'edit' - }) - }, - /** - * PAGE - DUPLICATE - */ - async pageDuplicate ({ sourecePageId, title, path }) { - try { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query loadPageSource ( - $id: UUID! - ) { - pageById( - id: $id - ) { - id - content - contentType - description - editor - } - } - `, - variables: { - id: sourecePageId ?? pageStore.id - }, - fetchPolicy: 'network-only' - }) - const pageData = cloneDeep(resp?.data?.pageById ?? {}) - if (!pageData?.id) { - throw new Error('ERR_PAGE_NOT_FOUND') - } - this.pageCreate({ - editor: pageData.editor, - title, - path, - content: pageData.content, - description: pageData.description - }) - } catch (err) { - console.warn(err) - throw err - } - }, - /** - * PAGE - EDIT - */ - async pageEdit ({ path, id, fromNavigate = false } = {}) { - const editorStore = useEditorStore() - - const loadArgs = { - withContent: true - } - - if (id) { - loadArgs.id = id - } else if (path) { - loadArgs.path = path - } else { - loadArgs.id = this.id - } - - await this.pageLoad(loadArgs) - - if (!editorStore.configIsLoaded) { - await editorStore.fetchConfigs() - } - - editorStore.$patch({ - isActive: true, - mode: 'edit', - editor: this.editor - }) - }, - /** - * PAGE - MOVE - */ - async pageMove ({ id, title, path } = {}) { - const resp = await APOLLO_CLIENT.mutate({ - mutation: gql` - mutation movePage ( - $id: UUID! - $destinationLocale: String! - $destinationPath: String! - $title: String - ) { - movePage ( - id: $id - destinationLocale: $destinationLocale - destinationPath: $destinationPath - title: $title - ) { - operation { - succeeded - message - } - } - } - `, - variables: { - id, - destinationLocale: this.locale, - destinationPath: path, - title - } - }) - const result = resp?.data?.movePage?.operation ?? {} - if (!result.succeeded) { - throw new Error(result.message) - } else { - this.router.replace(`/${path}`) - } - }, - /** - * PAGE - Rename - */ - async pageRename ({ id, title } = {}) { - const resp = await APOLLO_CLIENT.mutate({ - mutation: gql` - mutation renamePage ( - $id: UUID! - $patch: PageUpdateInput! - ) { - updatePage ( - id: $id - patch: $patch - ) { - operation { - succeeded - message - } - } - } - `, - variables: { - id: id, - patch: { - title - } - } - }) - const result = resp?.data?.updatePage?.operation ?? {} - if (!result.succeeded) { - throw new Error(result.message) - } - - // Update page store - if (id === this.id) { - this.$patch({ title }) - } - }, - /** - * PAGE SAVE - */ - async pageSave () { - const editorStore = useEditorStore() - const siteStore = useSiteStore() - try { - if (editorStore.mode === 'create') { - const resp = await APOLLO_CLIENT.mutate({ - mutation: gqlMutations.createPage, - variables: { - ...pick(this, [ - 'alias', - 'allowComments', - 'allowContributions', - 'allowRatings', - 'content', - 'description', - 'icon', - 'isBrowsable', - 'isSearchable', - 'locale', - 'password', - 'path', - 'publishEndDate', - 'publishStartDate', - 'publishState', - 'relations', - 'scriptJsLoad', - 'scriptJsUnload', - 'scriptCss', - 'showSidebar', - 'showTags', - 'showToc', - 'tags', - 'title', - 'tocDepth' - ]), - editor: editorStore.editor, - siteId: siteStore.id - } - }) - const result = resp?.data?.createPage?.operation ?? {} - if (!result.succeeded) { - throw new Error(result.message) - } - const pageData = cloneDeep(resp.data.createPage.page ?? {}) - if (!pageData?.id) { - throw new Error('ERR_CREATED_PAGE_NOT_FOUND') - } - // Update page store - this.$patch({ - ...pageData, - relations: pageData.relations.map(r => pick(r, ['id', 'position', 'label', 'caption', 'icon', 'target'])), - tocDepth: pick(pageData.tocDepth, ['min', 'max']) - }) - - editorStore.$patch({ - mode: 'edit' - }) - - this.router.replace(`/${this.path}`) - } else { - const resp = await APOLLO_CLIENT.mutate({ - mutation: gql` - mutation savePage ( - $id: UUID! - $patch: PageUpdateInput! - ) { - updatePage ( - id: $id - patch: $patch - ) { - operation { - succeeded - message - } - } - } - `, - variables: { - id: this.id, - patch: { - ...pick(this, [ - 'alias', - 'allowComments', - 'allowContributions', - 'allowRatings', - 'content', - 'description', - 'icon', - 'isBrowsable', - 'isSearchable', - 'password', - 'publishEndDate', - 'publishStartDate', - 'publishState', - 'relations', - 'scriptJsLoad', - 'scriptJsUnload', - 'scriptCss', - 'showSidebar', - 'showTags', - 'showToc', - 'tags', - 'title', - 'tocDepth' - ]), - reasonForChange: editorStore.reasonForChange - } - } - }) - const result = resp?.data?.updatePage?.operation ?? {} - if (!result.succeeded) { - throw new Error(result.message) - } - } - // Update editor state timestamps - const curDate = DateTime.utc() - editorStore.$patch({ - lastChangeTimestamp: curDate, - lastSaveTimestamp: curDate, - reasonForChange: '' - }) - } catch (err) { - console.warn(err) - throw err - } - }, - async cancelPageEdit () { - const editorStore = useEditorStore() - await this.pageLoad({ id: editorStore.originPageId ? editorStore.originPageId : this.id }) - this.router.replace(`/${this.path}`) - }, - generateToc () { - - } - } -}) diff --git a/ux/src/stores/site.js b/ux/src/stores/site.js deleted file mode 100644 index 7880fc26b..000000000 --- a/ux/src/stores/site.js +++ /dev/null @@ -1,283 +0,0 @@ -import { defineStore } from 'pinia' -import gql from 'graphql-tag' -import { clone, sortBy } from 'lodash-es' - -import { useUserStore } from './user' - -export const useSiteStore = defineStore('site', { - state: () => ({ - id: null, - hostname: '', - company: '', - contentLicense: '', - footerExtra: '', - dark: false, - title: '', - description: '', - logoText: true, - search: '', - searchLastQuery: '', - searchIsLoading: false, - printView: false, - pageDataTemplates: [], - showSideNav: true, - showSidebar: true, - overlay: null, - overlayOpts: {}, - features: { - profile: false, - ratingsMode: 'off', - reasonForChange: 'required', - search: false - }, - editors: { - asciidoc: false, - markdown: false, - wysiwyg: false - }, - locales: { - primary: 'en', - active: [{ - code: 'en', - language: 'en', - name: 'English', - nativeName: 'English' - }] - }, - tags: [], - tagsLoaded: false, - theme: { - dark: false, - injectCSS: '', - injectHead: '', - injectBody: '', - colorPrimary: '#1976D2', - colorSecondary: '#02C39A', - colorAccent: '#f03a47', - colorHeader: '#000', - colorSidebar: '#1976D2', - codeBlocksTheme: '', - sidebarPosition: 'left', - tocPosition: 'right', - showSharingMenu: true, - showPrintBtn: true - }, - sideDialogShown: false, - sideDialogComponent: '', - docsBase: 'https://beta.js.wiki/docs', - nav: { - currentId: null, - items: [] - } - }), - getters: { - overlayIsShown: (state) => Boolean(state.overlay), - sideNavIsDisabled: (state) => Boolean(state.theme.sidebarPosition === 'off'), - scrollStyle: (state) => { - const userStore = useUserStore() - let isDark = false - if (userStore.appearance === 'site') { - isDark = state.theme.dark - } else if (userStore.appearance === 'dark') { - isDark = true - } - return { - thumb: { - right: '2px', - borderRadius: '5px', - backgroundColor: isDark ? '#FFF' : '#000', - width: '5px', - opacity: isDark ? 0.25 : 0.15 - }, - bar: { - backgroundColor: isDark ? '#000' : '#FAFAFA', - width: '9px', - opacity: isDark ? 0.25 : 1 - } - } - }, - useLocales: (state) => { - return state.locales?.active?.length > 1 - } - }, - actions: { - openFileManager (opts) { - this.$patch({ - overlay: 'FileManager', - overlayOpts: { - insertMode: opts?.insertMode ?? false - } - }) - }, - async loadSite (hostname) { - try { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query getSiteInfo ($hostname: String!) { - siteByHostname ( - hostname: $hostname - exact: false - ) { - company - contentLicense - description - editors { - asciidoc { - isActive - } - markdown { - isActive - } - wysiwyg { - isActive - } - } - features { - browse - profile - ratingsMode - reasonForChange - search - } - footerExtra - hostname - id - locales { - primary - active { - code - language - name - nativeName - } - } - logoText - theme { - dark - colorPrimary - colorSecondary - colorAccent - colorHeader - colorSidebar - codeBlocksTheme - sidebarPosition - tocPosition - showSharingMenu - showPrintBtn - baseFont - contentFont - } - title - } - } - `, - variables: { - hostname - } - }) - const siteInfo = resp.data.siteByHostname - if (siteInfo) { - this.$patch({ - id: clone(siteInfo.id), - hostname: clone(siteInfo.hostname), - title: clone(siteInfo.title), - description: clone(siteInfo.description), - logoText: clone(siteInfo.logoText), - company: clone(siteInfo.company), - contentLicense: clone(siteInfo.contentLicense), - footerExtra: clone(siteInfo.footerExtra), - features: { - ...this.features, - ...clone(siteInfo.features) - }, - editors: { - asciidoc: clone(siteInfo.editors.asciidoc.isActive), - markdown: clone(siteInfo.editors.markdown.isActive), - wysiwyg: clone(siteInfo.editors.wysiwyg.isActive) - }, - locales: { - primary: clone(siteInfo.locales.primary), - active: sortBy(clone(siteInfo.locales.active), ['nativeName', 'name']) - }, - tags: [], - tagsLoaded: false, - theme: { - ...this.theme, - ...clone(siteInfo.theme) - } - }) - } else { - throw new Error('Invalid Site') - } - } catch (err) { - console.warn(err.networkError?.result ?? err.message) - throw err - } - }, - async fetchTags (forceRefresh = false) { - if (this.tagsLoaded && !forceRefresh) { return } - try { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query getSiteTags ($siteId: UUID!) { - tags ( - siteId: $siteId - ) { - tag - usageCount - } - } - `, - variables: { - siteId: this.id - } - }) - this.$patch({ - tags: resp.data.tags ?? [], - tagsLoaded: true - }) - } catch (err) { - console.warn(err.networkError?.result ?? err.message) - throw err - } - }, - async fetchNavigation (id) { - try { - const resp = await APOLLO_CLIENT.query({ - query: gql` - query getNavigationItems ($id: UUID!) { - navigationById ( - id: $id - ) { - id - type - label - icon - target - openInNewWindow - children { - id - type - label - icon - target - openInNewWindow - } - } - } - `, - variables: { id } - }) - this.$patch({ - nav: { - currentId: id, - items: resp?.data?.navigationById ?? [] - } - }) - } catch (err) { - console.warn(err.networkError?.result ?? err.message) - throw err - } - } - } -}) diff --git a/ux/src/stores/store-flag.d.ts b/ux/src/stores/store-flag.d.ts deleted file mode 100644 index 7677175b0..000000000 --- a/ux/src/stores/store-flag.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable */ -// THIS FEATURE-FLAG FILE IS AUTOGENERATED, -// REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING -import "quasar/dist/types/feature-flag"; - -declare module "quasar/dist/types/feature-flag" { - interface QuasarFeatureFlags { - store: true; - } -} diff --git a/ux/src/stores/user.js b/ux/src/stores/user.js deleted file mode 100644 index 265c3eb67..000000000 --- a/ux/src/stores/user.js +++ /dev/null @@ -1,214 +0,0 @@ -import { defineStore } from 'pinia' -import { jwtDecode } from 'jwt-decode' -import Cookies from 'js-cookie' -import gql from 'graphql-tag' -import { DateTime } from 'luxon' -import { getAccessibleColor } from '@/helpers/accessibility' - -import { useSiteStore } from './site' - -export const useUserStore = defineStore('user', { - state: () => ({ - id: '10000000-0000-4000-8000-000000000001', - email: '', - name: '', - hasAvatar: false, - localeCode: '', - timezone: '', - dateFormat: 'YYYY-MM-DD', - timeFormat: '12h', - appearance: 'site', - cvd: 'none', - permissions: [], - pagePermissions: [], - iat: 0, - exp: null, - authenticated: false, - token: Cookies.get('jwt'), - profileLoaded: false - }), - getters: { - preferredDateFormat: (state) => { - if (!state.dateFormat) { - return 'D' - } else { - return state.dateFormat.replaceAll('Y', 'y').replaceAll('D', 'd') - } - }, - preferredTimeFormat: (state) => { - return state.timeFormat === '24h' ? 'T' : 't' - } - }, - actions: { - isTokenValid (offset) { - return this.exp && this.exp > (offset ? DateTime.now().plus(offset) : DateTime.now()) - }, - loadToken () { - if (!this.token) { return } - try { - const jwtData = jwtDecode(this.token) - this.id = jwtData.id - this.email = jwtData.email - this.iat = jwtData.iat - this.exp = DateTime.fromSeconds(jwtData.exp, { zone: 'utc' }) - if (this.exp > DateTime.utc()) { - this.authenticated = true - } else { - console.info('Token has expired and will be refreshed on next query.') - } - } catch (err) { - console.warn('Failed to parse JWT. Invalid or malformed.') - } - }, - async refreshToken () { - try { - const respRaw = await APOLLO_CLIENT.mutate({ - context: { - skipAuth: true - }, - mutation: gql` - mutation refreshToken ( - $token: String! - ) { - refreshToken(token: $token) { - operation { - succeeded - message - } - jwt - } - } - `, - variables: { - token: this.token - } - }) - const resp = respRaw?.data?.refreshToken ?? {} - if (!resp.operation?.succeeded) { - throw new Error(resp.operation?.message || 'Failed to refresh token.') - } - Cookies.set('jwt', resp.jwt, { expires: 365, path: '/', sameSite: 'Lax' }) - this.token = resp.jwt - this.loadToken() - return true - } catch (err) { - console.warn(err) - return false - } - }, - async refreshProfile () { - if (!this.authenticated || !this.id) { - return - } - try { - const respRaw = await APOLLO_CLIENT.query({ - query: gql` - query refreshProfile ( - $id: UUID! - ) { - userById(id: $id) { - id - name - email - hasAvatar - meta - prefs - lastLoginAt - groups { - id - name - } - } - userPermissions - } - `, - variables: { - id: this.id - } - }) - const resp = respRaw?.data?.userById - if (!resp || resp.id !== this.id) { - throw new Error('Failed to fetch user profile!') - } - this.name = resp.name || 'Unknown User' - this.email = resp.email - this.hasAvatar = resp.hasAvatar ?? false - this.location = resp.meta.location || '' - this.jobTitle = resp.meta.jobTitle || '' - this.pronouns = resp.meta.pronouns || '' - this.timezone = resp.prefs.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone || '' - this.dateFormat = resp.prefs.dateFormat || '' - this.timeFormat = resp.prefs.timeFormat || '12h' - this.appearance = resp.prefs.appearance || 'site' - this.cvd = resp.prefs.cvd || 'none' - this.permissions = respRaw.data.userPermissions || [] - this.profileLoaded = true - } catch (err) { - console.warn(err) - } - }, - logout () { - Cookies.remove('jwt', { path: '/' }) - this.$patch({ - id: '10000000-0000-4000-8000-000000000001', - email: '', - name: '', - hasAvatar: false, - localeCode: '', - timezone: '', - dateFormat: 'YYYY-MM-DD', - timeFormat: '12h', - appearance: 'site', - cvd: 'none', - permissions: [], - iat: 0, - exp: null, - authenticated: false, - token: '', - profileLoaded: false - }) - EVENT_BUS.emit('logout') - }, - getAccessibleColor (base, hexBase) { - return getAccessibleColor(base, hexBase, this.cvd) - }, - can (permission) { - if (this.permissions.includes('manage:system') || this.permissions.includes(permission) || this.pagePermissions.includes(permission)) { - return true - } - return false - }, - async fetchPagePermissions (path) { - if (path.startsWith('/_')) { - this.pagePermissions = [] - return - } - const siteStore = useSiteStore() - try { - const respRaw = await APOLLO_CLIENT.query({ - query: gql` - query fetchPagePermissions ( - $siteId: UUID! - $path: String! - ) { - userPermissionsAtPath( - siteId: $siteId - path: $path - ) - } - `, - variables: { - siteId: siteStore.id, - path - } - }) - this.pagePermissions = respRaw?.data?.userPermissionsAtPath || [] - } catch (err) { - console.warn(`Failed to fetch page permissions at path ${path}!`) - } - }, - formatDateTime (t, date) { - return (typeof date === 'string' ? DateTime.fromISO(date) : date).toFormat(t('common.datetime', { date: this.preferredDateFormat, time: this.preferredTimeFormat })) - } - } -}) diff --git a/ux/vite.config.js b/ux/vite.config.js deleted file mode 100644 index 51ab84cbd..000000000 --- a/ux/vite.config.js +++ /dev/null @@ -1,86 +0,0 @@ -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import yaml from 'js-yaml' -import fs from 'node:fs' -import { fileURLToPath } from 'node:url' -import { quasar, transformAssetUrls } from '@quasar/vite-plugin' -import vueDevTools from 'vite-plugin-vue-devtools' - -// https://vitejs.dev/config/ -export default defineConfig(({ mode }) => { - const userConfig = mode === 'development' ? { - dev: { port: 3001, hmrClientPort: 3001 }, - ...yaml.load(fs.readFileSync(fileURLToPath(new URL('../config.yml', import.meta.url)), 'utf8')) - } : {} - - return { - build: { - assetsDir: '_assets', - chunkSizeWarningLimit: 5000, - dynamicImportVarsOptions: { - warnOnError: true, - include: ['!/_blocks/**'] - }, - outDir: '../assets', - target: 'es2022', - ...(mode === 'production') && { - rollupOptions: { - output: { - manualChunks (id) { - if (id.includes('lodash')) { - return 'lodash' - // } else if (id.includes('quasar')) { - // return 'quasar' - } else if (id.includes('pages/Admin')) { - return 'admin' - } else if (id.includes('pages/Profile')) { - return 'profile' - } - } - } - } - } - }, - optimizeDeps: { - include: [ - 'prosemirror-state', - 'prosemirror-transform', - 'prosemirror-model', - 'prosemirror-view' - ] - }, - plugins: [ - vue({ - template: { transformAssetUrls } - }), - quasar({ - autoImportComponentCase: 'kebab', - sassVariables: '@/css/_theme.scss' - }), - vueDevTools() - ], - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) - } - }, - server: { - // https: true - open: false, // opens browser window automatically - allowedHosts: true, - port: userConfig.dev?.port, - proxy: ['_graphql', '_blocks', '_site', '_thumb', '_user'].reduce((result, key) => { - result[`/${key}`] = { - target: { - host: '127.0.0.1', - port: userConfig.port - } - } - return result - }, {}), - hmr: { - clientPort: userConfig.dev?.hmrClientPort - } - } - } -})