From 6438660b0369b65304d5a482bd2962b487fc06dc Mon Sep 17 00:00:00 2001 From: Rene Kievits Date: Thu, 18 Dec 2025 01:30:52 +0100 Subject: [PATCH] init --- .gitignore | 34 + README.md | 0 client/.env.android | 2 + client/.gitignore | 2 + client/Dockerfile | 17 + client/capacitor.config.js | 30 + client/eslint.config.js | 69 + client/index.html | 16 + client/package-lock.json | 6658 +++++++++++++++++ client/package.json | 47 + client/src/App.vue | 348 + client/src/assets/android-chrome-192x192.png | Bin 0 -> 22942 bytes client/src/assets/android-chrome-512x512.png | Bin 0 -> 60005 bytes client/src/assets/apple-touch-icon.png | Bin 0 -> 20385 bytes client/src/assets/favicon-16x16.png | Bin 0 -> 771 bytes client/src/assets/favicon-32x32.png | Bin 0 -> 1988 bytes client/src/assets/favicon.ico | Bin 0 -> 15406 bytes client/src/assets/icon.svg | 18 + .../components/dashboard/WidgetAccuracy.vue | 38 + .../dashboard/WidgetDistribution.vue | 73 + .../components/dashboard/WidgetForecast.vue | 41 + .../src/components/dashboard/WidgetGhosts.vue | 32 + .../dashboard/WidgetGuruMastery.vue | 45 + .../components/dashboard/WidgetHeatmap.vue | 89 + .../src/components/dashboard/WidgetStreak.vue | 59 + .../components/dashboard/WidgetWelcome.vue | 76 + client/src/components/kanji/KanjiCanvas.vue | 247 + .../src/components/kanji/KanjiSvgViewer.vue | 138 + client/src/main.js | 49 + client/src/plugins/i18n.js | 306 + client/src/stores/appStore.js | 136 + client/src/styles/abstracts/_mixins.scss | 68 + client/src/styles/abstracts/_variables.scss | 5 + .../styles/abstracts/variables/_colors.scss | 18 + .../styles/abstracts/variables/_effects.scss | 30 + .../styles/abstracts/variables/_layout.scss | 46 + .../styles/abstracts/variables/_spacing.scss | 10 + .../abstracts/variables/_typography.scss | 25 + client/src/styles/base/_typography.scss | 23 + client/src/styles/components/_buttons.scss | 26 + client/src/styles/components/_kanji.scss | 147 + client/src/styles/components/_widgets.scss | 174 + client/src/styles/main.scss | 10 + client/src/styles/pages/_app.scss | 61 + client/src/styles/pages/_collection.scss | 128 + client/src/styles/pages/_dashboard.scss | 34 + client/src/styles/pages/_review.scss | 47 + client/src/views/Collection.vue | 181 + client/src/views/Dashboard.vue | 81 + client/src/views/Review.vue | 238 + client/stylelint.config.js | 17 + client/vite.config.js | 19 + docker-compose.yml | 51 + server/Dockerfile | 13 + server/package-lock.json | 2851 +++++++ server/package.json | 25 + server/server.js | 73 + server/src/config/constants.js | 4 + server/src/config/db.js | 12 + server/src/controllers/auth.controller.js | 28 + .../src/controllers/collection.controller.js | 33 + server/src/controllers/review.controller.js | 11 + server/src/controllers/sync.controller.js | 10 + server/src/models/ReviewLog.js | 10 + server/src/models/StudyItem.js | 21 + server/src/models/User.js | 21 + server/src/routes/v1.js | 22 + server/src/services/auth.service.js | 29 + server/src/services/review.service.js | 85 + server/src/services/stats.service.js | 112 + server/src/services/sync.service.js | 78 + server/src/utils/dateUtils.js | 32 + server/tests/services/auth.service.test.js | 52 + server/tests/services/controllers.test.js | 142 + server/tests/services/review.service.test.js | 144 + server/tests/services/stats.service.test.js | 147 + server/tests/services/sync.service.test.js | 212 + server/tests/utils.test.js | 54 + 78 files changed, 14230 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 client/.env.android create mode 100644 client/.gitignore create mode 100644 client/Dockerfile create mode 100644 client/capacitor.config.js create mode 100644 client/eslint.config.js create mode 100644 client/index.html create mode 100644 client/package-lock.json create mode 100644 client/package.json create mode 100644 client/src/App.vue create mode 100644 client/src/assets/android-chrome-192x192.png create mode 100644 client/src/assets/android-chrome-512x512.png create mode 100644 client/src/assets/apple-touch-icon.png create mode 100644 client/src/assets/favicon-16x16.png create mode 100644 client/src/assets/favicon-32x32.png create mode 100644 client/src/assets/favicon.ico create mode 100644 client/src/assets/icon.svg create mode 100644 client/src/components/dashboard/WidgetAccuracy.vue create mode 100644 client/src/components/dashboard/WidgetDistribution.vue create mode 100644 client/src/components/dashboard/WidgetForecast.vue create mode 100644 client/src/components/dashboard/WidgetGhosts.vue create mode 100644 client/src/components/dashboard/WidgetGuruMastery.vue create mode 100644 client/src/components/dashboard/WidgetHeatmap.vue create mode 100644 client/src/components/dashboard/WidgetStreak.vue create mode 100644 client/src/components/dashboard/WidgetWelcome.vue create mode 100644 client/src/components/kanji/KanjiCanvas.vue create mode 100644 client/src/components/kanji/KanjiSvgViewer.vue create mode 100644 client/src/main.js create mode 100644 client/src/plugins/i18n.js create mode 100644 client/src/stores/appStore.js create mode 100644 client/src/styles/abstracts/_mixins.scss create mode 100644 client/src/styles/abstracts/_variables.scss create mode 100644 client/src/styles/abstracts/variables/_colors.scss create mode 100644 client/src/styles/abstracts/variables/_effects.scss create mode 100644 client/src/styles/abstracts/variables/_layout.scss create mode 100644 client/src/styles/abstracts/variables/_spacing.scss create mode 100644 client/src/styles/abstracts/variables/_typography.scss create mode 100644 client/src/styles/base/_typography.scss create mode 100644 client/src/styles/components/_buttons.scss create mode 100644 client/src/styles/components/_kanji.scss create mode 100644 client/src/styles/components/_widgets.scss create mode 100644 client/src/styles/main.scss create mode 100644 client/src/styles/pages/_app.scss create mode 100644 client/src/styles/pages/_collection.scss create mode 100644 client/src/styles/pages/_dashboard.scss create mode 100644 client/src/styles/pages/_review.scss create mode 100644 client/src/views/Collection.vue create mode 100644 client/src/views/Dashboard.vue create mode 100644 client/src/views/Review.vue create mode 100644 client/stylelint.config.js create mode 100644 client/vite.config.js create mode 100644 docker-compose.yml create mode 100644 server/Dockerfile create mode 100644 server/package-lock.json create mode 100644 server/package.json create mode 100644 server/server.js create mode 100644 server/src/config/constants.js create mode 100644 server/src/config/db.js create mode 100644 server/src/controllers/auth.controller.js create mode 100644 server/src/controllers/collection.controller.js create mode 100644 server/src/controllers/review.controller.js create mode 100644 server/src/controllers/sync.controller.js create mode 100644 server/src/models/ReviewLog.js create mode 100644 server/src/models/StudyItem.js create mode 100644 server/src/models/User.js create mode 100644 server/src/routes/v1.js create mode 100644 server/src/services/auth.service.js create mode 100644 server/src/services/review.service.js create mode 100644 server/src/services/stats.service.js create mode 100644 server/src/services/sync.service.js create mode 100644 server/src/utils/dateUtils.js create mode 100644 server/tests/services/auth.service.test.js create mode 100644 server/tests/services/controllers.test.js create mode 100644 server/tests/services/review.service.test.js create mode 100644 server/tests/services/stats.service.test.js create mode 100644 server/tests/services/sync.service.test.js create mode 100644 server/tests/utils.test.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..52e9015 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +node_modules/ + +.env +.env.local +.env.*.local +zen_kanji_js/.env +zen_kanji_js/client/.env +zen_kanji_js/client/.env.android + +dist/ +dist-ssr/ +*.local + +.vscode/* +!.vscode/extensions.json +.idea/ +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +.DS_Store +Thumbs.db + +coverage/ + +zen_kanji_js/client/android/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/client/.env.android b/client/.env.android new file mode 100644 index 0000000..871871e --- /dev/null +++ b/client/.env.android @@ -0,0 +1,2 @@ +VITE_API_URL=http://10.0.2.2:3000 +CAP_ENV=dev diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..37d7e73 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,2 @@ +node_modules +.env diff --git a/client/Dockerfile b/client/Dockerfile new file mode 100644 index 0000000..a4a7cdd --- /dev/null +++ b/client/Dockerfile @@ -0,0 +1,17 @@ +FROM node:24-alpine AS dev-stage +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +EXPOSE 5173 +CMD ["npm", "run", "dev", "--", "--host"] + +FROM dev-stage AS build-stage +ARG VITE_API_URL +ENV VITE_API_URL=$VITE_API_URL +RUN npm run build + +FROM nginx:stable-alpine AS production-stage +COPY --from=build-stage /app/dist /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/client/capacitor.config.js b/client/capacitor.config.js new file mode 100644 index 0000000..3fa2da7 --- /dev/null +++ b/client/capacitor.config.js @@ -0,0 +1,30 @@ +/// +require('dotenv').config(); + +const isDev = process.env.CAP_ENV === 'dev'; + +const config = { + appId: "com.zenkanji.app", + appName: "Zen Kanji", + webDir: "dist", + server: { + androidScheme: isDev ? "http" : "https", + cleartext: isDev + }, + plugins: { + Keyboard: { + resize: "body", + style: "dark", + resizeOnFullScreen: true + }, + SplashScreen: { + launchShowDuration: 2000, + backgroundColor: "#1e1e24", + showSpinner: false + } + } +}; + +console.log(`⚡️ Capacitor Config loaded for: ${isDev ? 'DEVELOPMENT (http)' : 'PRODUCTION (https)'}`); + +module.exports = config; diff --git a/client/eslint.config.js b/client/eslint.config.js new file mode 100644 index 0000000..5931bfc --- /dev/null +++ b/client/eslint.config.js @@ -0,0 +1,69 @@ +import js from '@eslint/js'; +import globals from 'globals'; +import pluginVue from 'eslint-plugin-vue'; +import pluginVuePug from 'eslint-plugin-vue-pug'; +import pluginJsonc from 'eslint-plugin-jsonc'; + +export default [ + { + ignores: [ + '**/node_modules/**', + '**/dist/**', + '**/android/**', + '**/coverage/**', + '**/*.min.js' + ] + }, + + js.configs.recommended, + { + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.node, + ...globals.es2021 + } + }, + rules: { + 'no-unused-vars': 'warn', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' + } + }, + + ...pluginVue.configs['flat/recommended'], + { + files: ['*.vue', '**/*.vue'], + plugins: { + 'vue-pug': pluginVuePug + }, + languageOptions: { + parser: pluginVue.parser, + parserOptions: { + parser: js.configs.recommended.parser, + ecmaVersion: 'latest', + sourceType: 'module', + } + }, + rules: { + 'vue/multi-word-component-names': 'off', + 'vue/require-default-prop': 'off', + 'vue/html-indent': ['error', 2], + 'no-unused-vars': 'off', + 'vue/component-name-in-template-casing': ['error', 'PascalCase', { + registeredComponentsOnly: true, + ignores: [] + }] + } + }, + + ...pluginJsonc.configs['flat/recommended-with-jsonc'], + { + files: ['*.json', '**/*.json'], + rules: { + 'jsonc/sort-keys': 'off', + } + } +]; diff --git a/client/index.html b/client/index.html new file mode 100644 index 0000000..1f1ce09 --- /dev/null +++ b/client/index.html @@ -0,0 +1,16 @@ + + + + + + + Zen Kanji + + + + +
+ + + + diff --git a/client/package-lock.json b/client/package-lock.json new file mode 100644 index 0000000..765ed49 --- /dev/null +++ b/client/package-lock.json @@ -0,0 +1,6658 @@ +{ + "name": "zen-kanji-client", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "zen-kanji-client", + "version": "0.0.0", + "dependencies": { + "@capacitor/android": "^8.0.0", + "@capacitor/core": "^8.0.0", + "@mdi/font": "^7.3.67", + "capacitor": "^0.5.6", + "i18n": "^0.15.3", + "pinia": "^3.0.4", + "pug": "^3.0.3", + "vue": "^3.3.4", + "vue-i18n": "^11.2.2", + "vue-pug": "^1.0.2", + "vue-pug-plugin": "^2.0.4", + "vue-router": "^4.2.5", + "vuetify": "^3.4.0" + }, + "devDependencies": { + "@capacitor/cli": "^7.4.4", + "@eslint/js": "^9.39.2", + "@vitejs/plugin-vue": "^6.0.3", + "dotenv": "^17.2.3", + "eslint": "^9.39.2", + "eslint-plugin-jsonc": "^2.21.0", + "eslint-plugin-vue": "^9.33.0", + "eslint-plugin-vue-pug": "^0.6.2", + "globals": "^16.5.0", + "sass": "^1.97.0", + "stylelint": "^16.26.1", + "stylelint-config-recommended-vue": "^1.6.1", + "stylelint-config-standard-scss": "^16.0.0", + "vite": "^7.3.0", + "vue-eslint-parser": "^9.4.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cacheable/memory": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.6.tgz", + "integrity": "sha512-7e8SScMocHxcAb8YhtkbMhGG+EKLRIficb1F5sjvhSYsWTZGxvg4KIDp8kgxnV2PUJ3ddPe6J9QESjKvBWRDkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.3.2", + "@keyv/bigmap": "^1.3.0", + "hookified": "^1.13.0", + "keyv": "^5.5.4" + } + }, + "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.0.tgz", + "integrity": "sha512-KT01GjzV6AQD5+IYrcpoYLkCu1Jod3nau1Z7EsEuViO3TZGRacSbO9MfHmbJ1WaOXFtWLxPVj169cn2WNKPkIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.2.0", + "hookified": "^1.13.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.5.4" + } + }, + "node_modules/@cacheable/memory/node_modules/keyv": { + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.5.tgz", + "integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.2.tgz", + "integrity": "sha512-8kGE2P+HjfY8FglaOiW+y8qxcaQAfAhVML+i66XJR3YX5FtyDqn6Txctr3K2FrbxLKixRRYYBWMbuGciOhYNDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.2.0", + "keyv": "^5.5.4" + } + }, + "node_modules/@cacheable/utils/node_modules/keyv": { + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.5.tgz", + "integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@capacitor/android": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-8.0.0.tgz", + "integrity": "sha512-FrBSvVAC5JuLaYHNyDnwQny0/SYnP+xDQbc/KA4wInmRkMXLDv22fkx9aBJIDrxjuUVd+jsRih4SAt8FgMEzCw==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": "^8.0.0" + } + }, + "node_modules/@capacitor/cli": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-7.4.4.tgz", + "integrity": "sha512-J7ciBE7GlJ70sr2s8oz1+H4ZdNk4MGG41fsakUlDHWva5UWgFIZYMiEdDvGbYazAYTaxN3lVZpH9zil9FfZj+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/cli-framework-output": "^2.2.8", + "@ionic/utils-subprocess": "^3.0.1", + "@ionic/utils-terminal": "^2.3.5", + "commander": "^12.1.0", + "debug": "^4.4.0", + "env-paths": "^2.2.0", + "fs-extra": "^11.2.0", + "kleur": "^4.1.5", + "native-run": "^2.0.1", + "open": "^8.4.0", + "plist": "^3.1.0", + "prompts": "^2.4.2", + "rimraf": "^6.0.1", + "semver": "^7.6.3", + "tar": "^6.1.11", + "tslib": "^2.8.1", + "xml2js": "^0.6.2" + }, + "bin": { + "cap": "bin/capacitor", + "capacitor": "bin/capacitor" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@capacitor/core": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.0.0.tgz", + "integrity": "sha512-250HTVd/W/KdMygoqaedisvNbHbpbQTN2Hy/8ZYGm1nAqE0Fx7sGss4l0nDg33STxEdDhtVRoL2fIaaiukKseA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.21.tgz", + "integrity": "sha512-plP8N8zKfEZ26figX4Nvajx8DuzfuRpLTqglQ5d0chfnt35Qt3X+m6ASZ+rG0D0kxe/upDVNwSIVJP5n4FuNfw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@dual-bundle/import-meta-resolve": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz", + "integrity": "sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/JounQin" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz", + "integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz", + "integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz", + "integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz", + "integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz", + "integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz", + "integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz", + "integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz", + "integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz", + "integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz", + "integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz", + "integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz", + "integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz", + "integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz", + "integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz", + "integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz", + "integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz", + "integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz", + "integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz", + "integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz", + "integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz", + "integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz", + "integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz", + "integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz", + "integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz", + "integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz", + "integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@intlify/core-base": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.2.2.tgz", + "integrity": "sha512-0mCTBOLKIqFUP3BzwuFW23hYEl9g/wby6uY//AC5hTgQfTsM2srCYF2/hYGp+a5DZ/HIFIgKkLJMzXTt30r0JQ==", + "license": "MIT", + "dependencies": { + "@intlify/message-compiler": "11.2.2", + "@intlify/shared": "11.2.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.2.2.tgz", + "integrity": "sha512-XS2p8Ff5JxWsKhgfld4/MRQzZRQ85drMMPhb7Co6Be4ZOgqJX1DzcZt0IFgGTycgqL8rkYNwgnD443Q+TapOoA==", + "license": "MIT", + "dependencies": { + "@intlify/shared": "11.2.2", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/shared": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.2.2.tgz", + "integrity": "sha512-OtCmyFpSXxNu/oET/aN6HtPCbZ01btXVd0f3w00YsHOb13Kverk1jzA2k47pAekM55qbUw421fvPF1yxZ+gicw==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@ionic/cli-framework-output": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz", + "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-array": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.6.tgz", + "integrity": "sha512-0JZ1Zkp3wURnv8oq6Qt7fMPo5MpjbLoUoa9Bu2Q4PJuSDWM8H8gwF3dQO7VTeUj3/0o1IB1wGkFWZZYgUXZMUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-fs": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.7.tgz", + "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-fs/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ionic/utils-object": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", + "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-process": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", + "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-object": "2.1.6", + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.7.tgz", + "integrity": "sha512-eSELBE7NWNFIHTbTC2jiMvh1ABKGIpGdUIvARsNPMNQhxJB3wpwdiVnoBoTYp+5a6UUIww4Kpg7v6S7iTctH1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-subprocess": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-3.0.1.tgz", + "integrity": "sha512-cT4te3AQQPeIM9WCwIg8ohroJ8TjsYaMb2G4ZEgv9YzeDqHZ4JpeIKqG2SoaA3GmVQ3sOfhPM6Ox9sxphV/d1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-array": "2.1.6", + "@ionic/utils-fs": "3.1.7", + "@ionic/utils-process": "2.1.12", + "@ionic/utils-stream": "3.1.7", + "@ionic/utils-terminal": "2.3.5", + "cross-spawn": "^7.0.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-terminal": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz", + "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@mdi/font": { + "version": "7.4.47", + "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz", + "integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==", + "license": "Apache-2.0" + }, + "node_modules/@messageformat/core": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.4.0.tgz", + "integrity": "sha512-NgCFubFFIdMWJGN5WuQhHCNmzk7QgiVfrViFxcS99j7F5dDS5EP6raR54I+2ydhe4+5/XTn/YIEppFaqqVWHsw==", + "license": "MIT", + "dependencies": { + "@messageformat/date-skeleton": "^1.0.0", + "@messageformat/number-skeleton": "^1.0.0", + "@messageformat/parser": "^5.1.0", + "@messageformat/runtime": "^3.0.1", + "make-plural": "^7.0.0", + "safe-identifier": "^0.4.1" + } + }, + "node_modules/@messageformat/date-skeleton": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.1.0.tgz", + "integrity": "sha512-rmGAfB1tIPER+gh3p/RgA+PVeRE/gxuQ2w4snFWPF5xtb5mbWR7Cbw7wCOftcUypbD6HVoxrVdyyghPm3WzP5A==", + "license": "MIT" + }, + "node_modules/@messageformat/number-skeleton": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.2.0.tgz", + "integrity": "sha512-xsgwcL7J7WhlHJ3RNbaVgssaIwcEyFkBqxHdcdaiJzwTZAWEOD8BuUFxnxV9k5S0qHN3v/KzUpq0IUpjH1seRg==", + "license": "MIT" + }, + "node_modules/@messageformat/parser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.1.1.tgz", + "integrity": "sha512-3p0YRGCcTUCYvBKLIxtDDyrJ0YijGIwrTRu1DT8gIviIDZru8H23+FkY6MJBzM1n9n20CiM4VeDYuBsrrwnLjg==", + "license": "MIT", + "dependencies": { + "moo": "^0.5.1" + } + }, + "node_modules/@messageformat/runtime": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.2.tgz", + "integrity": "sha512-dkIPDCjXcfhSHgNE1/qV6TeczQZR59Yx0xXeafVKgK3QVWoxc38ljwpksUpnzCGvN151KUbCJTDZVmahtf1YZw==", + "license": "MIT", + "dependencies": { + "make-plural": "^7.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "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" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz", + "integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.5.tgz", + "integrity": "sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.5.tgz", + "integrity": "sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.5.tgz", + "integrity": "sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz", + "integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.5.tgz", + "integrity": "sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.5.tgz", + "integrity": "sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.5.tgz", + "integrity": "sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.5.tgz", + "integrity": "sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz", + "integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.5.tgz", + "integrity": "sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.5.tgz", + "integrity": "sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.5.tgz", + "integrity": "sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.5.tgz", + "integrity": "sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.5.tgz", + "integrity": "sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.5.tgz", + "integrity": "sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.5.tgz", + "integrity": "sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.5.tgz", + "integrity": "sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.5.tgz", + "integrity": "sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.5.tgz", + "integrity": "sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.5.tgz", + "integrity": "sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.5.tgz", + "integrity": "sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz", + "integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==", + "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/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.3.tgz", + "integrity": "sha512-TlGPkLFLVOY3T7fZrwdvKpjprR3s4fxRln0ORDo1VQ7HHyxJwTlrjKU3kpVWTlaAjIEuCTokmjkZnr8Tpc925w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-beta.53" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz", + "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.25", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz", + "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz", + "integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.25", + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz", + "integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.7.9", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz", + "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.9" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.9", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", + "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.9", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.9", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", + "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.25.tgz", + "integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.25.tgz", + "integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.25.tgz", + "integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.25", + "@vue/runtime-core": "3.5.25", + "@vue/shared": "3.5.25", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.25.tgz", + "integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25" + }, + "peerDependencies": { + "vue": "3.5.25" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz", + "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==", + "license": "MIT" + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", + "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/assert-never": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", + "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "license": "MIT" + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/birpc": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", + "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/bplist-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", + "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/cacheable": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.1.tgz", + "integrity": "sha512-yr+FSHWn1ZUou5LkULX/S+jhfgfnLbuKQjE40tyEd4fxGZVMbBL5ifno0J0OauykS8UiCSgHi+DV/YD+rjFxFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/memory": "^2.0.6", + "@cacheable/utils": "^2.3.2", + "hookified": "^1.14.0", + "keyv": "^5.5.5", + "qified": "^0.5.3" + } + }, + "node_modules/cacheable/node_modules/keyv": { + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.5.tgz", + "integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/capacitor": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/capacitor/-/capacitor-0.5.6.tgz", + "integrity": "sha512-xjyv2ztJxD1VayTMGIkh+TNfpdJU9BT3jO4Y5kEsh5MpF+zEdBQYLC/pFD9lNyS6mi8Pm3b/bj0ZUSOKblkfcw==", + "dependencies": { + "immutable": "^3.7.3", + "lodash": "^4.17.21" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "license": "MIT", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/copy-anything": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", + "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", + "license": "MIT", + "dependencies": { + "is-what": "^5.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "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/css-functions-list": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12 || >=16" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/elementtree": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", + "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "sax": "1.1.4" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "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/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz", + "integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.1", + "@esbuild/android-arm": "0.27.1", + "@esbuild/android-arm64": "0.27.1", + "@esbuild/android-x64": "0.27.1", + "@esbuild/darwin-arm64": "0.27.1", + "@esbuild/darwin-x64": "0.27.1", + "@esbuild/freebsd-arm64": "0.27.1", + "@esbuild/freebsd-x64": "0.27.1", + "@esbuild/linux-arm": "0.27.1", + "@esbuild/linux-arm64": "0.27.1", + "@esbuild/linux-ia32": "0.27.1", + "@esbuild/linux-loong64": "0.27.1", + "@esbuild/linux-mips64el": "0.27.1", + "@esbuild/linux-ppc64": "0.27.1", + "@esbuild/linux-riscv64": "0.27.1", + "@esbuild/linux-s390x": "0.27.1", + "@esbuild/linux-x64": "0.27.1", + "@esbuild/netbsd-arm64": "0.27.1", + "@esbuild/netbsd-x64": "0.27.1", + "@esbuild/openbsd-arm64": "0.27.1", + "@esbuild/openbsd-x64": "0.27.1", + "@esbuild/openharmony-arm64": "0.27.1", + "@esbuild/sunos-x64": "0.27.1", + "@esbuild/win32-arm64": "0.27.1", + "@esbuild/win32-ia32": "0.27.1", + "@esbuild/win32-x64": "0.27.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "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.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", + "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-json-compat-utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz", + "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esquery": "^1.6.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": "*", + "jsonc-eslint-parser": "^2.4.0" + }, + "peerDependenciesMeta": { + "@eslint/json": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsonc": { + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.21.0.tgz", + "integrity": "sha512-HttlxdNG5ly3YjP1cFMP62R4qKLxJURfBZo2gnMY+yQojZxkLyOpY1H1KRTKBmvQeSG9pIpSGEhDjE17vvYosg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.1", + "diff-sequences": "^27.5.1", + "eslint-compat-utils": "^0.6.4", + "eslint-json-compat-utils": "^0.2.1", + "espree": "^9.6.1 || ^10.3.0", + "graphemer": "^1.4.0", + "jsonc-eslint-parser": "^2.4.0", + "natural-compare": "^1.4.0", + "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-vue": { + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.33.0.tgz", + "integrity": "sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.3", + "vue-eslint-parser": "^9.4.3", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-vue-pug": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue-pug/-/eslint-plugin-vue-pug-0.6.2.tgz", + "integrity": "sha512-jZt5f8FtRcNncHiWIfZDvzGlu2Y3XLj7OshpH8y2KHtCXjGBsyvUzKayHsFgTf8yN4ZOh8k5uOwMstgY2vUHsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "vue-eslint-parser-template-tokenizer-pug": "^0.4.11" + }, + "peerDependencies": { + "eslint-plugin-vue": "^9.8.0" + } + }, + "node_modules/eslint-plugin-vue/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "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" + }, + "node_modules/fast-printf": { + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.10.tgz", + "integrity": "sha512-GwTgG9O4FVIdShhbVF3JxOgSBY2+ePGsu2V/UONgoCPzF9VY6ZdBMKsHKCYQHZwNk3qNouUolRDsgVxcVA5G1w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=10.0" + } + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hashery": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.3.0.tgz", + "integrity": "sha512-fWltioiy5zsSAs9ouEnvhsVJeAXRybGCNNv0lvzpzNOSDbULXRy7ivFWwCCv4I5Am6kSo75hmbsCduOoc2/K4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.13.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, + "node_modules/hookified": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.14.0.tgz", + "integrity": "sha512-pi1ynXIMFx/uIIwpWJ/5CEtOHLGtnUB0WhGeeYT+fKcQ+WCQbm3/rrkAXnpfph++PgepNqPdTC2WTj8A6k6zoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/i18n": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.15.3.tgz", + "integrity": "sha512-tW/AA5R4lJZLnd60Agcd0PfXB1C2G7UqTrdNewuv/SIYdxcHkCE8w4Zx1SgCjJ+2BLuAAGIG/KXb/xNYF1lO5Q==", + "license": "MIT", + "dependencies": { + "@messageformat/core": "^3.4.0", + "debug": "^4.4.3", + "fast-printf": "^1.6.10", + "make-plural": "^7.4.0", + "math-interval-parser": "^2.0.1", + "mustache": "^4.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/mashpie" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-what": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", + "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "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" + }, + "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" + }, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.2.tgz", + "integrity": "sha512-1e4qoRgnn448pRuMvKGsFFymUCquZV0mpGgOyIKNgD3JVDTsVJyRBGH/Fm0tBb8WsWGgmB1mDe6/yJMQM37DUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "license": "MIT", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/known-css-properties": { + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", + "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-plural": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.4.0.tgz", + "integrity": "sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==", + "license": "Unicode-DFS-2016" + }, + "node_modules/math-interval-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", + "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "license": "BSD-3-Clause" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/native-run": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.1.tgz", + "integrity": "sha512-XfG1FBZLM50J10xH9361whJRC9SHZ0Bub4iNRhhI61C8Jv0e1ud19muex6sNKB51ibQNUJNuYn25MuYET/rE6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-fs": "^3.1.7", + "@ionic/utils-terminal": "^2.3.4", + "bplist-parser": "^0.3.2", + "debug": "^4.3.4", + "elementtree": "^0.1.7", + "ini": "^4.1.1", + "plist": "^3.1.0", + "split2": "^4.2.0", + "through2": "^4.0.2", + "tslib": "^2.6.2", + "yauzl": "^2.10.0" + }, + "bin": { + "native-run": "bin/native-run" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pinia": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz", + "integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^7.7.7" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.5.0", + "vue": "^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-html": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.8.0.tgz", + "integrity": "sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "htmlparser2": "^8.0.0", + "js-tokens": "^9.0.0", + "postcss": "^8.5.0", + "postcss-safe-parser": "^6.0.0" + }, + "engines": { + "node": "^12 || >=14" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.29" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pug": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz", + "integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==", + "license": "MIT", + "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" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz", + "integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==", + "license": "MIT", + "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.0" + } + }, + "node_modules/pug-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "license": "MIT", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qified": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.5.3.tgz", + "integrity": "sha512-kXuQdQTB6oN3KhI6V4acnBSZx8D2I4xzZvn9+wFLLFCoBNQY/sFnCW6c43OL7pOQ2HvGV4lnWIXNmgfp7cTWhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.13.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "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/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.5.tgz", + "integrity": "sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.5", + "@rollup/rollup-android-arm64": "4.53.5", + "@rollup/rollup-darwin-arm64": "4.53.5", + "@rollup/rollup-darwin-x64": "4.53.5", + "@rollup/rollup-freebsd-arm64": "4.53.5", + "@rollup/rollup-freebsd-x64": "4.53.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.5", + "@rollup/rollup-linux-arm-musleabihf": "4.53.5", + "@rollup/rollup-linux-arm64-gnu": "4.53.5", + "@rollup/rollup-linux-arm64-musl": "4.53.5", + "@rollup/rollup-linux-loong64-gnu": "4.53.5", + "@rollup/rollup-linux-ppc64-gnu": "4.53.5", + "@rollup/rollup-linux-riscv64-gnu": "4.53.5", + "@rollup/rollup-linux-riscv64-musl": "4.53.5", + "@rollup/rollup-linux-s390x-gnu": "4.53.5", + "@rollup/rollup-linux-x64-gnu": "4.53.5", + "@rollup/rollup-linux-x64-musl": "4.53.5", + "@rollup/rollup-openharmony-arm64": "4.53.5", + "@rollup/rollup-win32-arm64-msvc": "4.53.5", + "@rollup/rollup-win32-ia32-msvc": "4.53.5", + "@rollup/rollup-win32-x64-gnu": "4.53.5", + "@rollup/rollup-win32-x64-msvc": "4.53.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "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/safe-identifier": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", + "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==", + "license": "ISC" + }, + "node_modules/sass": { + "version": "1.97.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.0.tgz", + "integrity": "sha512-KR0igP1z4avUJetEuIeOdDlwaUDvkH8wSx7FdSjyYBS3dpyX3TzHfAMO0G1Q4/3cdjcmi3r7idh+KCmKqS+KeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass/node_modules/immutable": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", + "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", + "dev": true, + "license": "ISC" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "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": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.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/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint": { + "version": "16.26.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.26.1.tgz", + "integrity": "sha512-v20V59/crfc8sVTAtge0mdafI3AdnzQ2KsWe6v523L4OA1bJO02S7MO2oyXDCS6iWb9ckIPnqAFVItqSBQr7jw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-syntax-patches-for-csstree": "^1.0.19", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3", + "@csstools/selector-specificity": "^5.0.0", + "@dual-bundle/import-meta-resolve": "^4.2.1", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^9.0.0", + "css-functions-list": "^3.2.3", + "css-tree": "^3.1.0", + "debug": "^4.4.3", + "fast-glob": "^3.3.3", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^11.1.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^7.0.5", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.37.0", + "mathml-tag-names": "^2.1.3", + "meow": "^13.2.0", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.5.6", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.1.0", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "supports-hyperlinks": "^3.2.0", + "svg-tags": "^1.0.0", + "table": "^6.9.0", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/stylelint-config-html": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stylelint-config-html/-/stylelint-config-html-1.1.0.tgz", + "integrity": "sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12 || >=14" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "postcss-html": "^1.0.0", + "stylelint": ">=14.0.0" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-17.0.0.tgz", + "integrity": "sha512-WaMSdEiPfZTSFVoYmJbxorJfA610O0tlYuU2aEwY33UQhSPgFbClrVJYWvy3jGJx+XW37O+LyNLiZOEXhKhJmA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "stylelint": "^16.23.0" + } + }, + "node_modules/stylelint-config-recommended-scss": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-16.0.2.tgz", + "integrity": "sha512-aUTHhPPWCvFyWaxtckJlCPaXTDFsp4pKO8evXNCsW9OwsaUWyMd6jvcUhSmfGWPrTddvzNqK4rS/UuSLcbVGdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-scss": "^4.0.9", + "stylelint-config-recommended": "^17.0.0", + "stylelint-scss": "^6.12.1" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^16.24.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-config-recommended-vue": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-vue/-/stylelint-config-recommended-vue-1.6.1.tgz", + "integrity": "sha512-lLW7hTIMBiTfjenGuDq2kyHA6fBWd/+Df7MO4/AWOxiFeXP9clbpKgg27kHfwA3H7UNMGC7aeP3mNlZB5LMmEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5", + "stylelint-config-html": ">=1.0.0", + "stylelint-config-recommended": ">=6.0.0" + }, + "engines": { + "node": "^12 || >=14" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "postcss-html": "^1.0.0", + "stylelint": ">=14.0.0" + } + }, + "node_modules/stylelint-config-standard": { + "version": "39.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-39.0.1.tgz", + "integrity": "sha512-b7Fja59EYHRNOTa3aXiuWnhUWXFU2Nfg6h61bLfAb5GS5fX3LMUD0U5t4S8N/4tpHQg3Acs2UVPR9jy2l1g/3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "license": "MIT", + "dependencies": { + "stylelint-config-recommended": "^17.0.0" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "stylelint": "^16.23.0" + } + }, + "node_modules/stylelint-config-standard-scss": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-16.0.0.tgz", + "integrity": "sha512-/FHECLUu+med/e6OaPFpprG86ShC4SYT7Tzb2PTVdDjJsehhFBOioSlWqYFqJxmGPIwO3AMBxNo+kY3dxrbczA==", + "dev": true, + "license": "MIT", + "dependencies": { + "stylelint-config-recommended-scss": "^16.0.1", + "stylelint-config-standard": "^39.0.0" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^16.23.1" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-scss": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-6.13.0.tgz", + "integrity": "sha512-kZPwFUJkfup2gP1enlrS2h9U5+T5wFoqzJ1n/56AlpwSj28kmFe7ww/QFydvPsg5gLjWchAwWWBLtterynZrOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.1", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.37.0", + "mdn-data": "^2.25.0", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-selector-parser": "^7.1.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "stylelint": "^16.8.2" + } + }, + "node_modules/stylelint-scss/node_modules/mdn-data": { + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.25.0.tgz", + "integrity": "sha512-T2LPsjgUE/tgMmRXREVmwsux89DwWfNjiynOeXuLd2mX6jphGQ2YE3Ukz7LQ2VOFKiVZU/Ee1GqzHiipZCjymw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stylelint-scss/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.1.tgz", + "integrity": "sha512-TPVFSDE7q91Dlk1xpFLvFllf8r0HyOMOlnWy7Z2HBku5H3KhIeOGInexrIeg2D64DosVB/JXkrrk6N/7Wriq4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^6.1.19" + } + }, + "node_modules/stylelint/node_modules/flat-cache": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.19.tgz", + "integrity": "sha512-l/K33newPTZMTGAnnzaiqSl6NnH7Namh8jBNjrgjprWxGmZUuxx/sJNIRaijOh3n7q7ESbhNZC+pvVZMFdeU4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cacheable": "^2.2.0", + "flatted": "^3.3.3", + "hookified": "^1.13.0" + } + }, + "node_modules/stylelint/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylelint/node_modules/postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/stylelint/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/superjson": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", + "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", + "license": "MIT", + "dependencies": { + "copy-anything": "^4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/synckit": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/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/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "license": "MIT" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "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==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", + "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "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 + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/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/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue": { + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.25.tgz", + "integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-sfc": "3.5.25", + "@vue/runtime-dom": "3.5.25", + "@vue/server-renderer": "3.5.25", + "@vue/shared": "3.5.25" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-eslint-parser": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser-template-tokenizer-pug": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/vue-eslint-parser-template-tokenizer-pug/-/vue-eslint-parser-template-tokenizer-pug-0.4.11.tgz", + "integrity": "sha512-fZ+KprCfIuk2Nt1aBUa0k3dpHyKj5D1oRx0H+GRA1GsqTg5f5lJpto7n6crwDeSIQWsn/1zBb+6b3d3b7n/AVQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "pug-lexer": "^5.0.1" + }, + "peerDependencies": { + "vue-eslint-parser": "^9.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/vue-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/vue-i18n": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.2.2.tgz", + "integrity": "sha512-ULIKZyRluUPRCZmihVgUvpq8hJTtOqnbGZuv4Lz+byEKZq4mU0g92og414l6f/4ju+L5mORsiUuEPYrAuX2NJg==", + "license": "MIT", + "dependencies": { + "@intlify/core-base": "11.2.2", + "@intlify/shared": "11.2.2", + "@vue/devtools-api": "^6.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue-i18n/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/vue-pug": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vue-pug/-/vue-pug-1.0.2.tgz", + "integrity": "sha512-fV58pm/a/bBOR8QPNulb0sU3EYt0q9ZH2uAHwE/XsODcY7PukU/Iu1GSB60CfsfTYcPtbXxelraZEdoKgAoIcg==", + "license": "GPL-2.0", + "peerDependencies": { + "pug": "^3.0.2" + } + }, + "node_modules/vue-pug-plugin": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vue-pug-plugin/-/vue-pug-plugin-2.0.4.tgz", + "integrity": "sha512-g1BUmg2W152T1bQABhzKmt3W/6d2fcql3DmbLvu3lyuJNFEnlUpFNPuZBpvuYZxSw11j5HOYNKuW6XwGp/PzDQ==", + "license": "MIT", + "peerDependencies": { + "pug": "^3.0.1" + } + }, + "node_modules/vue-router": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz", + "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/vuetify": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.11.4.tgz", + "integrity": "sha512-614MKpopMzNjkQVD5CS/xr77p4CqtF2wNqQByAi7oTEcKzA+gOsy5O3l97ZIqomNidOSGXyVg5s6t5bNO9p4+Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/johnleider" + }, + "peerDependencies": { + "typescript": ">=4.7", + "vite-plugin-vuetify": ">=2.1.0", + "vue": "^3.5.0", + "webpack-plugin-vuetify": ">=3.1.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "vite-plugin-vuetify": { + "optional": true + }, + "webpack-plugin-vuetify": { + "optional": true + } + } + }, + "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" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-file-atomic/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/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..89e628d --- /dev/null +++ b/client/package.json @@ -0,0 +1,47 @@ +{ + "name": "zen-kanji-client", + "version": "0.0.0", + "type": "module", + "scripts": { + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "lint:style": "stylelint \"**/*.{css,scss,vue}\"", + "lint:style:fix": "stylelint \"**/*.{css,scss,vue}\" --fix", + "dev": "vite", + "build": "vite build", + "build:android": "vite build --mode android", + "preview": "vite preview" + }, + "dependencies": { + "@capacitor/android": "^8.0.0", + "@capacitor/core": "^8.0.0", + "@mdi/font": "^7.3.67", + "capacitor": "^0.5.6", + "i18n": "^0.15.3", + "pinia": "^3.0.4", + "pug": "^3.0.3", + "vue": "^3.3.4", + "vue-i18n": "^11.2.2", + "vue-pug": "^1.0.2", + "vue-pug-plugin": "^2.0.4", + "vue-router": "^4.2.5", + "vuetify": "^3.4.0" + }, + "devDependencies": { + "@capacitor/cli": "^7.4.4", + "@eslint/js": "^9.39.2", + "@vitejs/plugin-vue": "^6.0.3", + "dotenv": "^17.2.3", + "eslint": "^9.39.2", + "eslint-plugin-jsonc": "^2.21.0", + "eslint-plugin-vue": "^9.33.0", + "eslint-plugin-vue-pug": "^0.6.2", + "globals": "^16.5.0", + "sass": "^1.97.0", + "stylelint": "^16.26.1", + "stylelint-config-recommended-vue": "^1.6.1", + "stylelint-config-standard-scss": "^16.0.0", + "vite": "^7.3.0", + "vue-eslint-parser": "^9.4.3" + } +} diff --git a/client/src/App.vue b/client/src/App.vue new file mode 100644 index 0000000..464eac8 --- /dev/null +++ b/client/src/App.vue @@ -0,0 +1,348 @@ + + + + + diff --git a/client/src/assets/android-chrome-192x192.png b/client/src/assets/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..c7e2585758f347599cc70c3c17530e7663dcbb2f GIT binary patch literal 22942 zcmV(_K-9m9P)2 z1nYrIFLmU=0|!b$bCI}CKWR?%7gx3vBNO-xpt7yS$~VOEs%_x&h9vCmGJ4$9H4n1Z z$doCCT-{%sK}K9RDzQWnSI49{;_&~7#N){t9R9DxO}K0Ck6DRX%XL<){^Yx&qPQfY z4PsU|OUd%(vh_ZV!Cq|ryxOdvuO0BMtEx&Q(ma-lzO|Uh=1jWnsbNzwc1vdHh9Xuc z>1X`?Erj581Yj-`cdiUHZ^*YtuaK&$Z6wO|uHBgL^?n4!>U~>@m;&zY$36PpKz=W5 z`J^8kYZGD&A8Dk{dg}U&&r<584Q7r+%?uen=8b@FyIx(MzLVFh?r8I}bLS3`rd9hh z>3_ro8_73c>dSsi zoFBEU#BDpQnTr=Ok^aZ$9w~O7m6hJtgCv^x9;@!|V%?pP4;7f+)wf1IW}|u(b?Hfo z%bOC7E|Jlr>(+O9=v{-9@6o8J7%By<($GHTQt2!{1r#kz3a`XK;SRWS@Q99j!@WAYyFt=wvf={(_G{=Sr{F^5(D zdii4ci?Y#1L&P-iB*ys_m!saSvqdNVlc;c$q`*v*?aIDbAB17u765PJ$IB#Q_GeP> z%K(3mPv@0BIj5I0;Q!*#`>1^W=L8-J|73y-XL8n2;~U;V+h0Z zGIH$e^vhZkY;R~`h;3MR1z^t1Z%K3f8U}J_`b+imRPU+-{%=&<#I@jFf{4*c>tlm8WImTNdC%nfng^_r^IEdiK4yPr7q-{xR<8a;eWx2v`> zYCHcQ8^Yz{)=w8VI-CRU#Y}hvV7;C6sV1hSUmn4ndWA$w-jQv$ZR#~MILn5t8v;;U z%OSRLcNY2m>5n~IR{T_5qmHB3x%TgpaGn%{+0xj<5r!Y+$v&UukoDN@ss=5fkDlP? zBlO)&%&59c^y$*~1)#Q4&5+kKp+}*!t5qg-v9>`RbBQ?iL1~J7O(O0MT&((izdk*R z`E9(ajHpKPk~GQ1QdYJgzmE_1X?;@w)PnQ&+e4&&#U6CWJ$%$V+g+(cNTy00)hHHQ zC2rIIaWK9BJzudqy|w6yt5_n%^r-E=S0YcgWQ^1f&_>U#p9lYdq<))^N)-|otYDwd|ZW&aZ_IX5xs{{@a`9D3|2>=rn% zdX1-6XS7cAFZnEBLVbv^E|7?$Li+{tei849y&nHiIaZ(w6yPaZUvkwveAUA_x;(5SwXl%;5#V4{Rlq^=;a+MB=ta+~)aGRIq|MzFMM# z>*R|s;7_8hDN1KsNXhboeOvgrd6vg-;Q1(6Q1ooi6W7{t%m?x{7S77Z* zNF+Xz??$sz;MKO9^1UKa^$f+fl1(v{>`G@#GlD%~f&%h-b;-1o^Y>CSvFAq;sKg7Fs+@=e0m+VB_c&;TPFNAOvZ2V-EhA9 zIzNZ;340~(u8Z_6@iCu;2*)fBvTf}fEEFGdir5xG+>Zb20)t?%&{&&k+YmU^PAC3X z88Jbh*K14f7J#a%Z;F$6lz|xG&qQfwu%exUiEgf##A{f5SmkV*GeT%%^Dg@OB#x}= zRQp`|MYct2-LAGO2@tu`2IZI&^rZS?&SVbU%0n8(Hj|<&3yC)jv4!sEU!O6 z2KU2*YwuywZR6v<%r8-ssxf+S#hGUBLPsYaz}*P-;#elm-u!*@%q#D~JB@tAIpI-> z+JEqVA7L)uK&1I3e&2^ysYhMavmm93MeJ~Ca9)ye<5U&vRi*a{!0Y83bC5cp4nNV~ z%41hC*>9Ib{q+(lIRt(C3|1W?t#VRSzy5#;GMPzV&Y5H;J5E1Vx_x;rE4>#7kg3{` zlLlv1skI!`O$~MMuIdCM)YF)K5pac<=$XN9Y2cpwIjCRO+f<_7B>=VM#M7F4>Eu#6 zOzqh|iv1k|^Eam5<=ppEe?sG<+K!i4LSGD)q-bQ4e7fXw*>KSIOo($4wjEnm#@^MJ z8N6aQx2UP}3xwcR)TFxzs#(IjA4q>6%x^Ir{+EO1P26(;pRnHt%)AE(dlIY0`KULzo8qM$X4z##Rf6@i z7+@sU{#lyrTq!hal0Kb&(%sLGM_nCer^<*i5A_C=Y1k7cvk6gEaXc1?OSxGsBYp~Y zX7_4Lh_5ja*KorR{oEAn8pGkx-p9Z`LTtb%oJVxU+l%K-q@JL9aIi=BjjNZ?%$Mj7 z79d;A&cNBr5M*REW+EMQT#=f3N=H?lIL@ue zU%5|16T>Y=-XebX9BE2SlLF^F#^`V+|2Ok!Q405ca$DOf`er^Bw_7Cb?;XLkl ze7eVFiJsle_433sm&>J>_E@|@&j~A;uT-6&ovd*dE{9z)m{EzdHgYJxtK}%wTx$mAcZ(GFzn~}L4Dv4k|EtfAf%5IwY}(-qrvze})6*WovV%3J@gs>xH6Z5aTr?!x zird|9OcU=rpEhfp?J}MTq79B7)qZsZbfS1c`9^t%fF+=AiB0eI4z-b?SEks$qRm$U>QXF_ znmWTME0}cm0Fk~D>&{lp$Gez}+htg>>afe1&`VLz7O|qe#LssS)=C*Q{%yX??4UOf zHF32WPkrB^trJi$fGW5Mrzzq81N?c%Gkl}aZnK}T&YcY4?;VLmFQnZXwA9u4K>P3? zQXfA{cFdm;zN9=!ur$s1q;8icZw~z44wQmwpLc^5Y!S2U#GF?_XW@L z2w>Hi<$|yJ3M0S^EVF4BU^j<4o2sRBA_JbI;syCPZ;#h`^A=nY-e$|{3eLz6PAW&u z@= zqSGbO2=ut$G8sNx@%s5MbLSSw%9R@cv>U|20>DlbFz6#jBL7Y0i5kf8p+_&%n3#kA z;7Z#2e_gbM-O@ZO4e=vEld7pTrzQ6S;8}Z|-!t(~Wa9YO`IUZ9VsL9V9m9R9KW2L% z1*K`91SoeV*p!1%Cw@@ap= zp9}Y!JGZ|yuN=es?!mbM20Wwmjeb?nth(FB%`W{56Nl*7Y8dBvd^&;$6+d*V4B7Z% z*>X#b@5o8XtpL=N>m0R-V7HP2VUh8{e0S6Mh@!;9l5aBstqaCUed(!QqL2!QJOvnzi@hbxr8C$^`hVa7Zl1@SY0;oil)2WRo( zYI*qr6Wk$apI@T(sMlC0e}^7WE=+t30-t^&alVWiSJ~%Qd%vAD`?-FS7|1!n0kZAI zDERlj`+Y_x*ID}?cG};tBdB9k;}6=zOjrfp9V;Wsp2!7uC^rHyyQ+-UHn>^Qz)5MF zagIe>-RZ#tG1d;i9IP{E(rJbd`o6_?(5ZlOR5b^LV>49e>j2M%Oq*`c{y;~?z&{KR|f5*OiUKkC^i=BYGZ(hs+ozjHYEBHxH9NK>quj_obnJBB)x zhc$UVOVTnDUFRMnrQ_aAS546G!xw;A)4wiOL2ABXvMp^kus66k$6_(aXrJcI(|20R zw>4x)agRiu`3BabTe++Y2aH{aCUmYu3tyJ)w@2q+zgUqy&+M#OOtQuwU{bw=RaTu< zT^GYdxAF{qR6zj#tITh#U-iTtyUo%NO-OOEEBzZ?SykvrLA@jO1&$OF2I?XZF2)P} z7^RVihTgclF}7XBb?Z*7u@)MIrsuZ1`FB`LgLF41!AISJGIG~tK__{4*M}c0kYKrq;EK#Wf8niKSyA(xU;`ht|ZplFO+0q32L4orv1mIolT4Ar6PX z%e95Ud#<%nCYrJ`bbx$tyr^>;aQdvy#n$e>^SScPX}duXPCUt zO6mL4#T=FpJx|19#ZuxHNxUc`F&Af?Q$P;1A(*Q*mO}x95q<(8ci*P(Kj!Z%Bwo-c zO--w1{CJI`vr;=_7~lOERqSWp;n#W$AFT&;O+a!Gegh85<}dB%0`Q9EtB=7F7uumX zJOR+o8CY^!h9=8bSWJ!*rvPA_RVPV?1wI`U`2~lnEtve*QHio0w3av>jpNJwS>9dv zf*i(x=BiAawviMP6YPi{>Y!yu7_Hl3M?+W*dBt3J0S7>~c6Yjr9KSGEO-fs@cW$d1 z4jyU{4y(n8z}qYkajBU~ZnGFGw;Ch7JPJzHqM?zfr-qzqs5hy7J1R(TF{X>?dl=-5 z3d9H8^A+&<10`M;`0WlfkaExYSO#GZfui|O`&Zn)~Q%|S= zK@xR;meIRv9B*z)O*s@SasmUkH_ubsw&Hoxf&Fyr$B~9!Z7rdev1>_GkvV)Kj5kyD zsH%#Ii5e*u(4qMnlXGA&CuWxoQB_7g=)h1k7@s)qh;ti>{N5x*6}vzYBnZyYe6QiK zMBqh^1_6Ml-Q3RgN^h@a5j;j8_du06cQqrfD?j`+*weWjU0~q;SBWrD4^5 z{NDPKfvVv?@?Y6K*q)=TV2^Y2Ft387O7t;@tJ7rUIQ@ILMOVIx3OGig5{YQsfR|S+ z-Goom1~1a>4q_c{!pr+fUL0>a;j63FBD5ik(Rlh(;UUVInh%Oa4Y&LUJLDgvKJgKz z=auX_5Ftdb;O~2|L!J$WXddHu4-Pctfz>%XA5`!}g6tK=n^nnP0F=R@x&MtcRNe3a z3k+!u=<9`%!@Lzbv&mD(Fo8kWqz-tDtp^3rqUVZdiC?`?Mo)mABjmDRL6I!|;xL{^ z#uV4#G0GJc`HI zC6kW};ehiLlYa$sOf>|cD_ZO`P`DhMZGN-t1i)K4D$(8X*d?L7K?+s`bFMf|uae*y zJ|DO%GbxU_nFH1x5{=!zsHZZpHEJ$sy0I8D^RnE6cnYo%!5V^UJ$$m02hGHUk~ z;#~CIxyl0=)G2{4AcYYc98=-Oh~4xkJ^Wu><{r6 z|A|3_p}-5k(1X$~GP3N#K&=US@!M|?kh*06x(Mp=67A)zG&31~!en?Z>wu9~)2FRx zA`!VIW|y3`I-H7MrHvP3v8!5>(zRwL7$>~Ln!QKlecM|XFc$a=s6(A*O3Hc}q_TJAg_ly%m<_9U11xtG&sFDL z=Ka}S7b=!10nOvey2r9v?WDRwlLY>XK3C$d-m>C%KY2U^uDzSZ@@5$`2Ch>t%O^1* z_FB4Ioox3KTz_;1Gtj#w^8u@__!W0+f{9E3R!DXX607E084N<^0=HvHi|(z|-!~$J ziWFt*#I9Ue@>13-WzgQ#5Kn1RFQ&drE)I^GqG$>hk;5~Jn3`L;2}FgEjah{m1cRmo z?TcJouMu=c`AeMxuo#iLmj6{w+lj;R!;HO}VSgl}%3jOl(U}QAb@dJm258B^CeI`s zR^9K$Gl!`uD=6H7$$(kRjogg@{g(sMCSJH<)c#y{7+0N1Cxmj32K<=#-)WmB?Fhdl zEn2$-8tAI35}Z{(#8E{C9oahkM&-T6Pf>r4lldP$FNYrLN^KRO)Jppi<>Twz!7O)U-9gUnsWYN{AP=_LfA7SwMh5Yx0 zsXa-r;l0G`m79ZNeUjf4dK`Xnh)EbR_7GncE6bh${nj{)%&cp^9@7ICy~W~r31>V# z42#UFJO%;3iQVB`d1t}hK^>gI1)!>mBopzcGql=(DN)W(+~fux`Jf;ykGNI#V^B%* z;JL{SFTbCRE_AW`Bb`bn)OnJiL4 z+m-L@NoMXI4@~+|9Ck6Z5%m`D%%ZwqQ0~!S0^lX8D0!K;Rj+R*rJ4ik9^ifc#LZoW z!*y3DPzD2Aw0l1jV20;8HRf~~IVOAuS0-=PdXE>86-PbuBC^6SilG@*_E?t{KL^}- z!@;MpEL_d^nVikSZ*T5u)S#vFh$_36#2@&g>S38f75;q5MY7L6>Rj_xf(bxv2A^lsQ37ESzh;`3@9PMhw#_Y zqsiElzW5UWCA6yd5SAJ}lu7vlHU)UKX9NCjZ(Vo`sQRLJ$-{dI3<>57fKCLRuWwpQd2eFc9N6~I$M@4 z!@0%Il7yhF>z1Ajx{usu1BMVtK{o*bwi z194JgoUDc5>_?B&EHHhi%$rvzE0?IZJAEIgeJdPbPQe+{&=4o&T#>iRmf>HGOk4jt zb-{8L+Y^CIJd)O5l6G+3o;pBQ$6m=|^;ZF?fRly{<;^csPms)w(C76ZBdb>r@#0A} zP@=Du>T)=VOm?fZCCaXZ?CVPtbBJ8R>ekNfYz|oa zbo#G2s(hrG4W^aJ?3zc*=!qZ5tP0>Cax)*b^Y@0L!R};wbY5ZNPX&lLONM-Xu`K$8 zz*!r*R z6V{$oJ(KjzYBIP?3YptsVkj;B1guLLp@C1(Ckp-U`C{!<7RAe@#Ccu5KW35C%z$Ce z`6chFD>*y7w?k=su^++L!@UN`69=t%1c(i3Nc=|%3nRcuVD@kn_pjM{GK&_pmQ-5N zJ-eg7=|%u%o{FTZJ3ouUM0Usq<3@3QS)W`#=!~&~gJk>Csw^JdGq-B6M)i~-;uM3q z_h1RZ4*l9{P1j_dQ)T4n$7JU8iD2GIHPnvYCI9c{r9E=r0eE<&tZsNz1`HrMctU}8 zN_wo6C4MHm-*&S@VC5krvfuUF>MpM1f$?1kXIq61ID@UO4c}vTwG#bbI!>Y1e&cwJ%&r(FarDR1GUfHm zuaCeBGc4y&XEe+Z7_c3@ad5_l&dFWHEFtx9X&^b{=hj z<}&dhw8i!C`a}7mRwxqS83PrfQY0#&af{01pu-2s0ntS>4P$QwhH#4|$9WiR&m5w_ z%J|!>Zz1D;%Idgj`C3rFnd3v1?rfSSOKsk`$xG zAWEZ95as|&euu98O#c-6%Um zF$>W~z*csrAC!0WJ3$`T#kIPa5$|DuIJnoy@|9ST25KatV#)jlQfZcrWR1gu9F z$%!;6G#V&pq-Oo1bw-8 z2{t_s^>PXXXFF3L@Mq&MnW2R;r*tfFEF>oEP&)4b6%|`@W>nr9_4z8H`fzE)F4eTN5|mq zbRvbY%3+^|=TZ{rw+?Zpa8@dPxK%aKQLdbCQBPZ{MgMK={z_Ik=)s$?^>19iT$Yt6 zHRQ!SKPb&iIPJ0aWk8F+lX)MO2aT@kvH?#&T_|7Qa1V9|81pI3G^2ul}nwS|jIvD9JSSB!C001BWNklK;8E%7AwaN&a14-Vj8A= zIl7A^k&E3I4RpUvmaRTFFvj1X0Hk|{R*;uP+%Wtx@QCYNul>BxlsP^0pPV7l5j&O^K^i6-0R< zvnd~;V(iUMLN-QwM%s#W0K}XiqsA(^Zm=?U?htrIVPgm}b9}HCWPY`Qse0ttUr7>f zt}Ek#nOBzaof=yDTR?|@Uqe2XaaBHUR0m;^qexawd7Ir%Amn1Uuz{E+pwLD5nymI; zs$E+T!xv&;(FJ~urLesK)K)6_sCv$_(9^ivl0P@PY?QkitM9<%-B$~_t>K1z1jfs|Ou(m?>qFJLRtfa>guS~Ti4 z_}$?EYW(;T{)HNlnbql^|BT31!(bBj*x~w0si&XMV8^?Ypq7c4oFAa!`A%N95PkeK zRz!`^%YT`Tu_d7ficDAmJ2iJ66qyH+=m{E0qsZmXx!{twC?)%ZwyBod3qVczR3_|> zS@(v4-a8(@9g`t0d{O$k?u()E+0d6)S14WyhPbS^)O0Nk=X-+TyA zd=p(13&musd6%!(3P9Cg;a3>}V{_Jx(Q41Ybq;qY5lkZKFf2_3F%R(@#N6de)y~)v z_`tvUu4kydgH4G!_%RQa)sfGEi4ZZCwHgrY=|W7kfz)i|*jYhu4DEW4I;QzbDTw?L zA~7J|9yNP*#mhBep2qZksBAp+3T8IhhPt4sRR7edace?**9t(*ObAomF1=-eTc%Pb zE_#-8r)Nv=wwPydQY2I0WLi9Oq=e=a&i3%0X$$<`hw3AT@xIUC+K07`d5$&&XBmG(r{A&fE zwvyaS%D5Xwarfb+w&sAR^>u%+i(qmc-V)@U&7*57aUemF*Lw>=A?6-g-E^*OP`t4; zHb28;+$xXF{gD1S8~r!rIOPoApr(Q>G=jI@;@t&FYQ-PrWBSLzq-}oz90Pxn1+w8W zNVhKzc%l(WareUsTUQr-0#X6e)9v8Nu*xt-r{yOm7XNhk#R zH3Z;vOy>l#&E5)`e9m&_GpScePwRpvm3CQtKIJ=-ZjYUr6o9a){31pDK{To~E3Q9vam*Ef z-xMwA7yIA+kR-E*9D}Ui*kfR_PA$aAXWYGI-Usi=)?1zplJrV0$&bTJNySX#Zc@6l zCcW-`<@Ks>lhsqxAZ?0I;0VBq8)3&+GO=tu#I5i8iVUy^$SO05`Op@TtbsBRjFsJ& z6o6!o-$(g`L$c&X2BY8INqyZpx3GxVGcif|CNlLkg34pGY!MmaEvb`wybu(RkS||- zjST7kUAB3(zU0Z_WjPE+b|D-J_KheW>62zMxsOuW4M6`AP{><>en-( z9^Ye8sy@O+hK~zZnHF!s<$O9~>}4$iP>JV^=$mlT=OlR8#z3m|@S)NEsR|era2z8$ zLsYXKu-9J)SXOs0^<+xrm~|7p3aqV`MB~9S_6Hxr6o>UCN0jNETdU^QE9LXW*9V~r z59g%=)Z*>f6=(n?>{C3LV~<5$0p4sC7Lt8QMzsAyN}5lSx|qf`tTpmj4#z9%PfiLz zb>&`6MxC(PXFK$8_))O*%@6ZZyLR&yYL?rpty?<#H*Qly)zoitz|JNEW%kW+*>*>l z{fFdq5QCwMhj+kB(>9Wi6!zO2>i8wuzeJ8}sGjjt1VFU_^#lAv5=|FLwD2weA+%}R zM^cvPcr+5={bZ(Z4Y0R%G9bF2wh91=s;#OlX`EJRAEv8b12ibOq1#1ib-q#c)6%iH zt#cT|TMooHCf8zRfZH^y_y!*@-u4pB_AZYh+((f~ekg5FkXD|YbUZs+^3Aq@uYiru z@8wl9$`FA6ut03WXDRU`Kg47U1-{X&n_(5rGIi(09=q3CLtazw2WpXw}zj^QF9YpkNoR%>aR|sVT&JQ5;m~< zpM?PG!8bEv;UMp7Z5-$0@33xM6XdoYy|%o3AbFl=(uQRGurW8`M17V8c@qB%3)->* zoX~do1(do)la6b!)0bis<6Cxs@-um`2ChS3lx5MBmi;4}%Bln@EW3+qwJ<%8Q-@IQ zi>GVW63m@or%Mo@V1{M?P{?`>0~J>=o4hNLl9f`}&>)XIzif@Osk-`mFk>hsWH`o! zw2ij^hEd|gKB4-weV3Z@=NS_wC&fDp6p%ln>7FzyblTo%cY$#(WCys9{1jN7yg;pl zB;q4l55XKd(s*tCKhCoH4V8EUhfqrz%M`_l>?tEg^Wu3fibQN&0i}m?G##vg?E{&h z8Um@pU+6igGSQ1ipc2hJAu(ncl+wM)lp}jsh zA4?wLQ4=%Dmm69$GO4Jx;zIAx-dYq(W(?d)_EP>7){Z?FuGw+Yu=0B9R$6&BY`arZ z0Q4koVF3uMm;!>z8%cv|QbQ{W`ww8HQeC;{iU!jp>bI6y;b45n1DWc|Y*s**tM~Lv zdWiHp(0&+#>K}XI%Rn%K>he)^v?goFepmI=Lz=XF#MpB}^QriGW?0u~{t4GJ!?zZ8 zO(%Cn6C6?}9k zDoddrh4A>Es$wb`b&6xNSY2R|%S-tS3rV&dPI+l)+J{stB%+-mCQewbI>`>_@8p&a ztB`Ig+IRwIj(gdq_hD#ce)Sz^P1^TuxuCY< zQg*#d{9c~rbvTb=`w~mhJCUA2U#_+S4k=MI!rG!q(P3xB82uuDY){}2wEi{M<0&6m zHW>DE%&zWvEdo%n6AyZX2888#V-<9M#jc{^cb%O;9U}8HewW^KWAzN2Ue1$wTK!=~ zgP?ch_@p^+T_`n`7)3awwwHh>V0k!$5J!bfD+6~p#f@x*NtB$`?p>{(;2pe(dOs8< zzM5d?OJQtpGCXRXTX(v}mHhyTX<*2@Q7qgbTv0boxh1>o(s2T0v=&Bzjt%~g3A zqwYb_?dchybM#Zxj+Pzrz~LWSkEN-ovT}2RIg|ql7khGULw`i4wQ;N0Z&CPhjpN&5&$ERXL;wytHSGF zGlf3f6{yMt4El z645ugCHq*4w9h4Rg{j|03KrE#;}(DR!u%ox6^$5|e@s={wg$W)?{MG=>ACr= zMsumnnn~IqSg>k;nPX*u;FGAi;d=bc|NVd^PfU^kYL=;?aJvma5ONX?-r$! z8C0S%6q*h-BpY>#?$Fggk@%&Ip75a5%p}2ttKpTcFkwZm?nHm~y|l7zU$>@04G5k2 zN{xJh`tx&kStUOXhquZqOSF5ej2i!_?f{yS@{jWF`@fZ~w^+#UA=+Ev!E}^s$cr^t zTQtYh$g=Ed*n3iZs-}Mz;a1%{_p86iy%0H_B%2N1kZevG*Sbx+SGR<-jvAN5xcAkP zj7x_uvSTrjC%8Wc6LfBfrchlp;7TgH9RaA+%o*703kVQt#FAlt5n3N=1{Bv-P!mZv zOj`@dA9y%PA^LEcRSC2#7tv{*@uB}auQJ$N8 z!7##q@0xO)h~~1+6`Lj&(O)C@N-lhBXb)E0(a17*fodw>M*tuyHDgI=;gZ;*B2*l^ z1s1Jam^esyYhm(~jtevDKeT>HThXlPU+1i(1XsCEW`}A@Lh2&OqCQ&LC>w5Y13R@^ zo4P)4c!Buj8W=t<%yV4Y?g;II>T*qUg|(+s0rHK9-6lTbtcoc#q_S23$|v)HUD$q3 zk(hau+_{g@#mW>HPVp$$l^&3gy)`NB$xu={?)%|9Adj_Z67hrfK9iMLfqc29H(Z7p z`FJ2BkFxr2#X(T>9}u#cvOq@z7wd>If9aE9k+l_nXW?a`?5b$ebF$VaLrlXdYXqRS zf=upS;Py*62lm6V@h5%{536s?|G;u^K#M$tAZ)g#^&`h>@Oe0#py6~$`dX@|1EPvP z78;9o_fLFD=D)wEjQLtjmi9x1gk3s)K}cel_d;UZPXD~{uBa)8Rwh-x1o%RW2V5uh zE5bANuH6A2df(7#>KMy{R>ABD3g%o8u-XgeoB;u5v!{f5I`NQq8z^?DuZ)t&W#z2p3~YxT}R zZkC8#N+_d}+J;ls2td`0UxLC*CbRYe5(*w9ahs;2?>fm?(8qhQ2!XTTDvgNZWm*am z`h5wijq+c|E zn?{y}LxLJom!zyl556{v{oS^=zvtq)sxl^=J*2q!Gih9bY0Y(zHIfmsOR+|b-9Z{;Ub8cuQ5_y{(YiXHFF@G?5HaSKY%d{G4p8-*RT$H z9MIs%w}iKew3pUmd+J1MQZLFN=dryk9aP917= zAw^K>8094G{pYNzir?ec?k+_3b_Dt?vJS2ANX)V?ke=CdFfacZy>=RW^$~z+96*vp zwYSLN)#uC75{21n>iKYr2aZG4iV9XI+mA{Y0v_H?hLzsUnerUBA7KF$k4uf)*yz}Vr3D7@l6>}vKNoj!$}zFEA`;}9u6G@%_`jD+dK!GdgK_kY0!DS ztSC6kfucJ+qJY#dsDw>T&3j7O#A>N7KY_8({Ayur_4>^DSow~?K~~wzdN|pf+KT^U zP7pflsl{CvHG>xPzX+oM)cc{7&k%rvIRlipGQ%CpKr0YwZGsG!{9S{F-YzSbDBeAc z)ks?o@Q!piuG4?L9@aO*--Wkl5Yx&?r?;?ja}%_JahT-ncrw zND~xhG0#ZMJ;pm*^rqr5XjicCn(nQE#$1CH= zxzcJXfrwj0$%g%0&6RaCR=2ZymAY9~HHd`T?pa`3-KHmf{`C!0)W6zZl6=&!Pr?WM4Fki8v=R#BdNr?j!h$J zvv)0NlpKw{&b}CMMI+1hORhhyrKVh|5j#MX)i2=ehnn&c0`dZvhC`bo(59FKkxdaY zrjxCsqa+!vf2s&)*hp&QahH}(ga8@M%F>& zstGeB{!mtau`?O;3#ju5PUPzH@3~S_15mF?=^-c5h+LCf>3d>{5YG|;ydt|PkEgIfiSXc%hvDPTN`RC&rJ=zH8o&j4k7b7dA*8I z6^K5{-deF-643lbBcH+_v{JSo{chGT7^H%#7qCJMxE!J9P_9_0yp(2ky`Rd64l3XD z=|k|yzmlg|gO(Td@)_SF@%n3I?5>~XJ0ghAG8HKPYDk1woEd|z% z9J^+*YcBw^W{!l)ghNTY0QS}a#;^S?)H_QBmXUk!SsgxopDX$+Ae8rJjwo^NS}SFyjfgt?$PQ!HuurrX08Q_cF2lP>GV68}Xt3+5 z5Nw)hTh`tO9Y&=1P*j5aY{g!3X2G)Hu{r0jXxy%e?*X6uvzbck(p%fq3Fap5r#qgbeOXe_*w0b5cf370IHXn#2vf<}|NDSSIHnQeYYNDNMF&$l?4_&JM`cl}B)}{fjU1 zg@iqnSoH*KB|vhrTX44@nQ4^$Q6!uhG$_F`Kwxc{Kz zvfT-mf)4#Z(4ndV3}es( z#e-7Y#XR{LQk7oj5hsUPk_(XLkoLzv)no@rfrT2~QOcBTcEtqaP88VKtK05wodv*i zPbU=mutVDSHu4Uu)z7dBH6k?ka=lX5WfL-pq|0#X1&VITd&v;XJY-CR#|_ zL2EAfQkrF~lm&==s4jn&f!fpmBXV)2(Vh8DEP#_}|3@;mZn>CUHFh`iGH2$uBu=b? z-~dfmth_5lbt9yynB5{v3y?xiOym%DHdVdWl&;mB+KOK%<9K}(3wy8Yo-L8)xnc_8 zaGv&+B1q=7Tveb{q!OrKsXg%M>H)AXB~|14~fS@-XvdcUGy zm#@Cb_XKIJ(E?4coe4C>UdNwug%9#G7VWRGf=`H@L0q5|M&Zc{snGFC9-1wAzUt!_ z%fuAWmYVXnxDUQqU*&irx5^PXwE$(KSgE}O<9h`WNWXzBPK6q7#F#MeC~Yq8D4x zujvI@;ta%o`%~)RoM1;H4B2^)6`^WOD~L-EL>e9kXC&mimXxd##d^XHXA2JV@Gjjm zsb$lle(s%5r|;F)Ww6l&@6v?wg`(7 z5tytz&B68#DR3)gyRt9Yb+Dhis5|C+e3wsWQpdhs#+LhIwp<7RLMXZziBaoSSqQb| zt_lUKtyq0#m+IcE%Ae9Fnk!;$&{cOWG3HKC$e60*i?cLWH=~B`0qS;2Fagl3Ybs!L z_Tn`&_xP&wN9>>QFFYr8&~+4$A1vY=P3;7Jd&ts42DXR^tG}lfG%w$n0MEuUpnUl@ z_JWLD{)Nma+?bU@Bi3}qPj6Ys-SD^8Oox+ip`iceoL$ss5>6qZn`fRjgp&5k!kMw8 zX}d0A?F#cKjA+}tT!p)M9egGjR$O2Zj;DoWUNqLaG4X#m_mokhQ%S$F*Hma^)b*LS zz`Ii^``+QDNOtCc|5!0u1`TVF)l0X+B(@Qz)Q!>izKyvJ9wPh?#tdMvampDES1vek z19|~-8I0!9z72bIt^9And{i4{uK)lUO-V#SRQcvNHwC~p7Rly=S<{MIO7d;pNzo;W zSuY?1P7X4-Cn?f3p1N)1UY0`>!tKVq$9SFKLA$#uNr;E$it~Gz|A6_h7iNFrqdj7< zObZ8gWyUD$oOht5#`FT9mXxB1zSy`-ThZn|wG?OoJZW$2basMgr4g$^S(!Rsl4b7P z0w~&JV2xmek6T%?q)`?vipjUP7|%VVT;i~+E^!y0d$-BS~d0y?A z7oz~E7uRor7}yek6|DyYr1UW0(=seZ9%A)RLAjo+)1Lq+cTg0QqH9m#o?fDAWY{UW zxeXv02|z}SekP|NvbAkjxWqmPf$}-^)VT+uT1!yPxYU3`rIR-i4W%9CyW6e2Ap;kW zmX$+LeUz#vV=6?5*b?Jp%!F?9QTr1BZT+l@@31f{MM`=EpYOL_2QJjZxsp!_=~D9@ zXIoo2#`Bs>XqGj<1EQ+VU*PM!0ESiN87-b`r_m!O*M4E4#}bT1Z6 z0JOH63X*AfR-sHAm#$5H<@*I5{9^>%rd=KW^7$6YIF8e3$BC?(xjPqV#zrd;C&Vu9 zG7F7H*hL0yNx=OaRJ5yD9D;>-YKUxo^T|>iQ8VdXIeV--~#Xo z=Ydb-1Z_CS_c9AiCY_bpJr?#(WA-PqYf6`qU76LI-Cb%uYg~ap#DU%>q~s>;Tcpm- z-$=CRfs{zy>T(kK31GSC0uaSY?e5p?$)z6P?o+cwmELR|;?O&lIv z0Q6bqfX)hy=KPwlUI~Gh?Z*C(E&5ot|JI};*-hNA@18q%2<#r3kWgbDG^J{0W8B&< zJ>zHw_h{ry89rKbMszNosXTTGwtL0;TudLqZQ3RuoWFMjY3lBWpJ)=7w=$LcyR-GG zWd7gZgZaPMZ!k~houfif;9!a))lqnfG=jZw-mkWm1o59HqsPxoceu)X)7n1JV_azd z0T!4aCox1e1Me|x48~06{-c%L6vD!?Wk&;%4SHC81;V!6gEe<9_KH|jdB<9dy7yqmr>g1}P zu^nf@SGW&QA~6`oc|7pSZ*dMeBwu$UCkLh4&rAT+^p+rS z+M0(+y~wB7VmhIL<=8TCnkSb@}xYf`|UM>iK_>082;Sz5CqLH zojT1?s%Kl7D$Vds#V{u;QCB9#!ZqtShk*FhsI@>PGXc;?RL>x?-@(ZdKSD!d z5NTSi!5c_(A2*SDaR<&*kahh=wjTwRNe(GO0u5I$xwsN!YSg{kQ>UybHtXm7RM4b< zhgb4dG>8hvS2IKiF(So$LZv%)gQoXgR(Dn4sJp=1RmTU{RG=@CJtm?sfHAdR1k=*b zFJRSF`g2Wr)0=>5er6BoQ#GTpo4L+idH3x4X<<)ZqmUTWygz+3iOJu@*dM{zZ^W5_ zNWhHz4|9mDq(078j(XEGDTGVToIPGnIw>Qz>&$lmZx_&DbMtR>WX(l&JaE|8yjPfA zMegCm$^53#VENl#i_HFe6HEOa+8 z_Cqr0EIjF!^hhowT#*O3Urn|_%R+AWIX3@{6AET00AAGCGP0VuPz=gjVu1p;LQmhG zIzSqt2V#9ty)K-r^Fh1E_w^R`3Fl;qEG_R5qFCSU?4b*lIlO7rePF?$$oCdB&7lA~ z*fRDR@~;NGdfOh)dyEH@A8!?kLx z#mwo-1A8ZLp|EsSGiGr3Jq3r8^6O_7-fHb~f}8e0OHjfDRi`qr9uj-*a`4SE!D99T zpyR7dzYZ9Y68PoIlUa2p2!NAlBxvxNHFJ_kvU%8o`0-$ZEtpFQ@Lqu12W59sNP87G1=p}=P&psd}gKv;I zbLwQ+u+2Q0b)ycGR$Fv-FX8j=#92tHvNVvLkQGGaW=y9K!3_MNtX%2Hz#;^}Ifn0twGf|bXNT1$MFK8i zu)bi+zE>Jo|69iG`cc+Bwk}uTg`?JwBoy_}O#D$Tud1Y1(3!;931YhXW3|b2jBvWS z?oYXU81<{)ASgepQsCTx$@6#U{RGZuU&5Mf$(CpYkQ0Tm!Ky<<@$%2{LlaQ!#Q!g% z@l0?Jtp|iy9+l!jugW&ttj4GC9WhbTR?0SfH;n5w%IUjwl4g=juPP-$P)oQUb;e>< zaNeP#7jl1ve75*)*?aG})RcdRs=kGv=sKaRh)h9N4? z)1&kkC{G7~nQvBy&NI`>3doPoWHEXLA_OdlLTcWC#mHo0$d8h7<3d}=!W95d2xh>^ z0?0^WhdCJ3f> zV2p^Hji>`0i*fjg%igfMD`3lc7hAGYGuA`Ov_hH-8|A(CR(bVRPTf`_v3>dOVCwoh z`%*s-XQG+e6P#I|eCD@bsX;ns6(`XrU~mA`RAf8l~3Av5#o{v6w`4@=fB-jy#>3 zuSx?;p1?9tjyZL;I3@M6dUagB5wDkFyAU+r!5gcH$9TM$zbk!8Ok#;5bi)DcB;+h0 zhnZu3z+_Lyu@A?P{f(IVm)1KgkS608SfaEtYNqbU_@VI*_e&yvE7*J`v&xPUL}^p> zJdxbpz3hwu%QBX&UqCRdF$STQ+z5a|WCxaexPzx`psy?pf9hlGG)a$2-_PQ#~ z-YMT0cpP0agX>RKYm_6XrC0>Xx++|o@b|%7gKA|-bLypR3i?h;0saDaF))oUO6ks; zxNY4n>aAb=`OduWFX%f3Fm^wcjb9)Vy7lSiuo4bLuZmT0T&4Y@e7%z=OjTUA>$CA5LERs z|B$+-6Vt-7GaRnm34k`}wbwR~{)Mmd(j5b%KjUwjA9#B@)P-u$g9_y;;`Rh##3BO^&GA3aAvxl}TbHpTxHk~Jl0`f+H zuL?HCdjC|ICw9-q)0=MCb3f@keo@$>r31s4syX6bL8rfoSCFI{xW#)H+k|4{=P)r| z1gr9zG$p2BeLyAa14ZG=d+)s!J20tiNoQ+4bu$&#rh#{S$g|G4Tc_bSoY@Rx}S3|0Ii+n znMWhfGM~Bv#(jwHc^VQ=GVa35d1M@`uS z>UeBkPL})PffBc4=)Zkfy){XQ4`e0`48|b>%Oz7hISdq37EC?qZeV7Sq31ZbiYz;d zrg-w34JLU;6ay;+*@Z@qUzm^4&z}J3+svK;OxgiQB1+=aaiw9EB}udsxtqZAuVFPH zu7IQ(y}FPp$XNUwFkc(<1``QxQ@cQl8|G%56{frQt(itfPNQj5zsEB3=fb@Fw6Oo zUjgtOT@^dh>5waV+jAEMbE&IoSKYfwZdn^9mP&90h2 z)%gW2eNd}Ribr{wdz{0_=rV)R!qaQCz5a{B=>@Q4>A1IZt@gBSRDK1Z^~s*2%yWpP zroZrf0Tz>;qoz4EmnwpEU7=)DVIkp%=38!4tWBRN#Q&6Py^@Iuor@(&cLZJEC3;J| zRIwrG`Yn&p#3drX0^{{EEBIfM2kAiNV*rY~L6e`;18-L?>KOshmekIK-8i8MuscOq|uI5=gqnz2!Uovpo^0vUT+{|@a(vlb)8-5Kd8b(N8l0-NH&+E zf&T(b_jSZbbhDkWwDKniF20k$?x56 zU&BFmf;{!qyq>~j^_&2-&L|~RH3QN4Me}@h?-e#co5i^v*!4fKer!he4@`JuU{Bh( z!yeo|Hs>{GuT{3{N1zwK1Me&8l&tQs-4S7B`i^QEW-K_cI&L|Wm>h7PAII+)5Y9+~ z!_OE0O!nDFa}D=c>3IRrSAVNwD2NX-(}NNeU#q$vFdqjv_Z*fCMTe3`(?K=LgaWX~ z`aY}&GZ96-?Nj(!j{SXWtY`$At5eJ5Cj3;BSVRpTUNXg7&S}Od+{N!)QtZ`j;uKsh zBS-dl7^>e!hc#HK>+z_y2OdP{O!DwS}CR{5@gvD7Q61L=PSv!v9t?kyasp2idU4OXQedt8`e)Y8;jooWGQjwVj? ztSt-K_3n^Df=U{JfC~vF60WYo{vA$1p4xh?l?DV3IC3KkOwsr0+rP3{sSmZQF;09s#9UH!Ja9S+-YWpD-C0ADWwDq_S-rFIT6*YH zEDsUj7RJm&&Ds$Cc@HL-A|{71xtLH&@9lxd^3gBq1XDJ;dftn8W`$D7bXNJ9z(wXu zi6I=+`5sYOkWqQywoI7QvJnH?N9=}8oI=+7CDOe5SNvZCoYJeM$(=v!_AR5jl^JWCctGp$PPtk39T4=p-h+!m*iz23WAWDTB5NLZRrz zExD$M{}YR>9&1lPg8ChF`v)(?VO`Orf*vjM5%n)b_`dYwnMKLD8a@`McuTA*!}!0F z0|0@rz#crDPY;X{QFs~{6e*m9eP7kA(`mm?DioL>tgCs%{wSkHY4l&OE8TN;l z^~BYbOt*RyB)kHC$DreS{HAZ9Zp>hJn9n*lm*4BawiHSvs-K87HO2Tz?6IqYKpe8^ z+<#533*>-g4Ne1W3Ytioq-|~!X2W`EZgQo#(3LtDp>oD}JCB&%_=&(d8rG>aAz@O( zWYSCEm&`fvU@>_MNQP+lq7r{b1cPu3i31a45)FcT%A}Pc-P3mjp!J2lWN>xY;ogT| z1~n!dwJ2>TstyZ@mN;*5sK(x|2_z5-$9&A$pYh!)+K|je+Z>NcL1c)xk{iMb z*EsgtGDX< zsfN0@4Mf^0>0O{m$wB?t4cw!dXv#pHVMalJk6X8|((?yoWg4~DxZ+bO7;rSds|C*I znFDrkL?}tA2D4kn^LN%nCVAx9Y132>gLCR)@)-r>L!5cH6ok0IfY#MZ}ro z9O1!!yQclfWncDzx(!w*R|DYhmv}Rt-I$W!s&7Fd>1hgqO4j`ki_F8AHeXG5bzk{@ z-4X!pbxjTGI3)6xQ#i==g#ElXjy*IqF4nWc2cUUbAx(8hAp~T4@q*RUWbomPAdx$< zirpa_G=D0aPf*g~b*8L)0?>A7YHDDMi<7*~YEA;h!}ksnuG~)_n~XTaEUDna61hjg z3|Oe3I7~oFmX?@Sope~ZNFLH?Z;xTenN2uwvU%w66%D2U)e<~9~G3-G-yFR+Kr!MiBvabR@0VO?$+(=|20*6jQ z)zOKsd_UcpidpgPGf>;#gfZbQc#o8eRlV5jd|7`4pyN<#5KbM~bde)j^&sprY60mR z)}ti73Be>vF%Ny9iQX;4M@@%XUNQRLgqKID&NY6z>jV@@6DYd9aIlq!#Wp`6qbK6< zTmQ=XD*&xytt7rNGaP5m4-f(ZX$%mBP7HRvVP>ca@;wgrZ_pUv3Ve!STwZ0Hr4am( z>nK)71A>%}B*kivz-ZK%F_r8LuZe+(Y=@onZ|iOON&s4iKAD^YVMq)CwxHP$VK>lF zKbxAmCHK=NNoiutG}=N=tmgS*N|sA~eIrzo6Pfgcfx2XB_jWH`{kz)1no*6Wawhnv z7b8*NE|%|)SE#rK*sS;ED*;G11!hhk3Co$%4(bXEL6rf^LmYwT%e9^fF+DuE^D{Kp zfjXoVa;&^Zq(fy%6_bOB z61F;VVc9c!fPGeq`adY!Zma6fSEY*{_(}kROpB)>pZ)qq+e)GdrUge6a%{vzBP)%K z;7!HaLY%Ays#uFqXzp7e*2Yz+H32S4u**c(j}uwNgkR1oth6GaP;HYq@%N;3;wR!I zA74UvBW!Sv9S-vJJAm%C=6cjL)7EB>5P1N-52*VyzMsv{57`42NFw&Sl$NgBi9Uji zTQ}E!B>-V`q^eI-rbJ}G0J1E`qd1!kRv06VjliFmC*I{**5nm2 ztB?dWRjNu;!nK76helNaGxkWXNaEqnCtS3OJiANLSG;(L}*kdqJpRwb3? z?@?XLbbAz+QY8Ws0WTnse6h$P5s(NNi@=H%mGs$X<0znwBNk}Dg1rFC_^}W&rbt2C zU;w-a6X1S|ulWTv9M@fBJH|a04p-3dH*&l~V9Uf}6&Zp8ul42?ykC=p=XLn`U3~vC43C$oVRjf;Y38dZB}fF^jes-&+&z9$dn*xWZ4J=y;nftN z7V@!6Ao?%^#bbxeH(}wufhtB^M>A&hl-xGwj9z}Zg4V35qzQov+BR%AVzDD3;|R3< zIeb-@EW`N?JVexcK8@OGElr=k&H3s|4J88BAs`I^>#&xR+=RfgW#cHeWf~UCI_xwX zvG1IR1$tj&yTD&Td-qcX{hJPKSyocpsydl`y$52)jxP;91^Az6Pkf2pyDUiry72V} z()WBMfcv@ON$m2cTBzH z;Zan*(-k=8J{#?cUA%A(l%Hk&117E!#A(1mRM#BV|Cp>P5%3lQ@}=Re@szzO1c9!u ziPXDw4(_~pEFfhBQI%@$*AzMEUW#jnz?D$zNa!~f`UQ0MOjau$fe+!^aXHmA{kim}WD61j z=ObYJ%g_0JmKv550%8}vY2DGd$3GW~s&IZYzA#!1Z~Z%|I&eGf-|&HM0V~3jXiIEg zm>^%k!gDH)^R4i#*R5WeS6oY^T~AuY<5XWSA}|U&y(x3>WcS^HfHVNyF-}s;LJ$Z) zJ%)TEzl*E!Z{o2@_!4*IMwcyEw6CX_?+}b5vO3C(2 zK!DL_q|wW0`3kCUe#!(1vPp@6EeJ>hz!uo0P(u;mJV4>_H1ccbVNv~NU);K(A`*=y z7lLQtGw@@u@QDRs@FGI+Iy!cz3VvupC*g1=i&qc;&j7!I;(?_w{x*1}Q?eiBhk!Hy z%5TiQ)8mM86!!LFM~!%VGl^;V^Y9tCmWGXZE^mB(SL9HN_u{(2cQEeockm9_vL`tZ zz_kF6B<4na(?2Cb5&^d%APoSwjaWJB+txN5L2rn2_g{lu^?VbdK$sZ+05X0?^(}uK zQcgHrO_lLk6yv{y5psx$I?1M;jsT;3sh3?wO-*1WOfVM8A`x&j0@46*^zcaKaI{}R zzS!~DQR7aZ&junUhQTo``usK+7=Omm?%RW+&$*AH!DF%WI~Ugi!m-c{9|Jk~?nU5T zEdMuCFXmE9%SQKhLu&4I1f&7r^$~Vs|HJ~Twu8ma{}dKj!DeS>5#HUMV23+w$opJz zryq&z3}fV0?DRixrb4o9Pa*I&jDgeW^|#vSwprT~F~>B}5Xb2n zToJrut#Bz#B9I#aGheb2bBREH1XipViO{&;qT-iv{N9)AKL2Ay)`&yK59p(Hx6;Ce zLnnq&m06G>jDrbyMt)9;1YACr0|Aa`66X67)ipjL@sSAFiGX~u*@=F+%I@kK0SexQ z*j4`;Uwc>pgGd5%EqLF-@jpaa(Kep8`LD;3?di}!NA za-XC2^j{>3S_Yz_7JI}?spW`(eA$)bs9V`*aeTfkJcDA|O;}nFwLo+XGM=FdWXd~m zh`ZJ|TZhr7Bj%#+-H0wQHVKdgos=Rxi@>!M_x+g~8(;Hm4`s(3gMc&u95WOiR3sdn zk7Lc-E%4+|g2&iW;=Ny?y18!+iKZGt%svQ&lF4>tkq9^s0Zt!cK0iQpP3JpLIjNCX z5Re9dS4Pq){Sa~cOj`h|)H|V)RZMsyjBnwPoczJyPE_gp9TxpBI0Y)HheSXZ0-U!J zRh*5aM5}bwmz5*}IuVctfKH%fH5~{<+Rp+f&d;#px8_Klv6tYX|8+R`g$LEHGjt+p z9O-pwhK?S{DiQ%FBe04%`!Q&T|L$ZZrEcy)KpFt<87pUMy5a$3xSM(~aqV#^XqD&u zCcFqw!i(_9oS?ke-p)TqS`raPE$_m<4gpk0pQGWagJ7s zGJz`S&rnG4^ILVtFOsQlK{UZBR5$xk$jxL(i?*LZn(t=3@J2ZYD5;4=z##|-s$m~L zg=$-bUydvifk6?F27sI#*$4>oo@l5ZfA}@NaJ+6|;k1$b>@KRw5&s+x&m&*_L1?qH zg&Ijw5&^d&@HUL-uTkyn=iS-?skgZZNCUuJeBIZ2r?NM)mi-rsPqtopei>~AW8j=Q zTQX#aLOYY6KaL%Lt@S!di4pa%H9lQ>P2MIw+wKpFsYG9(e`Ql?UjKMe2s z11*JwBS9*sdx`w#fXJsiL$)}H=n7o`gX9KFb&|p)0-i*GZ6F@|64lRn%9Gubohlds zX#f-qnFk+GgI6ZQ`Iz6*-f@ajfFDn@THei)8x2lJ$lvq0{@>M7oun{{fY%Y=^a7{D5v;}r~hY~KJmgpWj>Hk`LSCS#;TPDt3DOo zUW>8cBMtEd@WbhKdsn3X`Vo)@fPSppU9+oe1Qvd=yFSz6j>PcZzl!QwL_(g-5{-@} zzU?n~xgT$_PEwqq2(b6j91_)NZ(yAUVH1BHr%G>vz-bM|{GZW=4WH5c`CAPW+1eVQ zQKQBZ>jm?p4;d#JzSqR5(G+|?4MxIVkiQpx-pMeT<((@qkDUm0Plv|iouZ}#^@t(8_6|4=*x*3j zq)G-NAYZ-)g6X)XghO3GTYz-9f+yelvEI;Kft?>t0Q!}1dovQ4h_Jrdw&>)zL2{Hr z?a*ctc7N}|SX_q1@&)RlXQ-*^Lq}<8q%upFPNWfmxiAP?@FkK-9e}Uhj1=M8wmADE zy}tTf7TsI?TJx=;vn?W1o>9eg{Mw z40UMZ+)rx95s)YRRSv_~bbOW3`;$LG8@3!T4MYQGvV)o^qY3OF)Xh>Q61*NS;0w{b z^}Bx2r`o0p$j?0T?+jgy7xg7J`5%~tv=iI?6w473B>5i3{q4JkEcPPJvJZ=$hA&2A zFovVi@saovNth~}2*LoJwn1;fF1b08TuS^;Fci3NC9XGC;c9Fd#kX`))4}f)+?N$A zDyh4BDsodCjyZoWp5MRVHr)0ABk*_7LaJ|G>^9YCwk8qD70+G2P-N$mkL1 zG{TfVmt~{;Q{oKS8MS{>{p?o?h9Dfq{D>ckBka#(VXDFNd*f?N!R?gi1HuXJO&CZk zak%y*jIRGsW8)inp%6~Eyk{Ts2adtB;*>yKiFl(V(skprU)OZGH#$_Fy^scgTgUy? zC8MajLL9{j&t>ZiL(cJ-uMsc8*HXg8BE#bMVDZoN0kB>>FGv(|^WqNwXNb!dDUkIS z!THd=ZbuqceGZOnzm+(?m&FVOaHT+C)2z6eH0|T8WLCK(E?*APtIg-(v`$c63*xI` zW+-N1n`_A*+n;95U1On4Das%Oqybp?I_9ws$z%XB6!+s)hJOQN=T71xPQRhi<1f>FO_C26`FG0@kOqKdP#Yjf zaP~(P#A-9~lDDIPAOzu24aa4s?Og_Eu^4~B4uxDVQ$$V($F!L5Xq=`j&D$TbXdrho zLMj`u*xY2}T*#|x*;iofFSI3g4$YnoXGEQ}$7%=>28g6#Y?S-_2l)Lst-|I+XJ5;H zg4hp$Gyv=$1AQ8Vm1E#s^iNc-)c1hVwb=c%Ve{9sC|#q$-{5Zg0;8psL3_AUX4liG zad+n3Idyd$K(Y87yjVXETto<(5n**@0I`F*$oYRUes|%z;2B*J8XR=T;p$V#&v0G9 z8y(b>e5&+PoS#6AErRny7KbAs4FHD^P(nQsgB%TsBpvpQ7fa+02WS6)5)6)}N+#(- z3!6iKLzv!KdGCv(!SfNW_9G0wxWBi_=qs#avbHV+1Z}e5X!rxITKz*^EPKM4&=<#P zkL7thbaiNuN^Rf+nOjN&@>%l{uxCLrzhB;vz#qU-@8ln&GvCG1Z%?MYTG08jfpor! z7m_%QKDc~7`Zf>kz~9|36qG!urtf%vxQSyYoAx#WufQ+l&)|2sm1fM?l+o3MpFr#j_;}uq z-#gT21pY!j+5yzk@~*ds$vwT3FLNi2RYdv3w!40TgP-p~vj%)Pqpf3!j|gLjG0jO( z*{q8QgM1p!d|w-a4wb=ia~4iaoPsGzOMVLxQA7 zu#wo;aiN4FL~xt7D~y1T3CufR#@-5+PA}Ik5X;p2^lfG zUD&zCeXFqe%dj&s;GABzJq(>EvN4H3HUh{|!0)B1 zE$7pW`2$Y{b|HWK0?ga9@R+kQadQ4Gs&DzD98h}^kOqLg_!EVLSAqFWc>3E{IR8C9 zjNeHqkZ>|m&VgRPvrj3Wauz4el=P)O_1EDMR!0I+MA!%vSP|ET{W z^vf<*zrLRH)8VCicM679II4}Q{wsd|vR%+PNbaLJ=KnrkrmqjGld4W8)_WbC|4zh< z)edTA2f-y(aR>q%u+aaRcwkY^E2@t6LlEI}Hgtv0fZhHAiKvH@kV?GGA=s6b8qxr; zW4I%2dm%3Te-Ldi{yzUvRMYU^6a<2IAUav3^>uh?k?DiB3NNI+hdkzQ#g2c>aD-{H z$);-~1xN&nMZo8~gK8Sj9Q5&M5bTn^f7|hd!58M zI|YmX-&0){*AYa*7%0Daz`=A_-@G{I@T=;MM7<(=+f3Wt0#+l? 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 W4mbZi(-wjN0000iQ{2@nV+ArO*~P(n%QB%uUC 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

`X2Jx@oi7NZJQc*9QX< zta5_5=d+U@Kp)SckC5ziilhgQDhEjEdr#*Y+?0EPuBn{P!?}@%;@8Bsn62zQDTEIr z>2RMZ3m^`iFV!v5$}a&7Jt-;oOb@hV6!Vdxq`hjduw}kT|Em$Mw^>}@lQhht0T7p zU01OsTWAf9XBME=9$Isy6c75jG_K%2NL{ik3)s#NM39SFITTEzIO3j)de0OCd<8(B zoBJ%qR?Te4Zeo`*CLBHFmLg;%duI=G8kfmnaTbhbKGQfT=hb(-A#RZkW+`s6SVmV z-md5IcBx?Z{gOy*B2M#uoHf*pwsQ-}zc>4>Q9@M+@(uh8&f9>?>1bl*py*;z8dt6d z#npif5%oGZ0{y}40rGiFS45p?zh!|GK|#=1z?SO%m7Btv=a^J;t*o0oOTLJm$HbmV zUESf1!4~;eO-pwiLzx2OKXI^jb5N%cwx8mh_m zcLh^;0RgdR^Yah8xRKRc7O+Y@BJt#9GG+?8-5OL9)w{7mVk=f~zjvVQy<+V{EGWO{ zx&EBKuu!$N@!PwJEczk4VWb|#Xa!nViqy*A)A1h#n?-vWFTic$#IPQCVEEugS&&lh z&vBA4iLtAh$b-75LjsAICqGDTAFt8~W6JR^Dp9&E>BVk;Yh#Mn>Z^a&E z#Z><3)kV#SBM2jF9+|c=H#Ifk{R1Y@qW>nIUq_tcec{c+H0$hy@B*tf3axE>P+h{` zzfC_TaGv=s-=`T{^@WK!C&}2dd!m}$=mfg93VqqVhk^R_0x}?t0|W%5gy1f4&2;2) z&_V#Jdk#*G=TTSGo2UVzZOiM-?WHg!J-CWlKWGbnuGa@Ya`48IOm4(7@>H(e=uc3Nb1 z#k@tEKf;;BixksEPw6PMe2Q~vH@NmNk!D|_5$Km*8ZOQCu-SWYbpDHxOR(%PIAZa_ zg-&rw2JSgz_(ig8k#3Xi!-*_mM-9y<$<(PDz#4tI2dB|yo9!n~N_Q5GvQhJ3=XTPp z1nLTZNSYfjlk%PBMc)}8HMYiCru%4R2CB(=!-=L>QcFh}R~@hao_oIK-|nhKwD~Vx zk4Mj7-$dN+(Wa4}xSRC17+af96_}A3+L#|RsmPW#p;UK2!VI{w(L1so?M^)Ta zc9^IvuvwL81UgZvE93Eef~XobL=f*Qg+_JmqeF}Wo;t#=3gQ|DbTRj@Hs&kCrooh@PAsW7`@hTak&A&v$LJS01mCZw`*hzu}?VO~^9W91$^f#8h)(g#!xFK9wvioZ)~ zIVRieO7;RhxB6&0rk=ncA^A(;nAio+zq)i4z8QQ{4LlJaFFHfk8+ik5>qMl-V(sgI z(~pv}DRZ-%nhtk+rm+ULOmhO?sDmckU|h9z!`T4?YRLq(?BuT0)Nr744`PN+;w-Tx zsu>(0Ii?EsXb!CES4m#o8TxuhpqZ)zG&5@f()XDc7F)ipRg!_S>F?8wS7Ls zLMHz~yg>q$M@V#wc;A|j+<$&E5*PetlQR}wF7fTpGDBYwuK`P3jpANmGN3)#uQxZJ^$t z$@odv`Mjg&%j#wh6L+8zS*kBUc}@C;Yh2*v*1R=B*xf@<{AX39c%mAlo@MNwg#>l1 zU^-L_Uxt~Ba00CYoT%3AOFeqQirRoJ0hOXCIujHUx)K1)bllTL5_j%y(f>$w2Fj~s zqMn>{SJF0ib)gf`8&$+ihwi$VE#H3c?$91fO@=gL=rmsVYnhvH_WazwB>nx6`Rakd0CLf>8`{qeCGR5UWO}I3rFk{wsA1`ZNc|`3rUn^0 z16&8pQ|ia4A~};sWkHhB!U?R>?* zp}mGmu{T>k`W5LW(rG0o$=GuB_(cwK>2@M@;;XB-#mocIR5g)23HyB49*?`7nffPLOT{ zn}kGS9RyNI0R6BVb?gT^lUxJN_~n336ny^9PZ_A*r&tekEDoZj6Q1lRM~h<&dlKdYy|dDw4d4xi~!V86;RQ@_)5wwj&!^@sMj}#fnj=b@wyITX4_cfO}rQ z%UA*kG>0Jv*KKg!ms?;6jioLpX!H?&nUJwpt1r-C)A2k!4v+?hPxllVF!ZL#y?+5Z z)b3Kx+EWQ!)hH=Vl;s*$CW3i8l-fD_d5)O0im`?k%(BWSSXy?m)Kw6tXo${deoM=q z_cLI>0<8~D&0?J=Ia4bZ_WGE!D?0Fc@TIBB;I}AF<0eo7_wl9@U`zB#=|qxZ_OX(V z%+VAW(G?eFsPW~;t*TIgPiqZ;A(WJK!923j^(pT)*^5y>F5-{~futFSH`Uk9?oXf- z38Jo>V8bz*_8@3^M&bkT<2R6nN<;O17GpqP0h+NMxy)QC8hm)4S(!TyAyM@{FIttkBTl#gO~Njg#myslc9|5@fcmoBSY_Lzdlw z1JK|;FU;EW+DeU?Q*Pxfi@6GV;qxKbSs$m-zp!>_)~~*T!^m=Mp>J1U)1T3&&(!dO zOtthZ(6zN&z*_$-)nw)d?%0yT2VHvrZt8*jt1GR)Ez{y5DjsyQG%VSNNQlS1NQk~( z5|xVY2oEgMJSdKHr<9Z(jTdrj$Sj}gWprGo8CP;MMFtX$qv%O~N(ToJspI8Sj9S+x z#4cV!_#DwkJ(r#Zx~>9`jUfgsL@}@oHQF-Li~Tl`^TC?Eu`@p|3I-Z8CR#XUh++7; zWp4EkFexfMaAp;*s|qdFi+J-Hvg72>rLOW{o|!6aUA{UT_#%>SYT&FHRz|fF4 z(O`pWCLAXow~RmL?Wi`j5i+wD->CsW!Tf%A<_wZ*-h_i>=S)%h-9G@2Ewt*(me85N zGr$dZNYQ&INz*2;Q-|N&+8?q?5!aSSY(|)ob-X9L75WC$Dy%tb)2;yc?xYWcy<2q6 zRkqOUF}dC#V~F=lLxc?xFEMs)Xvs819DI8&JFpT{x@H-_zbz}1HS*C%_43+lRxY>z zrs!%gKbTxa#i<9oGH3;4-7zN0a7^^0V$dv&E!&*~LJvfFuGiOlY2CeDrR+e}*V~9qu{vNcEneyOcyY-dyV15TGPdqV5))@{`%uO0-dPRZ9*ZUK_Q+kb7U70f48;7 z23Go1H#CanB%BFKbL+3XTrr9xNrCKGjxLus6~z#}0(*TDPC2tR?PHs_`r-yX1g+q( ze5m~Iid;xVX2wEC3v0v=-X+Y6V37*tw#t0 z!3;nlu|eWSyJ}hS7`U=wqg_%zSB4EB(p)f2lD;_z8IGjzOH6*Qs|LCe=!%P(WV};h z(+flA6^s1@K#>A>{4kGl=x8qY&9^*j7E#3UtEijw7Uq7ow98Rdlm;v}McW%(cqrBy zR$;q20z8_BuujPN(UAZ1F=ze}U6iPCla8m$e^Ft*4D{n2GHB2uS-BMbJ*MNEj{wi) zWhEOHL9W(iu|ZEZ&M=6}H$hic2a@ha{^LkHkL^?D@EJ)qUkY>5JCdwtVSqcu5H#(p z*vBNcVBa7%zK z+<0O*OhH0k4NawuZ_f*);5R=Bq4Z@u(2I2GP&x~ATHSb->%wk<7AxfD7<3M!2F+NN zsh(!y1GkYKCyH{Vbnm~>Mnzaq8{^7%L;CkPk8{g-XeJ0 ziV@hM^pF>X+=s?0Ll7bLR_*Si`D94X?6be=%QT_q4f59eKZTrTq{Lk^Z`u6<)sX$g z*!1CWHbuV)8-%*53;H6=tJ;!Lp)z^FxPA%kJC8!MW;vX-3{gndAy1^Qbkki%_H-f8 zm8v`IsuZ?-&g%IMSmz1UL@&-<9>#2?gf0F{_X6Fv4)rkUM^Sr9?$Y+V^tf9Yf{bx; zjxAQZylwuLr&c8@f5Ddf+nl%AZp7;7Lgz1?fCo}JGa@SK6@Cj2wTjir#^y}0GZ5ie z@eEXuTX|+Z%Y;YH85_}YM`{FV;0yp-1w2;5Ojc<;trEc#PK*% z)RXAHc<8@oRXP0TIrLw5ZmwLy3Um;Ob7m4`3mj5&yo5q7hV31`0DCmn0e!Z)Df22f zWwlnkdwV*zV6Ca=@jO}4bejw+xSTaeb4GUWVO9jei|TNx_=DUq(f>`oc_sWKrDcDVn%Uc+<|xoB z>Nv#i2dA`XHif=9>D5SA=B`@QOlLxzWw;Q%)*8PgCG!Cg(!7M}_*VYdgSKGd`Hqii zYY0H-9&8xwq4l%D^RDUts)hC&5#R%(rFi_!r>o zn8kB0<=W0BLsdJh1Jlw3W#ID4YJpZJ%JoMo;EVSDGo= zwQF=iJO;DkI~?HQUGZ=s9gCiiE+CraH?6*i)dKwnw$}Or?7_b5#@+Q*?TaL_0sHJ^ zSm_lC*d*IXc|diewdI;&=@x@D03 zHqrD;GY5Pze0>=h$L#4UiH!eTkX`rSL)SiLVNk0-;Cx-ty$QG#jvM_n=OTr&X<6?TL;|DTK4rd91A@!u#8>bZQES9T!<2)bFBp zIu5`t_g7h&gIn7-WXv+yr`;4Tc1KfLw83cuc`YrwDlO1+EBB;v)kU)_UamX$Oa@WW zLq!Uzz;jj}HX5dL)oF@fMF?ht{K{_ZVj5)m%1vaa|16ZceV$=CnU-aRnQyo9K1j7~ zWb$Mv)A~@E&myzb=$TCOkN*kp=-ouDs0A&GgYoT{^3Grpfv+dZFYp^U8^)EZ-#@xCuS)ITH&bC2IFyjxv0loyldx+1LuxC2 zz$&7E{aly#CDy!$jG5Z^OqZI{ZU4Q%SQzEG{x3Wudw^fpIf=qcs;EUJomVSbn@D@} z6ciALrUkmT;(J`+KU$>wM@5;I-LfxNZ6ry10z$2hn`{C+J5Q%EA7fRiC8wTgL3FnP1yeQfXpKC#A5^T;sEwz^~vui7wfD)KlKBzPieaRXe5n zD8#u0K~$A2f`Ze=<;8ZAP(P^bdO;jhT6JjEb&kur6}58M)Olb?p6#}-7>RzyOzg=D zl65yaRp13K6hX937FDrqQ)W2Zl%{f6n+aFI3jlmpUa?S45gcmd9aiCw3H1Fh8E@al zB&K{7-Itom1Jj`WEFDvsM}9A~!pEa(c({c=U*@v&yDdAvsvT+!Q1Z>J;#FHlttMZC zb1oU%fMi#H+1YjwOk`qv^22(aUx0 znrm;DWeumuFtVy?&T>qI(F(N492^TkM^jxRy{vqU{!IAP8dPfM9E@J5hv3}4s0OHP zNttF)$jHFiXJ$8@Qd-G2TP+(;pvi$@FHkluKhfQphVmIIinSWG1EGxhWhA?rk>5ihced=mH+db6+iHgw=S(sVD~sY(`e&)FfY`>1Txl(&ZAy3c8sE;J9!V_`J*7S}{#~`^x$4v&vq%tgcGsp=~g;vi+ZfM_E%@ zM39%p8`aP7Le5a$z!sH5)9p5Y7SVuFT?)>jJ~iF74?Qv#Ao|3<9I2go3g%UBk6NX+ zRXFf+R#=_o`~4zeQl=@WsnpoQzje6mIviGif!|LpM44*v^F7%j29qsf#iOmYX{Oj{ z_|EhYW8-@QaDR!uZrrXnhKE#At}$l)wKvn>O!ekF_z7a+Z{BNH(&aG_S|Dr~$75AyulVYiB6^@w>ez@>!aPr6 z*DLgVs0qeHC#<-RX#5gIgNqb>h(K4>%6iUD@<}s?4@bj?vM;V>g(h_07}5^3E%qE< z9;Mjre?{XihYq}-ab+7BpK0vZ$dH9+%F%_ewP3o* z(HKP(i)&Ap@e{99f!3AuOmbFSFR5XwA4YL{U&?bw-5`UkX~&g!I|7YR^s|!itU#J; zIy}vA#vv0Ex8U8qVfW|!k$fHj-lE+t4)j`M%lzj{&)8m`F6fSt%aB{fC0gIW{};u< z(3(FG(|MK(^h$*8K~B|2OXD(D1v0s2U%(Zcqv$N=J1?VXOELH1C^$6x>hoAb-Aq#4 z4IoQwJNIqW9nf9!7#_&KIn$ia%0&X7PQ--RZR1;!9#~na`cJ8=>INqS)05@EYlse4 z+J|h5wYNg(PSkgzav_tqkhgzp^fqv+UhcT;iian*mjaUihz?)Vrn1Lbp`&4 zZ{7{pJ#Y6{fmUoPK%z#rx?<%IQ!0S$S%|FsM@-`p)Tw}_Rz13gMu{BhCq?0*w%`$7 z_>!FU*s_=u+U;bAiJxLey@IxW+I?HVbKRBu%J`j$uIVQwQK=+~T~YhuF^p|V2o>L( zEHbXGnuk__u29yYgIWH8LdNc+0mua-!S{YCvEr29FaRZ3Mb;uqb&^9(fRuIHjQ+@u)=QM^V}_x+OgKzBWdrjXdqtWt2d z9sjBox|PBJ8dw*imNqtx%cxTXPLgj8ynE% z^5f8<=deO})LrR(6-!q99wt&HTg?9C>9qs7>^b3w-qW2mH85tTh^ojYHFSoqDS@{oEUBcd63Y_vY}h3Omz(6F$9~Z3e9%30 zyB3q3=_#}?IT~ceW38)vix;mxq~v3MmDFJvHnhht*)>=97DKE?}O=4U{muQBFYR@I-tg|`I{T+MXt z^MwSfSRGjR$na6e^*M@zL=`(dQT{ynfdiUn>>ZUlHK% zufEIPEeqcNu57W1u2xZCFPM1uKm_``X@((i3-wKhM3R!i$54G;lBl{DeNXN2IW*Ie zOwx5m%Oj7ZNLc|hr-dms>!ORo<*fMGdw8?%N}CF5D^F!6m5H@`8~zYf&}C|nh``F> z09hV8@yS+R4z)x7wM}=@`38%Ml9D8~f&@8%cRMSrMo{gFdnZ?X&Q>!{%E~^7at=e) z<>}3p>>ll0^r5QCaFaSkH0bpY*!mR~s?L$C)i{Qm3A7ts&kJ17?x4MMD#YCINS*Hv<&(7(1`v8|fbdq&3OIQJQg;qkj z3DkcIr+iH;)4L^|P+rMUqCgq;Fcv!>wQC<4vHpj$_%r2AZUfqiWC}i%Wb^befBxLK+%vD zc5d^(IL4;;IwEi0ymgsZwULkRep>7zQe$sRsdWnu!K=+U zCi^4QyC8_VMP{pC!fhs}0se;$42Go!xD=-JlKD>U%_gOs5oa*2C=R|oJ(C+)L4G7v zv$m9iLfr{-h-Wb`lZou8$WwjYtC33lAIG86>cO!G!S~T{8)w~W z0j-_0ABVQiWYn%)Ess2Qx*V|2?FjWzkqEV7e~ny262)Ig*~D9XbUFG<=2rfYs1RlK z$+a*qKy}*_#{IXYmPnMy2)}!n5@U!2Dfm{e(T63f$Od71b{1LtH;Kot;u!!Rwb{Z) zk79+^vss%JSM&W9nRn1}JEl}vihA&WTv>$!2HSMjIWm9^+6%?8pYsAulT_?`d5@LT zmscD}-jy^k$HmIY90b*h1UIHYzKn;U ziFUdu(Ei7YPL$+wKt}O@1OwA_Rh@IW3~2m~eB9j7?tup#PLS*8R+q7A-NzU=402nz zYk6r422GS5c4*I)?U8^d*&gwh=0~VG?5BPvv1ND3m_5}?ncK2DEpkuo5WU{`jh28C zb=_xiHnVrgl7MBiq-KE7`zb6; z>WAq*RO%hm|ndqumT)`Qm-@t z(UvsJJ^=)fW%nTZUQ+)Qx8Siz59Dih$}Y&~zQD`y}#drC&=c|5k&N%8n9W6HbNmlAJ=-_wwc}U0};^i`zNkh}US%a1|^rrxQ(aI0$OL&zi z@IdT+gDjmGvh-Nm1?F_fzDKv@SKn{Z1bXm9lF#@!NAQr9=f|0=tKo%Fh(;KWzJcxVfX@q z?$d=Y$_DFZ$%q+FUw|8=}T``0vB&E0sHsAP=i*NfWcDfGQ1gZOPw=&RU?0w*1CS+H8o^j^<0vE1@jA!1|cc;N^$W@ zxFgQwZHEfXY#vgmbON8pPWc452LwCWjIN}ycLx5w0yOq@vE`PKbzmIrVqbLLEfR*h^uVFX9PdPk{vyj(z9z#4?SLSoOIZy}$h9lG z^L*&bytMvzq3!89-*uJxkQKa@zg@-elhx~#-Dzq4v5ZmYzI~~I1m5vdAp4km0(AaESVJ+xwEw5+3+NAj+cvjT;;>F6x4k@!5aN%G4(^FowQswm~SBNr$B4&L;e<=Cp2v5pFzd z6pQcz{0?)(4181S>rpzK{k=>|;_+tm#55GV+kx(Ya8L?aDSEIs2da;Y)9KHoGj<2{p}ji!<(_*AWy_6u@E(P4 zz7M!<#)F->nJfb3OU)t{rZh1p2f!Gh5k_5>%mS_6wkZ=w2kVf1@;mSiap2W zVQR{xy(b=e-yGe0e`CfJp+3gyFLZ%ZG(rpUD%mS?~dqO=L zeGv%hSGiaWlVWdTQqRiT`QvvUYb*YQ;AmouG7)lxZoMrr8=eKsN@6+&0EF#b|GLk3EAu7NpHGh^0z(=QKlCu#&<& zd!m$2>e@@$rmkQDtp~%o)ygJ$Y)&RM*dX(BwW=8gqRHW-e%tHpMAg-sVGUB|))V=J zLpXLnYszYM9u|#?PFuRF7;6oqTZ;s<=j$cXjm6r}K1yg09ZP5pZL#sTn;Dw4!1|#OlYqaAfT@ ziUA4cDK#1!>dp}-e!c8CjsWN`4q9p8l#&cx%=emCP|#A7b_3o zi9Oh_MJb#>Yqyl#usE(l{hdCGKL|d3={u}_19KVFT4idM>bphFoVB&%QqW-3gpXxjK!++;mAFBt?bk-;L^nYN`9D&(iPrJ&%9&Cl^n_{B&@Ry}& z<4!}qR&h`R))Aw+@ zyikqwAorXfvFqT)`U)2fTibtsfMal_D9}G9J0Z-PYbI#2)OwsK-;?I#n^IVmIZ&hH zlq-tPO&ulUCfyzMX@nDKZKby28cxT1v!$HnrSyI0onlxuNlb5l#CDgjfYhMl?QlI< z634k&+~%wEMs|~Bk8^gr@`c0+r*q{pp5YQ`+K$5Ka2N~J@wDmJy`Ao!v9n~QJz9z! zQf-F{TDX}w#~*~TEQJ?nO=V%5VCJ{$GYLmwR(Zg)O;=S7=S+Je`cJ3un4CR~P!-#G z1owVVmV^9i%WM>?t~KDMx+*2(RR2N|&+eBT0#(KMNr)X+9W)d8OkuH5dv#DXv=*S+ zbiA?c33_}^ad?6DqAaRU=54;3w%+8FeZs2HeYKSiA9OT282)>(t3m9RK06-rGF2~> zrs{5~Z~m?9wA12{^{hF!c~SlbJF_8T2D`i1KSH4R8N07i{svo_)3JwlKxTg)y7vrT zjG#2R%1(PE#4-1Wo#5~Stu5Bn3?%lD6Ra}j*!Os=zvBtD9vsJvS;1<(9=6h*`MZ*w z`;AWwJC;oMeL)||ARu>fa(>;fT{Baq{rda5DqTr6s9DqOsWASL|0}hD(sKp1O6XLO z`2hkM$AJ;a5K|h!#HV)~=R!&GB8?xf!MdSJb^_hnWL@RUOvLsK;!X6Y{qfsRhh21Y z4vE(i*8eU9+zq5CP#7fowMY1pAB=B0A0R8Td#e;A|0X+ry&`*$Z1(H{QWVGX;9k{2 zJE7!3*Mo$+m$_0?x+d2a000kANklG@b}MWmDS9_L5c=(JdN8u z>&(5;2y|i&ym5~D>G2}j*$nD9aS8~ranC`ZfDD>@AufDC8W*pPS!{RyhBZX?=HFaE zA~iDzccY09w?En0uq#|HNF+iJ)dE zRd(cpbQsrHxp_k{JJU-)=4q^bIS?6JKm3rk%txwL#66?Dzzi94;Lu3vp<{UZE}QT?N5*+h#*D`U#efv^ zTfbyGRt_juZ8`VC8|)Bs<_=}Bx{Bj%QXLOWtdM+2Ah$7QDLa9x6R%2f(E@q(t#>f< zxV%_9@;7usXGiXVmWtG22J-JDJjCP6ANooPcA{!$Ui?#-4~@lZedZA27#w2uS^lEw zNJfVgrW97L19;*|4wDZszd86VGGnDN@3ebRtEI4$JZ= z@puhfF{EE^ak?l`h+!2Mc^lz-5Iy@|QZ}p(w$zn%k3EVwTohnE0lKJcUdVAnArapT zld`C=ah0h}0W?b%?TyG!q|QBfKpK0fLA32B))49ihd%B71cQARQ4=8_dvDw}cQ#pq zV@g-7juD;2HqYBY21F#j@l0#Mynt=Tq81V-^%tnU)EN^{T`|wGvL7a;J9p308gSmC z6=-cdoiOHUerk#8MR2W!Yk~y!HbvC0fiS(xLW&BdEO0+&asZ>a3s{}oo7Eh5Z9G@x z#m4q6W?deST23@iw*PS`KG#|$Q@jtr{(sjv8?@)`+kGQ;sQsB1l5uJzeLD$cPL=G1 zI8IB#&U6HQxS|%3x89p3n{Nzc0Ch5u&Ds8sq(OT{o!rR3AOsn5qG}g}P9vh*hHI(9 ze>K8X!r&oP$&;m{`+mR2SI@AzTq9$1%ugL;?y|YoOYa=R_K%}WWV=pPd5lBw2D+(j zInOA?aQJLohTSz4!$gtw9eHVvxdm>f=fL9 ziuSr2ss(8XTo-N*^Ao-!_jd@pXI9Un%bTIQf(*wJ?qgx0FP#V`x({1M6ec=k;I}zM z@55?~^`cw-6*f^(hmyi!H6^nm>HJ5Wbet+Zi=-^8d(-{m6q4}AO!5CHU^EpXx0lpk z*==-;|H`_&GIs*4&3QSWt1saP-QL=^rH8^7@Yx?KaWfgA|Cfg$=nF+niq z*BUJW)4Y9#ZTk(V(cbBnd?jirp7-Lql8kM}3cMM*FT^hJPg_xLlnkC$^EuWW?ET=F zjgXRq9P8N^1QKktq^?JcyqM|&q?5MGG3|j3iC@_^eMI(M>Rdza1zOvj_rxFq7LI37 z%D~j#t*SbeF@U*a>2z{#5*&dUor}R{S*J4HtEurz`m6Tu7Z}e>84n&j%90>)lN6AR z476f8oJuhj`tb)BFoyU*_h+05Fw>=2mCcrsMCe-%`AZv)g=q0?`lXTQ{`w85QS^Yd@B_ zlaS`rYUrb~;KyR^XaR2*;zW zeyrLq4jQMwbAafBT%Dsto%F`D{6rNkuXL@NjrBTKW)h1+u4v5mAzzA)0;j!wh!kw6 zNMY-1xwu{2eJw_d=Ad1ko;+M`L0~A z_}u*WIp^z2s0K7+0;@8svD-}acHy-ius*7iJ{;EqI8yW6a43%F^6>mwN7A_JKgig} zekBG>O&&|{2#01IU3cUWyzy5s)}FZX)Z|1M4=6D8Y-tRmYc&{mHMk~^lhsF>QeFO; zbjDvt1?Nz9JP6=TR4cx>?C`ml760e#l+&pD*E|EibjF`~0Hwhr?vO3Fq<{G>y(7@+ zm0I(-?8DS4`m1L!xg}uJ;Q*G3osIJVQ&iKrOtP-<{o&fq0bZsw)jr-1NX_`QUG{cVT25w%>^s`~d!tdh@zRlb8UgE@2+N3M|DjdRfG z3SOA&WN6{#vaDHIlGK{vS4OH4<}+mMcui5)YsGJ8bK5~pBNqc=YCU*k=91=|gH_%> zjS6x%5LKcjNE~Fml+J60I%04(#hhD!3CzVtKMFx(SCYw$Tlwt#yP7l4X8H<`u2y~~ zBO7j(F9%)6??>`izs{~Zh#@>z#!URsZ*#f2u5Spmj?Tj*q|{iiscwVtr!_G7_hC}H z3YhA<?H63>cauvMMuJLBy7Nvh7OP+MiD2dPNlv75v);3($hIR2)pMU*=7 z>Rxyp81^;h4WQ8gFw#lL7=03PDsnLeRqi8?|Hd~fQ?4YrrQW{xpld7lZE@2E#MTl@ zB$)az4kE~q;1rUtJUN<&vn{xhL)oq;2Uu}(Jnb#jTl)#`S`BvS=P>M{TDZ%xS!0Vf z)9808FY4y2Fyy)Fk(K)iOg)XZ;be&mA0@#d$1jFh*o&lEo$@14%pRzA$M zDlk1PXP&NlH?XeVE(`1HWZ1BcB-L~x!h@B>v~Jt2VPCl%V>)pt9tl30cKAh1V9&~m z#(&6^=FenKQGpC{_Tk%85fB79Z>5oy`8-zFE98JZC*fN68yu_Sm?=X>Oz#aVMyA>6 zy8^9|D9aat4%5gAyLG04^!&Yn8rKp$U^VmBtC+jeFNv|ES~Em<|N$KFAcUkp0VEA%zXs%Xay5mIN7Q-xcWeC@}5K-heP7 z^-$>{CHww**b!Avh=wut1sNw zQgLtK<+=!9z9Qv_G;uce_2L@y6ffY(^2R&w^(pjW2Wih=^0V(Yn)8JduK@%RNE3TK0LO$hRUEx8nIV(_rTBFAcIS>(xXE(uCn~uq|m=3K$ z@3r7EyaQ=ibt&vjb$6fgZm>Jaucg4ur{Bl(QYl_06IKRQ2}%fo|8L0fYx<&!(Q&~2 zL!euG{c;t#y$J}gFfnBl3m3Jx^zHgEr7>SC-3K5~+>{qqy|d{c=AH{LuK6A2xWAG_ z2oq`lDE&*ITj#W9Hu`7$#un_tn&?o8LVDmS0rJ_9JWYlUg=CWV zI8>l@>u05Z3bao0>y;y=-X#TtCZ#kQRusLnp`SfWue+Yp$;FoJUMKOv2}#zI9Mc@f zH$YT-#4xKWRm;KkI&m8wj*?m+pVQcX1-f;Xyz~iGnBzpL3BpG)=X2I`*VY1%cR!GE zQ=XMX#Wt7+l|5f!0X;uwgG0y4xp2$f!V8gCbX?R^(f>Z!o85AlxRWi1%^PuX$DHG*1r%@OFb# zl#*mf<~CH4Tl$j?IoLFHef3vQpj+ob(`m#lIY2b9)MFDO+FBGdl7H`BI@17I5bP_o zPaI$BWr-EdgEnnL97*Hok<#HRCtx>$3}o{%j&g_0!BaVlReUZ%SK0o@TbXx{OE~ z<;&Q_!)%Bd=56&>NxdOsC)C;#HUnnPigM#AW`Zpr(2}uAeYKpe9}I}%LEKNV3pYsf z@`RM_`iYltDei6xuyiwo7u28k0_{b8ZSfUq6ILq(xM>ehGN0>S0qFFK6b_i}C1(1% zw3~si1v;oeD6{Hehs9;tvSN>ny;v;`MXsy>Vb@B=K5d#>6}nD=p)X0?o`g`2=LJyV z)u?wps4YbBUjd%^33lYq_to@F#rGn literal 0 HcmV?d00001 diff --git a/client/src/assets/favicon-16x16.png b/client/src/assets/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..427f926aac64a06ab17d2eb1b157f8a317c0afe8 GIT binary patch literal 771 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 Wp1X+T%pFev0000Ppy^*W=e*pv-0f}m z-FM$_jOk>yGo3pd;6A4N_Qo7#jM-jd_N;Lk|tx_ctc7n=uE10|^vCJ)m8G z)hTmWP1-zFn>Eu&b89nZW=+PFlkQeqAtn_SW=C)y1OKCB#(Yd#Kwe4ZMWofqteFmc zQn)@Jm60_P+y>ge0B=?@ZEmm0np3Genfxu(y$6okrUT1o&NSb0Jdpc$QUh(Df!|EJ zb<`*Z&HF0@pMKp0|5f14180DmGa0i7bxUj=a^by^w1xEQmMvzxo;}SsQuU@EI2)lU zN0*-9&ZgX=@u1w7awBbXQdx6CO@ld_e6x5^--|xnY4aJg44NCNGv;U1&mw(n$2nu( z4BPuTb!j_@I`wq}Fb&=6RD(GB+USC4ZN;$?Sh&w@kN*SNj>~FJD$u9 zbRRaU@}dNTD#pc@Cg!LEmTb0Xy%DL2usIn|hr6-_`L z{I6&--$hr=t7NPLXD+y!W3AOWB=tk-Y2o^`exCJr9CW>)uL913ZaFlINzXG@$NIP( zk(Zs>hjb!I_UWts)z_QO$p+IE{fCk!k&^Ub0)2UdKD5x3;K>GCJt(iI{5oy2 z2lX}e?OO!0XCc3O=odMD4#KO2lx2(u(S8^8cT(<0K23fl`84!Pgin4m^>2`0OWoph zqdoo#c3(P*4|Ex5GUVSQuYD&zpOJc{rkcG9F{r6AKW5x}Ksy!O*-i&wV9T-Xvh(@q zb#5W&e(3s>#*+U4xD36;YYaBylzepg>a3kkndL*t6a~joD&4QCI3@wE-LJ z>da4a=qadAwe_YCGPMTOhcrBoNoCAAk{i~^Zm4hTn5$np9*pf(P9}I$NwU)u7`Jz* z|J=1jkh2GQyEyvhX6vVvN9|k3ZzVb%O1jUsiD%dbe|s(_5@sjnW+~;Rz?XsYk+i3t z1$M=z$!AZWa{b2CNx;k`TLZ2`8X1X>i`SPrVw;~!hrWrFjAFf}AJozoM)4?2O%xlOS?aH*J z$S?G1^5xO@wg=o% zPH#cRc7EJ<^LfZVseiuS(3FyNKH2f0&Dv=8Y-F3PkC`^l#pvdt_ruVA;b=o0`uj5d zd?IZQmwXR@9tl142x=(2i zb=EE;zmjpczBF{VB{+MjKS*~9+PYDvb8>~H3GBxb<)f4_n;5rV;2nqUzleU124Cl= z?vrCEFCi^xYBD=WKk8o&dC9l2_JOtbpJH|ZzITT-o6&0^boOkGbO`#h2t6iJr?W|E z3V3$k0K2-eL8n8|rzNBnp2kAw(Pa)N4xxV`#FtHNVT?`yKeD5)EguB$_3`6#?>X=o zY~==bnGZs`Ol_U%-b!}8`4jl-Bi{JM!qMH7{%WtdzHFTn^(m--ioNr% zuYN@PoBXGY?L?sT+DOWo-<)#bcV>{OIKf=mzhW}uZP@!CAm@4X(Ai!NANfyK9`zeZ z>Qfa-GUWB!D~T>H%Y&5 zubj5kv|CEW!GY7Q7eHR zRDn#z{f=OL-3rutTU=<(s~(&d^wqw57x*^mEztqT!sCuay*Wz$R0pY7lnt`>M5gX# z@_CBesyucKy*HuvXTTZwR0H898@^OLtI}rQqQbvIqt*%g`(McYG#qQE#|q>xBPkxD zbFa#tYeCHQ6ZHBdq}deGMYfsxRkRPm23L^(TnRgVvwSa9ZRKl!S@mV(kv$gv>y(hG zc$wl3IxiHPtEX-zP`>Yc^w$}q_^WWLNwVp>pVWeov$5FI zi{Y!YMln0Zi{3;R`IQ>4R%1$iu5R)Z0=!kg#qcTx`u@K5hkOF{YbdZ;W$>0UZvXhQ zV{YRvS#vEs6-!=#&pQ#@p?>7(=gL-QFhANC)+eD(F}D=D)C2Wy@iF@8onSsmZvh_x zqcI@gf*l(IY=(#S{2JENRnDK@mcB6V|Add^>McNiS|rEm>>zEL4~?s0_@^jds5q^Y zr?^8!t=YXUi0xm4j*8(Z*4}9Miq@nX7v8fNC#@figT`tR`BuKJ^~fbIh!Z_SD3d>!Qhx>qWO0k3xLIc(*Qm1(m#^bf&Dca}2vTmM6RNuM&`L#VTJ zt$85dEuXIOx=f?B>o3BiA9|HQ+l##7A=;mMU#uoQN$NrQuV2+}!$&cLcYyNKA|Hx* zQS4grKIiYNpGU^^^~?5M2VV%9%h@}x0A>5^y~>S+gXq42l%W0U%F3_yE+Ib>-E|h~ ze&XN#71PmPvS%Q$RCgg?XFp$AYkrMRJ;Ad+s_2R(+qYmprsPBTyxNiP)W~~`dzaOk zLiV|=n^DMgchS!obNRNieX_F~n3wAd@lK@7Ul<47(~IhzuN}INiJ_gEFGlFgv*%zi z$BG$gt?O={!d{%OyDPlAQI_3Oz3k|Fzy(ew`4!qbK2PP7Q_L~oko zt1+9-comHGRq}p=KCghY)!w+V(%R=OHhfVqeW9`B>4IG6yfozPmnX9^sqF z!O?liI~8NvhdCXDUDO*~A8=;)cz)iFm*f%~cf1{B-R@5P`^CnAw)Mz(IK73K8ajr& zbqwO|? zE+8GEcP#ADPMSA#93AqNuaXlJgx@&rCB;q2>wAJq&6#9Jy2x)JuI<)99NKre0)2qT zO7&6iIpp10nxi}Qi?^aFVah6#5$GD3*%dh=yEY;Gx*8zAuUVe(E0A9n{emg7j|( zOB?VS1YKPJN8qbik&UlAxx!;zmeO`lvHA7ovQ~e}IL~oB9276^iF(UQst$cVOiyk9 zJrSNgpw-zk$nkWL^--cVLVIvlY#lS*`zr9?uJd&)me(Ah+gHZR(%)Gw4C@Kmhr zA>X$y##3$JUrG7`9izB3Wy>4B{W(+QH|5L=Yf5*ERm{OQ-GA)2TKL_Lzk?zFO2+E8 zI=)eBOJ~0wnv0>=+0kDruV9?sm*MBxZ@07>4>w*ZbNROV+svEJ zOZjA_k$zf-T9>?qknZ*Cl}GQ9B%K4-`nt6zAI7?;#(9Q(XK$;YDjm>OXLsboS>C~# zAIVyI)Rx0BQl37Iv}4G*iOvP>Gw0-<^z&S3F4T8e?wyczbaL4LXb)Jv+K2czI=|a9 z7V;0!<9_DgHLH)WqrR65-Vb{E`iFYkw`bPg(D-|dglY+gXJ00KN__D&c`sbj@IWK%3 zQcj#KWPMEAlV9`Z2oq?qh2#9@coI{81|o3CUrc1I(> zwg2vo5AB3<(|0I$P&do3kMi=J ziL0|leRZLRjF+y*XqTz0(b2D1cw9Buzdxrda`M|CZ z;GRIA_r+iMp7xjB59B8kb7fy2%-mfEO$vJ35Au3zdzx|-8*yzR)E=M9Jl_Iu(GFxB z67+iodF@55foj&uZRBT@gue=$=z9R-QpbWH*;m>&FgF989B78SIDzX&F{n7WOm3;N5))pvlowj{)f$yRJh_sQ1%4dS~;#N}64n**V7YhH7| zkh0!xmDjmb#hhFdr^{DnzHj&SQC|IF%=X4!Tm)Z#Pe%JCP7^Ofr|(X0b>CsfWh1v2 zG>prCSLX)pzrd6Z?+@7q&u>wI(eEO)`ntttJN0QGhVhh z_~y{u#5y>~@rgt2L1?uGgMC9R0J+mWesjr}(yt!*VurG3(CYk+>pl(Hr~C5gYiDq; z26qxNa_p9)5B1PDMWb1NS2Di6{kVqD&*d4r)1b5WZQy#+K$35p^nJSCG0J%l-p|nq z+WV63F=-onACA12_*VKx#mnT&__)g3_{S9Hg5NSQC%xgR^G@F-XX)<<@1kV`d>+N}iTP$H8<*g0 zfX_1V6h!7EbRLCFeM6$VzwAd6I0IR?7vt%-=`3M9dcw1#m7-!m*aXy;E zFFHGE(>QDZ>TN{tUkS=OU$t-b?x49&;U}Kgp1s=6est3Bw$SA<@kiET;9%f~q@1x0 z+jWom6#O~pG?D#YLVq4Z*S^@32dLBfmz~u(>-+yTl(nYx&FvGiksYXeP8Su+MV8_d zim{YQKg#n-!8sS}PrQG5$~xQiwl$9a9iJoYe^k(K1sK!Q(M9ivFC$y`Q?02g@^dtf zdGySkC#@mYn(p6<5w|DK*U{Y>MGR1PD0}V_|7ML0KqsvYeMfVbz7M2MvDIq&Bl|0# aVFGmzSIN)de%Jx~v!lE9e|}%15%@2#ltSJB literal 0 HcmV?d00001 diff --git a/client/src/assets/icon.svg b/client/src/assets/icon.svg new file mode 100644 index 0000000..13cd18c --- /dev/null +++ b/client/src/assets/icon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/client/src/components/dashboard/WidgetAccuracy.vue b/client/src/components/dashboard/WidgetAccuracy.vue new file mode 100644 index 0000000..7a85a0d --- /dev/null +++ b/client/src/components/dashboard/WidgetAccuracy.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/client/src/components/dashboard/WidgetDistribution.vue b/client/src/components/dashboard/WidgetDistribution.vue new file mode 100644 index 0000000..9b3e08e --- /dev/null +++ b/client/src/components/dashboard/WidgetDistribution.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/client/src/components/dashboard/WidgetForecast.vue b/client/src/components/dashboard/WidgetForecast.vue new file mode 100644 index 0000000..517199e --- /dev/null +++ b/client/src/components/dashboard/WidgetForecast.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/client/src/components/dashboard/WidgetGhosts.vue b/client/src/components/dashboard/WidgetGhosts.vue new file mode 100644 index 0000000..1cc1bcd --- /dev/null +++ b/client/src/components/dashboard/WidgetGhosts.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/client/src/components/dashboard/WidgetGuruMastery.vue b/client/src/components/dashboard/WidgetGuruMastery.vue new file mode 100644 index 0000000..83263dd --- /dev/null +++ b/client/src/components/dashboard/WidgetGuruMastery.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/client/src/components/dashboard/WidgetHeatmap.vue b/client/src/components/dashboard/WidgetHeatmap.vue new file mode 100644 index 0000000..4a9b227 --- /dev/null +++ b/client/src/components/dashboard/WidgetHeatmap.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/client/src/components/dashboard/WidgetStreak.vue b/client/src/components/dashboard/WidgetStreak.vue new file mode 100644 index 0000000..8adbe3c --- /dev/null +++ b/client/src/components/dashboard/WidgetStreak.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/client/src/components/dashboard/WidgetWelcome.vue b/client/src/components/dashboard/WidgetWelcome.vue new file mode 100644 index 0000000..b462ea8 --- /dev/null +++ b/client/src/components/dashboard/WidgetWelcome.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/client/src/components/kanji/KanjiCanvas.vue b/client/src/components/kanji/KanjiCanvas.vue new file mode 100644 index 0000000..c201ca8 --- /dev/null +++ b/client/src/components/kanji/KanjiCanvas.vue @@ -0,0 +1,247 @@ + + + + + diff --git a/client/src/components/kanji/KanjiSvgViewer.vue b/client/src/components/kanji/KanjiSvgViewer.vue new file mode 100644 index 0000000..8f3c299 --- /dev/null +++ b/client/src/components/kanji/KanjiSvgViewer.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/client/src/main.js b/client/src/main.js new file mode 100644 index 0000000..a87a3f2 --- /dev/null +++ b/client/src/main.js @@ -0,0 +1,49 @@ +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import { createRouter, createWebHistory } from 'vue-router' +import i18n from '@/plugins/i18n' + +import '@/styles/main.scss' + +import 'vuetify/styles' +import { createVuetify } from 'vuetify' +import * as components from 'vuetify/components' +import * as directives from 'vuetify/directives' +import { aliases, mdi } from 'vuetify/iconsets/mdi' +import '@mdi/font/css/materialdesignicons.css' + +import App from './App.vue' +import Dashboard from './views/Dashboard.vue' +import Collection from './views/Collection.vue' +import Review from './views/Review.vue' + +const app = createApp(App) +const pinia = createPinia() + +const router = createRouter({ + history: createWebHistory(), + routes: [ + { path: '/', component: Dashboard }, + { path: '/dashboard', component: Dashboard }, + { path: '/collection', component: Collection }, + { path: '/review', component: Review } + ] +}) + +const vuetify = createVuetify({ + components, + directives, + theme: { + defaultTheme: 'dark', + themes: { + dark: { colors: { primary: '#00cec9', secondary: '#ffeaa7' } } + } + }, + icons: { defaultSet: 'mdi', aliases, sets: { mdi } } +}) + +app.use(pinia) +app.use(router) +app.use(vuetify) +app.use(i18n) +app.mount('#app') diff --git a/client/src/plugins/i18n.js b/client/src/plugins/i18n.js new file mode 100644 index 0000000..ff9fe4d --- /dev/null +++ b/client/src/plugins/i18n.js @@ -0,0 +1,306 @@ +import { createI18n } from 'vue-i18n' + +const messages = { + en: { + common: { + close: "Close", + cancel: "Cancel" + }, + nav: { + dashboard: "Dashboard", + review: "Review", + collection: "Collection", + settings: "Settings", + sync: "Sync", + logout: "Logout", + menu: "Menu" + }, + login: { + instruction: "Enter your WaniKani V2 API Key to login", + placeholder: "Paste key here...", + button: "Login", + failed: "Login failed. Is server running?" + }, + alerts: { + syncSuccess: "Sync complete! Collection: {count}", + syncFailed: "Sync failed.", + logoutConfirm: "Are you sure you want to log out? This will end your session.", + }, + hero: { + welcome: "Welcome Back", + subtitle: "Your mind is ready.", + start: "Start Review", + noReviews: "No Reviews", + nextIn: "Next review in", + now: "now", + prioritize: "Prioritize Lower Levels ({count})" + }, + stats: { + mastery: "Mastery (Guru+)", + srsDistribution: "SRS Levels", + accuracy: "Global Accuracy", + correct: "Correct", + total: "Total", + next24: "Next 24h", + availableNow: "Available Now", + inHours: "In {n} hour | In {n} hours", + noIncoming: "No reviews incoming for 24 hours.", + items: "items", + reviewsCount: "{count} reviews", + + consistency: "Study Consistency", + less: "Less", + more: "More", + + streakTitle: "Study Streak", + days: "days", + shieldActive: "Zen Shield Active: Protects streak if you miss 1 day.", + shieldCooldown: "Regenerating: {n} days left", + + ghostTitle: "Ghost Items", + ghostSubtitle: "Lowest Accuracy", + noGhosts: "No ghosts found! Keep it up." + }, + settings: { + title: "Settings", + batchSize: "Review Batch Size", + items: "Items", + language: "Language", + save: "Save & Close" + }, + review: { + meaning: "Meaning", + level: "Level", + draw: "Draw correctly", + hint: "Hint Shown", + tryAgain: "Try again", + correct: "Correct!", + next: "NEXT", + sessionComplete: "Session Complete!", + levelup: "You leveled up your Kanji skills.", + back: "Back to Collection", + caughtUp: "All Caught Up!", + noReviews: "No reviews available right now.", + viewCollection: "View Collection", + queue: "Session queue:", + loading: "Loading Kanji...", + }, + collection: { + searchLabel: "Search Kanji, Meaning, or Reading...", + placeholder: "e.g. 'water', 'mizu', '水'", + loading: "Loading Collection...", + noMatches: "No matches found", + tryDifferent: "Try searching for a different meaning or reading.", + levelHeader: "LEVEL", + onyomi: "On'yomi", + kunyomi: "Kun'yomi", + nanori: "Nanori", + close: "Close" + } + }, + de: { + common: { + close: "Schließen", + cancel: "Abbrechen" + }, + nav: { + dashboard: "Übersicht", + review: "Lernen", + collection: "Sammlung", + settings: "Einstellungen", + sync: "Sync", + logout: "Abmelden", + menu: "Menü" + }, + login: { + instruction: "Gib deinen WaniKani V2 API Key ein", + placeholder: "Key hier einfügen...", + button: "Anmelden", + failed: "Login fehlgeschlagen. Läuft der Server?" + }, + alerts: { + syncSuccess: "Sync fertig! Sammlung: {count}", + syncFailed: "Sync fehlgeschlagen.", + logoutConfirm: "Möchtest du dich wirklich abmelden? Deine Sitzung wird beendet.", + }, + hero: { + welcome: "Willkommen zurück", + subtitle: "Dein Geist ist bereit.", + start: "Starten", + noReviews: "Alles erledigt", + nextIn: "Nächste Review in", + now: "jetzt", + prioritize: "Niedrige Stufen zuerst ({count})" + }, + stats: { + mastery: "Meisterschaft (Guru+)", + srsDistribution: "SRS Verteilung", + accuracy: "Genauigkeit", + correct: "Richtig", + total: "Gesamt", + next24: "Nächste 24h", + availableNow: "Jetzt verfügbar", + inHours: "In {n} Stunde | In {n} Stunden", + noIncoming: "Keine Reviews in den nächsten 24h.", + items: "Einträge", + reviewsCount: "{count} Reviews", + + consistency: "Lern-Konstanz", + less: "Weniger", + more: "Mehr", + + streakTitle: "Lern-Serie", + days: "Tage", + shieldActive: "Zen-Schild Aktiv: Schützt dich bei einem verpassten Tag.", + shieldCooldown: "Regeneriert: noch {n} Tage", + + ghostTitle: "Geister-Items", + ghostSubtitle: "Niedrigste Genauigkeit", + noGhosts: "Keine Geister gefunden! Weiter so." + }, + settings: { + title: "Einstellungen", + batchSize: "Anzahl pro Sitzung", + items: "Einträge", + language: "Sprache", + save: "Speichern & Schließen" + }, + review: { + meaning: "Bedeutung", + level: "Stufe", + draw: "Zeichne das Kanji", + hint: "Hinweis angezeigt", + tryAgain: "Nochmal versuchen", + correct: "Richtig!", + next: "WEITER", + sessionComplete: "Sitzung beendet!", + levelup: "Du hast deine Kanji-Skills verbessert.", + back: "Zurück zur Sammlung", + caughtUp: "Alles erledigt!", + noReviews: "Gerade keine Reviews verfügbar.", + viewCollection: "Zur Sammlung", + queue: "Verbleibend:", + loading: "Lade Kanji...", + }, + collection: { + searchLabel: "Suche Kanji, Bedeutung oder Lesung...", + placeholder: "z.B. 'Wasser', 'mizu'", + loading: "Lade Sammlung...", + noMatches: "Keine Treffer", + tryDifferent: "Versuche einen anderen Suchbegriff.", + levelHeader: "STUFE", + onyomi: "On'yomi", + kunyomi: "Kun'yomi", + nanori: "Nanori", + close: "Schließen" + } + }, + ja: { + common: { + close: "閉じる", + cancel: "キャンセル" + }, + nav: { + dashboard: "ダッシュボード", + review: "復習", + collection: "コレクション", + settings: "設定", + sync: "同期", + logout: "ログアウト", + menu: "メニュー" + }, + login: { + instruction: "WaniKani V2 APIキーを入力してください", + placeholder: "キーを貼り付け...", + button: "ログイン", + failed: "ログイン失敗。サーバーは起動していますか?" + }, + alerts: { + syncSuccess: "同期完了! コレクション: {count}", + syncFailed: "同期に失敗しました。", + logoutConfirm: "ログアウトしてもよろしいですか?セッションが終了します。", + }, + hero: { + welcome: "お帰りなさい", + subtitle: "準備は完了です。", + start: "復習開始", + noReviews: "レビューなし", + nextIn: "次の復習まで", + now: "今", + prioritize: "低レベルを優先 ({count})" + }, + stats: { + mastery: "習得度 (Guru+)", + srsDistribution: "SRS分布", + accuracy: "正解率", + correct: "正解", + total: "合計", + next24: "今後24時間", + availableNow: "今すぐ可能", + inHours: "{n}時間後", + noIncoming: "24時間以内のレビューはありません。", + items: "個", + reviewsCount: "{count} レビュー", + + consistency: "学習の一貫性", + less: "少", + more: "多", + + streakTitle: "連続学習日数", + days: "日", + shieldActive: "Zenシールド有効: 1日休んでもストリークを守ります。", + shieldCooldown: "再チャージ中: 残り{n}日", + + ghostTitle: "苦手なアイテム", + ghostSubtitle: "正解率が低い", + noGhosts: "苦手なアイテムはありません!" + }, + settings: { + title: "設定", + batchSize: "1回の復習数", + items: "個", + language: "言語 (Language)", + save: "保存して閉じる" + }, + review: { + meaning: "意味", + level: "レベル", + draw: "正しく描いてください", + hint: "ヒント表示", + tryAgain: "もう一度", + correct: "正解!", + next: "次へ", + sessionComplete: "セッション完了!", + levelup: "漢字力がアップしました。", + back: "コレクションに戻る", + caughtUp: "完了しました!", + noReviews: "現在レビューするものはありません。", + viewCollection: "コレクションを見る", + queue: "残り:", + loading: "漢字を読み込み中...", + }, + collection: { + searchLabel: "漢字、意味、読みで検索...", + placeholder: "例: '水', 'mizu'", + loading: "読み込み中...", + noMatches: "見つかりませんでした", + tryDifferent: "別のキーワードで検索してください。", + levelHeader: "レベル", + onyomi: "音読み", + kunyomi: "訓読み", + nanori: "名乗り", + close: "閉じる" + } + } +} + +const savedLocale = localStorage.getItem('zen_locale') || 'en' + +const i18n = createI18n({ + legacy: false, + locale: savedLocale, + fallbackLocale: 'en', + messages +}) + +export default i18n diff --git a/client/src/stores/appStore.js b/client/src/stores/appStore.js new file mode 100644 index 0000000..b15502a --- /dev/null +++ b/client/src/stores/appStore.js @@ -0,0 +1,136 @@ +import { defineStore } from 'pinia'; + +const BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000'; + +export const useAppStore = defineStore('app', { + state: () => ({ + token: localStorage.getItem('zen_token') || '', + user: null, + queue: [], + collection: [], + stats: { + distribution: {}, + forecast: [], + queueLength: 0, + streak: {}, + accuracy: {}, + ghosts: [] + }, + batchSize: 20, + drawingAccuracy: 10, + loading: false + }), + + actions: { + async login(apiKey) { + const res = await fetch(`${BASE_URL}/api/auth/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ apiKey }) + }); + + const data = await res.json(); + if (!res.ok) throw new Error(data.error || 'Login failed'); + + this.token = data.token; + this.user = data.user; + + if (data.user.settings) { + this.batchSize = data.user.settings.batchSize || 20; + this.drawingAccuracy = data.user.settings.drawingAccuracy || 10; + } + + localStorage.setItem('zen_token', data.token); + + await this.fetchStats(); + return data; + }, + + async logout() { + try { + if (this.token) { + await fetch(`${BASE_URL}/api/auth/logout`, { + method: 'POST', + headers: this.getHeaders() + }); + } + } catch (e) { + console.error("Logout error:", e); + } finally { + this.clearData(); + } + }, + + clearData() { + this.token = ''; + this.user = null; + this.queue = []; + this.stats = {}; + localStorage.removeItem('zen_token'); + }, + + getHeaders() { + return { + 'Authorization': `Bearer ${this.token}`, + 'Content-Type': 'application/json' + }; + }, + + async sync() { + const res = await fetch(`${BASE_URL}/api/sync`, { + method: 'POST', + headers: this.getHeaders(), + body: JSON.stringify({}) + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error); + return data; + }, + + async fetchStats() { + if (!this.token) return; + const res = await fetch(`${BASE_URL}/api/stats`, { headers: this.getHeaders() }); + if (res.status === 401) return this.logout(); + const data = await res.json(); + this.stats = data; + return data; + }, + + async fetchQueue(sortMode = 'shuffled') { + if (!this.token) return; + const res = await fetch(`${BASE_URL}/api/queue?limit=${this.batchSize}&sort=${sortMode}`, { + headers: this.getHeaders() + }); + if (res.status === 401) return this.logout(); + this.queue = await res.json(); + }, + + async fetchCollection() { + if (!this.token) return; + const res = await fetch(`${BASE_URL}/api/collection`, { headers: this.getHeaders() }); + if (res.status === 401) return this.logout(); + this.collection = await res.json(); + }, + + async submitReview(subjectId, success) { + const res = await fetch(`${BASE_URL}/api/review`, { + method: 'POST', + headers: this.getHeaders(), + body: JSON.stringify({ subjectId, success }) + }); + if (res.status === 401) return this.logout(); + return await res.json(); + }, + + async saveSettings(settings) { + if (settings.batchSize) this.batchSize = settings.batchSize; + if (settings.drawingAccuracy) this.drawingAccuracy = settings.drawingAccuracy; + + await fetch(`${BASE_URL}/api/settings`, { + method: 'POST', + headers: this.getHeaders(), + body: JSON.stringify(settings) + }); + } + } +}); diff --git a/client/src/styles/abstracts/_mixins.scss b/client/src/styles/abstracts/_mixins.scss new file mode 100644 index 0000000..b4bf731 --- /dev/null +++ b/client/src/styles/abstracts/_mixins.scss @@ -0,0 +1,68 @@ +@use 'sass:color'; +@use 'variables' as *; + +@mixin flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +@mixin flex-column($gap: 0) { + display: flex; + flex-direction: column; + gap: $gap; +} + +@mixin grid-responsive($min-width: 960px) { + display: grid; + grid-template-columns: 1fr; + + @media (min-width: $min-width) { + // stylelint-disable-next-line no-invalid-position-declaration + grid-template-columns: 1fr 1fr; + } +} + +@mixin card-base { + background: $color-surface-light; + border-radius: $radius-md; + border: 1px solid transparent; + background-clip: padding-box; +} + +@mixin hover-lift { + transition: + transform $duration-fast $ease-default, + background $duration-fast $ease-default, + box-shadow $duration-fast $ease-default; + will-change: transform; + transform: translateZ(0); + backface-visibility: hidden; + + &:hover { + transform: translateY(-2px); + background: color.adjust($color-surface-light, $lightness: 5%); + box-shadow: $shadow-md; + } +} + +@mixin scrollbar { + scrollbar-width: thin; + scrollbar-color: #333 transparent; +} + +@mixin animate-fade-up($duration: 0.4s) { + animation: fade-slide-up $duration ease-out backwards; + + @keyframes fade-slide-up { + from { + opacity: 0; + transform: translateY(10px); + } + + to { + opacity: 1; + transform: translateY(0); + } + } +} diff --git a/client/src/styles/abstracts/_variables.scss b/client/src/styles/abstracts/_variables.scss new file mode 100644 index 0000000..3392633 --- /dev/null +++ b/client/src/styles/abstracts/_variables.scss @@ -0,0 +1,5 @@ +@forward 'variables/colors'; +@forward 'variables/typography'; +@forward 'variables/spacing'; +@forward 'variables/layout'; +@forward 'variables/effects'; diff --git a/client/src/styles/abstracts/variables/_colors.scss b/client/src/styles/abstracts/variables/_colors.scss new file mode 100644 index 0000000..0566d86 --- /dev/null +++ b/client/src/styles/abstracts/variables/_colors.scss @@ -0,0 +1,18 @@ +$color-primary: hsl(178deg 100% 40%); +$color-secondary: hsl(46deg 100% 82%); +$color-bg-dark: hsl(0deg 0% 7%); +$color-surface: hsl(240deg 9% 13%); +$color-surface-light: hsl(221deg 17% 22%); +$color-text-white: hsl(0deg 0% 100%); +$color-text-grey: hsl(213deg 14% 70%); +$color-border: hsl(0deg 0% 100% / 8%); +$color-srs-1: hsl(0deg 100% 73%); +$color-srs-2: hsl(39deg 98% 71%); +$color-srs-3: hsl(163deg 85% 64%); +$color-srs-4: hsl(206deg 92% 46%); +$color-srs-5: hsl(244deg 100% 82%); +$color-srs-6: hsl(247deg 72% 63%); +$color-danger: hsl(0deg 85% 65%); +$color-success: hsl(160deg 80% 45%); +$color-stroke-inactive: hsl(0deg 0% 33%); +$color-dot-base: hsl(0deg 0% 27%); diff --git a/client/src/styles/abstracts/variables/_effects.scss b/client/src/styles/abstracts/variables/_effects.scss new file mode 100644 index 0000000..0366c13 --- /dev/null +++ b/client/src/styles/abstracts/variables/_effects.scss @@ -0,0 +1,30 @@ +@use 'sass:color'; +@use 'colors' as *; + +$opacity-disabled: 0.5; +$opacity-inactive: 0.3; +$opacity-hover: 0.8; +$opacity-active: 1; +$blur-sm: blur(4px); +$blur-md: blur(10px); +$blur-lg: blur(20px); +$bg-glass-subtle: hsl(0deg 0% 100% / 5%); +$bg-glass-light: hsl(0deg 0% 100% / 6%); +$bg-glass-strong: hsl(0deg 0% 100% / 10%); +$bg-glass-dark: hsl(0deg 0% 0% / 20%); +$shadow-sm: 0 2px 4px hsl(0deg 0% 0% / 20%); +$shadow-md: 0 4px 15px hsl(0deg 0% 0% / 30%); +$shadow-lg: 0 20px 50px hsl(0deg 0% 0% / 50%); +$shadow-inset: inset 0 0 20px hsl(0deg 0% 0% / 30%); +$text-shadow: 0 2px 10px hsl(0deg 0% 0% / 50%); +$shadow-glow-xs: 0 0 4px hsl(0deg 0% 100% / 50%); +$shadow-glow-base: 0 0 20px color.change($color-primary, $alpha: 0.4); +$shadow-glow-hover: 0 0 40px color.change($color-primary, $alpha: 0.6); +$shadow-glow-active: 0 0 20px color.change($color-primary, $alpha: 0.4); +$dist-slide-sm: 10px; +$duration-fast: 0.2s; +$duration-normal: 0.3s; +$duration-slow: 0.5s; +$duration-chart: 1s; +$ease-default: ease; +$ease-out-back: cubic-bezier(0.175, 0.885, 0.32, 1.275); diff --git a/client/src/styles/abstracts/variables/_layout.scss b/client/src/styles/abstracts/variables/_layout.scss new file mode 100644 index 0000000..e6fcb70 --- /dev/null +++ b/client/src/styles/abstracts/variables/_layout.scss @@ -0,0 +1,46 @@ +@use 'colors' as *; + +$radius-sm: 4px; +$radius-md: 8px; +$radius-lg: 12px; +$radius-xl: 24px; +$radius-pill: 999px; +$radius-circle: 50%; +$border-width-sm: 1px; +$border-width-md: 2px; +$border-subtle: $border-width-sm solid $color-border; +$border-focus: $border-width-md solid $color-primary; +$border-transparent: $border-width-md solid transparent; +$z-back: -1; +$z-normal: 1; +$z-sticky: 10; +$z-dropdown: 50; +$z-modal: 100; +$z-tooltip: 200; +$z-above: 2; +$size-canvas: 300px; +$size-kanji-preview: 200px; +$size-icon-btn: 32px; +$size-icon-small: 18px; +$stroke-width-main: 3px; +$stroke-width-arrow: 2px; +$font-size-svg-number: 5px; +$radius-xs: 2px; +$radius-sm: 4px; +$radius-md: 8px; +$radius-lg: 12px; +$radius-xl: 24px; +$radius-pill: 999px; +$radius-circle: 50%; +$size-legend-box: 12px; +$size-streak-dot: 24px; +$size-srs-track: 24px; +$size-chart-height: 160px; +$size-ghost-min-height: 80px; +$max-width-heatmap: 950px; +$max-width-desktop: 1400px; +$padding-page-y: 40px; +$padding-page-x: 24px; +$breakpoint-md: 960px; +$offset-fab: 20px; +$size-heatmap-cell-height: 10px; diff --git a/client/src/styles/abstracts/variables/_spacing.scss b/client/src/styles/abstracts/variables/_spacing.scss new file mode 100644 index 0000000..148ed86 --- /dev/null +++ b/client/src/styles/abstracts/variables/_spacing.scss @@ -0,0 +1,10 @@ +$spacing-2xs: 2px; +$spacing-xs: 4px; +$spacing-sm: 8px; +$spacing-md: 16px; +$spacing-lg: 24px; +$spacing-xl: 32px; +$spacing-xxl: 48px; +$size-loading-spinner: 64px; +$gap-heatmap: 3px; +$size-card-min: 60px; diff --git a/client/src/styles/abstracts/variables/_typography.scss b/client/src/styles/abstracts/variables/_typography.scss new file mode 100644 index 0000000..75e7be9 --- /dev/null +++ b/client/src/styles/abstracts/variables/_typography.scss @@ -0,0 +1,25 @@ +$font-family-sans: + 'Inter', + system-ui, + -apple-system, + sans-serif; +$font-family-mono: 'Fira Code', monospace; +$font-xs: 0.75rem; +$font-sm: 0.875rem; +$font-md: 1rem; +$font-lg: 1.25rem; +$font-xl: 1.5rem; +$font-2xl: 2rem; +$font-3xl: 3rem; +$weight-regular: 400; +$weight-medium: 500; +$weight-bold: 700; +$weight-black: 900; +$tracking-tighter: -0.05em; +$tracking-tight: -0.025em; +$tracking-normal: 0em; +$tracking-wide: 0.025em; +$tracking-wider: 0.05em; +$leading-tight: 1.2; +$leading-normal: 1.5; +$leading-loose: 1.8; diff --git a/client/src/styles/base/_typography.scss b/client/src/styles/base/_typography.scss new file mode 100644 index 0000000..07af96f --- /dev/null +++ b/client/src/styles/base/_typography.scss @@ -0,0 +1,23 @@ +@use '../abstracts/variables' as *; + +body { + font-family: $font-family-sans; + line-height: $leading-normal; + -webkit-font-smoothing: antialiased; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: $weight-bold; + line-height: $leading-tight; + letter-spacing: $tracking-tight; +} + +code, +pre { + font-family: $font-family-mono; +} diff --git a/client/src/styles/components/_buttons.scss b/client/src/styles/components/_buttons.scss new file mode 100644 index 0000000..6b49f41 --- /dev/null +++ b/client/src/styles/components/_buttons.scss @@ -0,0 +1,26 @@ +@use '../abstracts/variables' as *; + +.glow-btn { + box-shadow: $shadow-glow-base; + transition: + transform $duration-fast $ease-default, + box-shadow $duration-fast $ease-default; + will-change: transform, box-shadow; + + &:hover { + transform: translateY(-2px); + box-shadow: $shadow-glow-hover; + } + + &:active { + transform: translateY(0); + box-shadow: $shadow-glow-active; + } + + &:disabled { + box-shadow: none; + transform: none; + opacity: $opacity-disabled; + cursor: not-allowed; + } +} diff --git a/client/src/styles/components/_kanji.scss b/client/src/styles/components/_kanji.scss new file mode 100644 index 0000000..f283fb3 --- /dev/null +++ b/client/src/styles/components/_kanji.scss @@ -0,0 +1,147 @@ +@use '../abstracts/variables' as *; +@use '../abstracts/mixins' as *; + +.canvas-container { + position: relative; + + @include flex-center; + + margin-bottom: $spacing-xl; +} + +.canvas-wrapper { + width: $size-canvas; + height: $size-canvas; + border-radius: $radius-lg; + background: rgba($color-surface, 0.95); + border: $border-width-md solid $color-surface-light; + position: relative; + cursor: crosshair; + box-shadow: $shadow-inset; + + canvas { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + touch-action: none; + } +} + +.loading-text { + position: absolute; + color: $color-text-grey; + z-index: $z-sticky; + font-size: $font-sm; + font-weight: $weight-medium; + letter-spacing: $tracking-wide; +} + +.svg-container { + width: $size-kanji-preview; + height: $size-kanji-preview; + margin: 0 auto $spacing-lg; + background: rgba($color-bg-dark, 0.2); + border-radius: $radius-md; + border: $border-subtle; + position: relative; + + @include flex-center; + + overflow: hidden; +} + +.stroke-path { + fill: none; + stroke: $color-stroke-inactive; + stroke-width: $stroke-width-main; + stroke-linecap: round; + stroke-linejoin: round; + transition: stroke $duration-normal; + + &.hidden { + opacity: 0; + } + + &.animating { + stroke: $color-primary; + stroke-dasharray: var(--len); + stroke-dashoffset: var(--len); + animation: draw-stroke var(--duration) linear forwards; + } + + &.drawn { + stroke: $color-text-white; + opacity: 1; + } +} + +@keyframes draw-stroke { + to { + stroke-dashoffset: 0; + } +} + +.stroke-start-circle { + fill: $color-srs-1; +} + +.stroke-number { + fill: $color-text-white; + font-size: $font-size-svg-number; + font-family: $font-family-sans; + font-weight: $weight-bold; + text-anchor: middle; + dominant-baseline: middle; + pointer-events: none; +} + +.stroke-arrow-line { + fill: none; + stroke: rgba($color-secondary, 0.7); + stroke-width: $stroke-width-arrow; + stroke-linecap: round; + stroke-linejoin: round; +} + +.loading-spinner { + color: $color-text-grey; + font-size: $font-sm; +} + +.play-btn { + position: absolute; + top: $spacing-sm; + right: $spacing-sm; + background: rgba($color-bg-dark, 0.3); + border: $border-width-sm solid rgba($color-primary, 0.5); + color: $color-primary; + border-radius: $radius-circle; + width: $size-icon-btn; + height: $size-icon-btn; + + @include flex-center; + + cursor: pointer; + transition: all $duration-fast ease; + z-index: $z-sticky; + backdrop-filter: $blur-sm; + + &:hover { + transform: scale(1.1); + background: $color-primary; + color: $color-bg-dark; + border-color: $color-primary; + box-shadow: $shadow-glow-base; + } + + &:active { + transform: scale(0.95); + } + + svg { + width: $size-icon-small; + height: $size-icon-small; + } +} diff --git a/client/src/styles/components/_widgets.scss b/client/src/styles/components/_widgets.scss new file mode 100644 index 0000000..50a90ee --- /dev/null +++ b/client/src/styles/components/_widgets.scss @@ -0,0 +1,174 @@ +@use '../abstracts/variables' as *; +@use '../abstracts/mixins' as *; +@use 'sass:color'; + +.widget-card { + @include card-base; + + border: $border-subtle; +} + +.level-0 { + background-color: $bg-glass-subtle; +} + +.level-1 { + background-color: color.mix($color-primary, $color-surface, 25%); +} + +.level-2 { + background-color: color.mix($color-primary, $color-surface, 50%); +} + +.level-3 { + background-color: $color-primary; +} + +.level-4 { + background-color: color.scale($color-primary, $lightness: 40%); +} + +.heatmap-container { + width: 100%; + + @include flex-center; +} + +.heatmap-year { + display: grid; + grid-template-columns: repeat(53, 1fr); + gap: $gap-heatmap; + width: 100%; +} + +.heatmap-week { + display: grid; + grid-template-rows: repeat(7, max-content); + gap: $gap-heatmap; +} + +.heatmap-day-wrapper { + width: 100%; +} + +.heatmap-cell { + width: 100%; + height: $size-heatmap-cell-height; + border-radius: $radius-xs; + transition: + opacity $duration-fast, + background-color $duration-fast; + + &:hover { + opacity: $opacity-hover; + } +} + +.today-cell { + border: $border-width-sm solid $color-text-white; + box-shadow: $shadow-glow-xs; + z-index: $z-above; + position: relative; + box-sizing: border-box; +} + +.legend-container { + display: flex; + align-items: center; + gap: $spacing-xs; +} + +.legend-box { + width: $size-legend-box; + height: $size-legend-box; + border-radius: $radius-xs; +} + +.ghost-card { + background: $bg-glass-subtle; + border-radius: $radius-md; + padding: $spacing-sm; + text-align: center; + border: $border-width-sm solid $bg-glass-subtle; + display: flex; + flex-direction: column; + justify-content: center; + min-height: $size-ghost-min-height; +} + +.srs-chart-container { + height: $size-chart-height; + width: 100%; +} + +.srs-column { + height: 100%; + display: flex; + flex-direction: column; + justify-content: flex-end; +} + +.srs-track { + width: $size-srs-track; + flex-grow: 1; + background: $bg-glass-light; + border-radius: $radius-md; + position: relative; + overflow: hidden; + display: flex; + align-items: flex-end; + margin: $spacing-xs 0; +} + +.srs-fill { + width: 100%; + border-radius: $radius-sm; + transition: height 1s $ease-out-back; + min-height: 0; +} + +.transition-text { + transition: color $duration-normal $ease-default; +} + +.streak-dot { + width: $size-streak-dot; + height: $size-streak-dot; + border-radius: $radius-circle; + background: $bg-glass-strong; + + @include flex-center; + + transition: all $duration-normal; + + &.active { + background: $color-primary; + box-shadow: $shadow-glow-active; + } +} + +.forecast-list { + overflow-y: auto; + + @include scrollbar; +} + +.gap-1 { + gap: $spacing-xs; +} + +.gap-2 { + gap: $spacing-sm; +} + +.border-subtle { + border: $border-subtle; +} + +.border-b-subtle { + border-bottom: $border-subtle; +} + +.border-t-subtle { + border-top: $border-subtle; +} diff --git a/client/src/styles/main.scss b/client/src/styles/main.scss new file mode 100644 index 0000000..09fa884 --- /dev/null +++ b/client/src/styles/main.scss @@ -0,0 +1,10 @@ +@use 'abstracts/variables'; +@use 'abstracts/mixins'; +@use 'base/typography'; +@use 'components/buttons'; +@use 'components/widgets'; +@use 'components/kanji'; +@use 'pages/app'; +@use 'pages/dashboard'; +@use 'pages/review'; +@use 'pages/collection'; diff --git a/client/src/styles/pages/_app.scss b/client/src/styles/pages/_app.scss new file mode 100644 index 0000000..b06713c --- /dev/null +++ b/client/src/styles/pages/_app.scss @@ -0,0 +1,61 @@ +@use '../abstracts/variables' as *; + +:root { + --v-theme-background: #{$color-bg-dark}; +} + +body, +html, +.zen-app, +.v-application { + background-color: $color-bg-dark !important; + font-family: $font-family-sans; + color: $color-text-white; +} + +.v-navigation-drawer { + background-color: $color-surface !important; + + // stylelint-disable-next-line selector-class-pattern + .v-list-item--active { + background-color: rgba($color-primary, 0.15); + color: $color-primary !important; + + .v-icon { + color: $color-primary !important; + } + } +} + +.v-card { + box-shadow: $shadow-lg !important; +} + +.app-bar-blur { + border-bottom-color: $color-border !important; + backdrop-filter: $blur-md; +} + +.cursor-pointer { + cursor: pointer; +} + +.tracking-wide { + letter-spacing: $tracking-wider; +} + +.tracking-tight { + letter-spacing: $tracking-tight; +} + +.border-subtle { + border: $border-subtle; +} + +.logo-hover { + transition: opacity $duration-fast $ease-default; + + &:hover { + opacity: $opacity-hover; + } +} diff --git a/client/src/styles/pages/_collection.scss b/client/src/styles/pages/_collection.scss new file mode 100644 index 0000000..cc3ac9e --- /dev/null +++ b/client/src/styles/pages/_collection.scss @@ -0,0 +1,128 @@ +@use '../abstracts/variables' as *; +@use '../abstracts/mixins' as *; + +.sticky-search { + position: sticky; + top: $spacing-sm; + z-index: $z-sticky; + box-shadow: $shadow-md; + border-radius: $radius-sm; +} + +.fade-slide-up { + @include animate-fade-up; +} + +.kanji-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax($size-card-min, 1fr)); + gap: $spacing-sm; +} + +.kanji-card { + @include card-base; + @include hover-lift; + + aspect-ratio: 1; + + @include flex-column; + + align-items: center; + justify-content: center; + position: relative; + overflow: hidden; + + .k-char { + font-size: $font-2xl; + font-weight: $weight-medium; + line-height: $leading-tight; + transition: all 0.3s ease; + } + + &.zen-master { + border: 1px solid rgb(255 215 0 / 50%); + background: linear-gradient(135deg, rgb(30 30 36 / 100%) 0%, rgb(45 45 55 / 100%) 100%); + box-shadow: 0 0 15px rgb(255 215 0 / 15%); + animation: zen-pulse 4s infinite ease-in-out; + + .k-char { + text-shadow: 0 0 15px rgb(255 215 0 / 60%); + transform: scale(1.1); + } + } + + .k-dots { + display: flex; + gap: $spacing-2xs; + margin-top: $spacing-xs; + + .dot { + width: $spacing-xs; + height: $spacing-xs; + border-radius: $radius-circle; + background: $color-dot-base; + } + } + + .k-bars { + display: flex; + gap: 3px; + width: 60%; + height: 4px; + margin-top: $spacing-sm; + + .bar { + flex: 1; + background: rgb(255 255 255 / 10%); + border-radius: 2px; + transition: background-color 0.3s ease; + + &.filled { + box-shadow: 0 0 4px rgb(0 0 0 / 30%); + } + } + } +} + +@keyframes zen-pulse { + 0% { + box-shadow: 0 0 10px rgb(255 215 0 / 10%); + border-color: rgb(255 215 0 / 30%); + } + + 50% { + box-shadow: 0 0 20px rgb(255 215 0 / 30%); + border-color: rgb(255 215 0 / 80%); + } + + 100% { + box-shadow: 0 0 10px rgb(255 215 0 / 10%); + border-color: rgb(255 215 0 / 30%); + } +} + +.readings-container { + display: grid; + grid-template-columns: 1fr 1fr; + gap: $spacing-sm; + text-align: left; + + .reading-group { + background: $bg-glass-dark; + padding: $spacing-sm $spacing-md; + border-radius: $radius-md; + + .reading-label { + font-size: $font-xs; + color: $color-text-grey; + text-transform: uppercase; + letter-spacing: $tracking-wider; + margin-bottom: $spacing-2xs; + } + + .reading-value { + color: $color-text-white; + font-size: $font-sm; + } + } +} diff --git a/client/src/styles/pages/_dashboard.scss b/client/src/styles/pages/_dashboard.scss new file mode 100644 index 0000000..12a40c8 --- /dev/null +++ b/client/src/styles/pages/_dashboard.scss @@ -0,0 +1,34 @@ +@use '../abstracts/variables' as *; +@use '../abstracts/mixins' as *; + +.dashboard-layout { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-auto-rows: min-content; + gap: $spacing-lg; + width: 100%; + max-width: $max-width-desktop; + margin: 0 auto; + padding: $padding-page-y $padding-page-x; + box-sizing: border-box; + + &.fade-in { + @include animate-fade-up($duration-slow); + } + + .grid-area-full { + grid-column: 1 / -1; + } + + .stats-split-layout { + grid-column: 1 / -1; + gap: $spacing-lg; + + @include grid-responsive($breakpoint-md); + + .stats-left, + .stats-right { + @include flex-column($spacing-lg); + } + } +} diff --git a/client/src/styles/pages/_review.scss b/client/src/styles/pages/_review.scss new file mode 100644 index 0000000..8d0fb8f --- /dev/null +++ b/client/src/styles/pages/_review.scss @@ -0,0 +1,47 @@ +@use '../abstracts/variables' as *; + +.text-shadow { + text-shadow: $text-shadow; +} + +.canvas-wrapper { + position: relative; + width: $size-canvas; + height: $size-canvas; + border-radius: $radius-lg; + background: $bg-glass-dark; + box-shadow: $shadow-inset; + + .next-fab { + position: absolute; + bottom: -#{$offset-fab}; + right: -#{$offset-fab}; + z-index: $z-sticky; + } +} + +.scale-enter-active, +.scale-leave-active { + transition: all $duration-normal $ease-out-back; +} + +.scale-enter-from, +.scale-leave-to { + opacity: 0; + transform: scale(0); +} + +.fade-slide-enter-active, +.fade-slide-leave-active { + transition: all $duration-normal $ease-default; +} + +.fade-slide-enter-from { + opacity: 0; + transform: translateY($dist-slide-sm); +} + +.fade-slide-leave-to { + opacity: 0; + transform: translateY(-#{$dist-slide-sm}); +} diff --git a/client/src/views/Collection.vue b/client/src/views/Collection.vue new file mode 100644 index 0000000..db89550 --- /dev/null +++ b/client/src/views/Collection.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/client/src/views/Dashboard.vue b/client/src/views/Dashboard.vue new file mode 100644 index 0000000..95bf329 --- /dev/null +++ b/client/src/views/Dashboard.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/client/src/views/Review.vue b/client/src/views/Review.vue new file mode 100644 index 0000000..0fc99f3 --- /dev/null +++ b/client/src/views/Review.vue @@ -0,0 +1,238 @@ + + + + + diff --git a/client/stylelint.config.js b/client/stylelint.config.js new file mode 100644 index 0000000..c6204bf --- /dev/null +++ b/client/stylelint.config.js @@ -0,0 +1,17 @@ +/** @type {import('stylelint').Config} */ +export default { + extends: [ + 'stylelint-config-standard-scss', + 'stylelint-config-recommended-vue' + ], + ignoreFiles: [ + '**/node_modules/**', + '**/dist/**', + '**/android/**' + ], + rules: { + 'at-rule-no-unknown': null, + 'scss/at-rule-no-unknown': true, + 'no-empty-source': null, + } +}; diff --git a/client/vite.config.js b/client/vite.config.js new file mode 100644 index 0000000..b174b26 --- /dev/null +++ b/client/vite.config.js @@ -0,0 +1,19 @@ +import { fileURLToPath, URL } from 'node:url' +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + } + }, + css: { + preprocessorOptions: { + scss: { + additionalData: `@use "@/styles/abstracts/_variables.scss" as *; @use "@/styles/abstracts/_mixins.scss" as *;` + } + } + } +}) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..fa20eb0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,51 @@ +services: + mongo: + image: mongo:6 + container_name: zen_mongo + restart: always + ports: + - "27017:27017" + volumes: + - mongo-data:/data/db + networks: + - zen-network + + server: + build: ./server + container_name: zen_server + restart: always + ports: + - "3000:3000" + env_file: + - .env + depends_on: + - mongo + networks: + - zen-network + volumes: + - ./server:/app + - /app/node_modules + + client: + build: + context: ./client + target: dev-stage + container_name: zen_client + ports: + - "5173:5173" + env_file: + - .env + depends_on: + - server + networks: + - zen-network + volumes: + - ./client:/app + - /app/node_modules + +volumes: + mongo-data: + +networks: + zen-network: + driver: bridge diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..af01477 --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,13 @@ +FROM node:24-alpine + +WORKDIR /app + +COPY package*.json ./ + +RUN npm install + +COPY . . + +EXPOSE 3000 + +CMD ["npm", "start"] diff --git a/server/package-lock.json b/server/package-lock.json new file mode 100644 index 0000000..7e14aad --- /dev/null +++ b/server/package-lock.json @@ -0,0 +1,2851 @@ +{ + "name": "zen-kanji-server", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "zen-kanji-server", + "version": "1.0.0", + "dependencies": { + "@fastify/cors": "^11.2.0", + "@fastify/jwt": "^10.0.0", + "cors": "^2.8.5", + "fastify": "^5.6.2", + "fastify-cors": "^6.0.3", + "mongoose": "^9.0.1", + "node-fetch": "^3.3.2" + }, + "devDependencies": { + "@vitest/coverage-v8": "^4.0.16", + "vitest": "^4.0.16" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fastify/ajv-compiler": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-4.0.5.tgz", + "integrity": "sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^3.0.0" + } + }, + "node_modules/@fastify/cors": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-11.2.0.tgz", + "integrity": "sha512-LbLHBuSAdGdSFZYTLVA3+Ch2t+sA6nq3Ejc6XLAKiQ6ViS2qFnvicpj0htsx03FyYeLs04HfRNBsz/a8SvbcUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fastify-plugin": "^5.0.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/@fastify/error": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@fastify/error/-/error-4.2.0.tgz", + "integrity": "sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/fast-json-stringify-compiler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-5.0.3.tgz", + "integrity": "sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "fast-json-stringify": "^6.0.0" + } + }, + "node_modules/@fastify/forwarded": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@fastify/forwarded/-/forwarded-3.0.1.tgz", + "integrity": "sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/@fastify/jwt": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@fastify/jwt/-/jwt-10.0.0.tgz", + "integrity": "sha512-2Qka3NiyNNcsfejMUvyzot1T4UYIzzcbkFGDdVyrl344fRZ/WkD6VFXOoXhxe2Pzf3LpJNkoSxUM4Ru4DVgkYA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.2.0", + "@lukeed/ms": "^2.0.2", + "fast-jwt": "^6.0.2", + "fastify-plugin": "^5.0.1", + "steed": "^1.1.3" + } + }, + "node_modules/@fastify/merge-json-schemas": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.2.1.tgz", + "integrity": "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@fastify/proxy-addr": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.1.0.tgz", + "integrity": "sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/forwarded": "^3.0.0", + "ipaddr.js": "^2.1.0" + } + }, + "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/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/@lukeed/ms": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz", + "integrity": "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.0.tgz", + "integrity": "sha512-ZHzx7Z3rdlWL1mECydvpryWN/ETXJiCxdgQKTAH+djzIPe77HdnSizKBDi1TVDXZjXyOj2IqEG/vPw71ULF06w==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.5.tgz", + "integrity": "sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.5.tgz", + "integrity": "sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.5.tgz", + "integrity": "sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz", + "integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.5.tgz", + "integrity": "sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.5.tgz", + "integrity": "sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.5.tgz", + "integrity": "sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.5.tgz", + "integrity": "sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz", + "integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.5.tgz", + "integrity": "sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.5.tgz", + "integrity": "sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.5.tgz", + "integrity": "sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.5.tgz", + "integrity": "sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.5.tgz", + "integrity": "sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.5.tgz", + "integrity": "sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.5.tgz", + "integrity": "sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.5.tgz", + "integrity": "sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.5.tgz", + "integrity": "sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.5.tgz", + "integrity": "sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.5.tgz", + "integrity": "sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.5.tgz", + "integrity": "sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz", + "integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "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/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.16.tgz", + "integrity": "sha512-2rNdjEIsPRzsdu6/9Eq0AYAzYdpP6Bx9cje9tL3FE5XzXRQF1fNU9pe/1yE8fCrS0HD+fBtt6gLPh6LI57tX7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.0.16", + "ast-v8-to-istanbul": "^0.3.8", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.1", + "obug": "^2.1.1", + "std-env": "^3.10.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.0.16", + "vitest": "4.0.16" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.16.tgz", + "integrity": "sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.16.tgz", + "integrity": "sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.16", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.16.tgz", + "integrity": "sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.16.tgz", + "integrity": "sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.16", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.16.tgz", + "integrity": "sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.16", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.16.tgz", + "integrity": "sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.16.tgz", + "integrity": "sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.16", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "license": "MIT" + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.9.tgz", + "integrity": "sha512-dSC6tJeOJxbZrPzPbv5mMd6CMiQ1ugaVXXPRad2fXUSsy1kstFn9XQWemV9VW7Y7kpxgQ/4WMoZfwdH8XSU48w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/avvio": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-9.1.0.tgz", + "integrity": "sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==", + "license": "MIT", + "dependencies": { + "@fastify/error": "^4.0.0", + "fastq": "^1.17.1" + } + }, + "node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT" + }, + "node_modules/bson": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-7.0.0.tgz", + "integrity": "sha512-Kwc6Wh4lQ5OmkqqKhYGKIuELXl+EPYSCObVE6bWsp1T/cGkOCBN0I8wF/T44BiuhHyNi1mmKVPXk60d41xZ7kw==", + "license": "Apache-2.0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/chai": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.1.tgz", + "integrity": "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-json-stringify": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.1.1.tgz", + "integrity": "sha512-DbgptncYEXZqDUOEl4krff4mUiVrTZZVI7BBrQR/T3BqMj/eM1flTC1Uk2uUoLcWCxjT95xKulV/Lc6hhOZsBQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/merge-json-schemas": "^0.2.0", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "fast-uri": "^3.0.0", + "json-schema-ref-resolver": "^3.0.0", + "rfdc": "^1.2.0" + } + }, + "node_modules/fast-jwt": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/fast-jwt/-/fast-jwt-6.1.0.tgz", + "integrity": "sha512-cGK/TXlud8INL49Iv7yRtZy0PHzNJId1shfqNCqdF0gOlWiy+1FPgjxX+ZHp/CYxFYDaoNnxeYEGzcXSkahUEQ==", + "license": "Apache-2.0", + "dependencies": { + "@lukeed/ms": "^2.0.2", + "asn1.js": "^5.4.1", + "ecdsa-sig-formatter": "^1.0.11", + "mnemonist": "^0.40.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fast-querystring": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", + "license": "MIT", + "dependencies": { + "fast-decode-uri-component": "^1.0.1" + } + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastfall": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/fastfall/-/fastfall-1.5.1.tgz", + "integrity": "sha512-KH6p+Z8AKPXnmA7+Iz2Lh8ARCMr+8WNPVludm1LGkZoD2MjY6LVnRMtTKhkdzI+jr0RzQWXKzKyBJm1zoHEL4Q==", + "license": "MIT", + "dependencies": { + "reusify": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fastify": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.6.2.tgz", + "integrity": "sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@fastify/ajv-compiler": "^4.0.0", + "@fastify/error": "^4.0.0", + "@fastify/fast-json-stringify-compiler": "^5.0.0", + "@fastify/proxy-addr": "^5.0.0", + "abstract-logging": "^2.0.1", + "avvio": "^9.0.0", + "fast-json-stringify": "^6.0.0", + "find-my-way": "^9.0.0", + "light-my-request": "^6.0.0", + "pino": "^10.1.0", + "process-warning": "^5.0.0", + "rfdc": "^1.3.1", + "secure-json-parse": "^4.0.0", + "semver": "^7.6.0", + "toad-cache": "^3.7.0" + } + }, + "node_modules/fastify-cors": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/fastify-cors/-/fastify-cors-6.0.3.tgz", + "integrity": "sha512-fMbXubKKyBHHCfSBtsCi3+7VyVRdhJQmGes5gM+eGKkRErCdm0NaYO0ozd31BQBL1ycoTIjbqOZhJo4RTF/Vlg==", + "license": "MIT", + "dependencies": { + "fastify-plugin": "^3.0.0", + "vary": "^1.1.2" + } + }, + "node_modules/fastify-cors/node_modules/fastify-plugin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-3.0.1.tgz", + "integrity": "sha512-qKcDXmuZadJqdTm6vlCqioEbyewF60b/0LOFCcYN1B6BIZGlYJumWWOYs70SFYLDAH4YqdE1cxH/RKMG7rFxgA==", + "license": "MIT" + }, + "node_modules/fastify-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-5.1.0.tgz", + "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fastparallel": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz", + "integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4", + "xtend": "^4.0.2" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fastseries": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/fastseries/-/fastseries-1.7.2.tgz", + "integrity": "sha512-dTPFrPGS8SNSzAt7u/CbMKCJ3s01N04s4JFbORHcmyvVfVKmbhMD1VtRbh5enGHxkaQDqWyLefiKOGGmohGDDQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/find-my-way": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.3.0.tgz", + "integrity": "sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-querystring": "^1.0.0", + "safe-regex2": "^5.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "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/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", + "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-ref-resolver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.0.tgz", + "integrity": "sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/kareem": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-3.0.0.tgz", + "integrity": "sha512-RKhaOBSPN8L7y4yAgNhDT2602G5FD6QbOIISbjN9D6mjHPeqeg7K+EB5IGSU5o81/X2Gzm3ICnAvQW3x3OP8HA==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/light-my-request": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-6.6.0.tgz", + "integrity": "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "cookie": "^1.0.1", + "process-warning": "^4.0.0", + "set-cookie-parser": "^2.6.0" + } + }, + "node_modules/light-my-request/node_modules/process-warning": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.1.tgz", + "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/mnemonist": { + "version": "0.40.3", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.40.3.tgz", + "integrity": "sha512-Vjyr90sJ23CKKH/qPAgUKicw/v6pRoamxIEDFOF8uSgFME7DqPRpHgRTejWVjkdGg5dXj0/NyxZHZ9bcjH+2uQ==", + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.4" + } + }, + "node_modules/mongodb": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.0.0.tgz", + "integrity": "sha512-vG/A5cQrvGGvZm2mTnCSz1LUcbOPl83hfB6bxULKQ8oFZauyox/2xbZOoGNl+64m8VBrETkdGCDBdOsCr3F3jg==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.3.0", + "bson": "^7.0.0", + "mongodb-connection-string-url": "^7.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.806.0", + "@mongodb-js/zstd": "^7.0.0", + "gcp-metadata": "^7.0.1", + "kerberos": "^7.0.0", + "mongodb-client-encryption": ">=7.0.0 <7.1.0", + "snappy": "^7.3.2", + "socks": "^2.8.6" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.0.tgz", + "integrity": "sha512-irhhjRVLE20hbkRl4zpAYLnDMM+zIZnp0IDB9akAFFUZp/3XdOfwwddc7y6cNvF2WCEtfTYRwYbIfYa2kVY0og==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^13.0.0", + "whatwg-url": "^14.1.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/mongoose": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.0.1.tgz", + "integrity": "sha512-aHPfQx2YX5UwAmMVud7OD4lIz9AEO4jI+oDnRh3lPZq9lrKTiHmOzszVffDMyQHXvrf4NXsJ34kpmAhyYAZGbw==", + "license": "MIT", + "dependencies": { + "kareem": "3.0.0", + "mongodb": "~7.0", + "mpath": "0.9.0", + "mquery": "6.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-6.0.0.tgz", + "integrity": "sha512-b2KQNsmgtkscfeDgkYMcWGn9vZI9YoXh802VDEwE6qc50zxBFQ0Oo8ROkawbPAsXCY1/Z1yp0MagqsZStPWJjw==", + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "license": "MIT" + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "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/pino": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-10.1.0.tgz", + "integrity": "sha512-0zZC2ygfdqvqK8zJIr1e+wT1T/L+LF6qvqvbzEQ6tiMAoTqEVK9a1K3YRu8HEUvGEvNqZyPJTtb2sNIoTkB83w==", + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", + "license": "MIT" + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ret": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.5.0.tgz", + "integrity": "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.5.tgz", + "integrity": "sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.5", + "@rollup/rollup-android-arm64": "4.53.5", + "@rollup/rollup-darwin-arm64": "4.53.5", + "@rollup/rollup-darwin-x64": "4.53.5", + "@rollup/rollup-freebsd-arm64": "4.53.5", + "@rollup/rollup-freebsd-x64": "4.53.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.5", + "@rollup/rollup-linux-arm-musleabihf": "4.53.5", + "@rollup/rollup-linux-arm64-gnu": "4.53.5", + "@rollup/rollup-linux-arm64-musl": "4.53.5", + "@rollup/rollup-linux-loong64-gnu": "4.53.5", + "@rollup/rollup-linux-ppc64-gnu": "4.53.5", + "@rollup/rollup-linux-riscv64-gnu": "4.53.5", + "@rollup/rollup-linux-riscv64-musl": "4.53.5", + "@rollup/rollup-linux-s390x-gnu": "4.53.5", + "@rollup/rollup-linux-x64-gnu": "4.53.5", + "@rollup/rollup-linux-x64-musl": "4.53.5", + "@rollup/rollup-openharmony-arm64": "4.53.5", + "@rollup/rollup-win32-arm64-msvc": "4.53.5", + "@rollup/rollup-win32-ia32-msvc": "4.53.5", + "@rollup/rollup-win32-x64-gnu": "4.53.5", + "@rollup/rollup-win32-x64-msvc": "4.53.5", + "fsevents": "~2.3.2" + } + }, + "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==", + "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/safe-regex2": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.0.0.tgz", + "integrity": "sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "ret": "~0.5.0" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/secure-json-parse": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", + "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/sonic-boom": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", + "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/steed": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/steed/-/steed-1.1.3.tgz", + "integrity": "sha512-EUkci0FAUiE4IvGTSKcDJIQ/eRUP2JJb56+fvZ4sdnguLTqIdKjSxUe138poW8mkvKWXW2sFPrgTsxqoISnmoA==", + "license": "MIT", + "dependencies": { + "fastfall": "^1.5.0", + "fastparallel": "^2.2.0", + "fastq": "^1.3.0", + "fastseries": "^1.7.0", + "reusify": "^1.0.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/toad-cache": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", + "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", + "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "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 + } + } + }, + "node_modules/vitest": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.16.tgz", + "integrity": "sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.0.16", + "@vitest/mocker": "4.0.16", + "@vitest/pretty-format": "4.0.16", + "@vitest/runner": "4.0.16", + "@vitest/snapshot": "4.0.16", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.16", + "@vitest/browser-preview": "4.0.16", + "@vitest/browser-webdriverio": "4.0.16", + "@vitest/ui": "4.0.16", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/server/package.json b/server/package.json new file mode 100644 index 0000000..07f6f56 --- /dev/null +++ b/server/package.json @@ -0,0 +1,25 @@ +{ + "name": "zen-kanji-server", + "version": "1.0.0", + "type": "module", + "main": "server.js", + "scripts": { + "start": "node server.js", + "dev": "node --watch server.js", + "test": "vitest", + "test:cov": "vitest run --coverage" + }, + "dependencies": { + "@fastify/cors": "^11.2.0", + "@fastify/jwt": "^10.0.0", + "cors": "^2.8.5", + "fastify": "^5.6.2", + "fastify-cors": "^6.0.3", + "mongoose": "^9.0.1", + "node-fetch": "^3.3.2" + }, + "devDependencies": { + "@vitest/coverage-v8": "^4.0.16", + "vitest": "^4.0.16" + } +} diff --git a/server/server.js b/server/server.js new file mode 100644 index 0000000..e452fc7 --- /dev/null +++ b/server/server.js @@ -0,0 +1,73 @@ +import Fastify from 'fastify'; +import cors from '@fastify/cors'; +import jwt from '@fastify/jwt'; +import { PORT, JWT_SECRET } from './src/config/constants.js'; +import { connectDB } from './src/config/db.js'; +import routes from './src/routes/v1.js'; +import { User } from './src/models/User.js'; + +const fastify = Fastify({ logger: true }); + +await connectDB(); + +const allowedOrigins = [ + 'http://localhost:5173', + 'http://localhost', + 'capacitor://localhost', + 'https://10.0.2.2:5173', + 'https://zenkanji.crylia.de' +]; + +if (process.env.CORS_ORIGINS) { + const prodOrigins = process.env.CORS_ORIGINS.split(','); + allowedOrigins.push(...prodOrigins); +} + +await fastify.register(cors, { + origin: allowedOrigins, + methods: ['GET', 'POST', 'PUT', 'DELETE'], + credentials: true +}); + +await fastify.register(jwt, { + secret: JWT_SECRET +}); + +fastify.decorate('authenticate', async function (req, reply) { + try { + const payload = await req.jwtVerify(); + + const user = await User.findById(payload.userId); + + if (!user) { + reply.code(401).send({ message: 'User not found', code: 'INVALID_USER' }); + return; + } + + if (payload.version !== user.tokenVersion) { + reply.code(401).send({ message: 'Session invalid', code: 'INVALID_SESSION' }); + return; + } + if (payload.version !== user.tokenVersion) { + throw new Error('Session invalid'); + } + + req.user = user; + + } catch (err) { + reply.code(401).send(err); + } +}); + +await fastify.register(routes); + +const start = async () => { + try { + await fastify.listen({ port: PORT, host: '0.0.0.0' }); + console.log(`Server running at http://localhost:${PORT}`); + } catch (err) { + fastify.log.error(err); + process.exit(1); + } +}; +start(); diff --git a/server/src/config/constants.js b/server/src/config/constants.js new file mode 100644 index 0000000..aa4b188 --- /dev/null +++ b/server/src/config/constants.js @@ -0,0 +1,4 @@ +export const PORT = process.env.PORT || 3000; +export const MONGO_URI = process.env.MONGO_URI || 'mongodb://mongo:27017/zenkanji'; +export const SRS_TIMINGS_HOURS = [0, 0, 4, 8, 23, 47]; +export const JWT_SECRET = process.env.JWT_SECRET; diff --git a/server/src/config/db.js b/server/src/config/db.js new file mode 100644 index 0000000..1a36c5d --- /dev/null +++ b/server/src/config/db.js @@ -0,0 +1,12 @@ +import mongoose from 'mongoose'; +import { MONGO_URI } from './constants.js'; + +export const connectDB = async () => { + try { + await mongoose.connect(MONGO_URI); + console.log('✅ Connected to MongoDB'); + } catch (err) { + console.error('❌ MongoDB Connection Error:', err); + process.exit(1); + } +}; diff --git a/server/src/controllers/auth.controller.js b/server/src/controllers/auth.controller.js new file mode 100644 index 0000000..7155d53 --- /dev/null +++ b/server/src/controllers/auth.controller.js @@ -0,0 +1,28 @@ +import * as AuthService from '../services/auth.service.js'; + +export const login = async (req, reply) => { + const { apiKey } = req.body; + if (!apiKey) return reply.code(400).send({ error: 'API Key required' }); + + try { + const user = await AuthService.loginUser(apiKey); + + const token = await reply.jwtSign( + { userId: user._id, version: user.tokenVersion }, + { expiresIn: '365d' } + ); + + return { + success: true, + token, + user: { settings: user.settings, stats: user.stats } + }; + } catch (err) { + return reply.code(401).send({ error: err.message }); + } +}; + +export const logout = async (req, reply) => { + await AuthService.logoutUser(req.user._id); + return { success: true }; +}; diff --git a/server/src/controllers/collection.controller.js b/server/src/controllers/collection.controller.js new file mode 100644 index 0000000..f266c91 --- /dev/null +++ b/server/src/controllers/collection.controller.js @@ -0,0 +1,33 @@ +import { User } from '../models/User.js'; +import * as ReviewService from '../services/review.service.js'; +import * as StatsService from '../services/stats.service.js'; +import { StudyItem } from '../models/StudyItem.js'; + +export const getCollection = async (req, reply) => { + const items = await StudyItem.find({ userId: req.user._id }); + return reply.send(items); +}; + +export const getQueue = async (req, reply) => { + const { limit, sort } = req.query; + const queue = await ReviewService.getQueue(req.user, parseInt(limit) || 20, sort); + return reply.send(queue); +}; + +export const getStats = async (req, reply) => { + const stats = await StatsService.getUserStats(req.user); + return reply.send(stats); +}; + +export const updateSettings = async (req, reply) => { + const { batchSize, drawingAccuracy } = req.body; + const user = req.user; + + if (!user.settings) user.settings = {}; + + if (batchSize) user.settings.batchSize = batchSize; + if (drawingAccuracy) user.settings.drawingAccuracy = drawingAccuracy; + + await user.save(); + return reply.send({ success: true, settings: user.settings }); +}; diff --git a/server/src/controllers/review.controller.js b/server/src/controllers/review.controller.js new file mode 100644 index 0000000..93b8df7 --- /dev/null +++ b/server/src/controllers/review.controller.js @@ -0,0 +1,11 @@ +import * as ReviewService from '../services/review.service.js'; + +export const submitReview = async (req, reply) => { + const { subjectId, success } = req.body; + try { + const result = await ReviewService.processReview(req.user, subjectId, success); + return reply.send(result); + } catch (err) { + return reply.code(404).send({ error: err.message }); + } +}; diff --git a/server/src/controllers/sync.controller.js b/server/src/controllers/sync.controller.js new file mode 100644 index 0000000..b6073df --- /dev/null +++ b/server/src/controllers/sync.controller.js @@ -0,0 +1,10 @@ +import * as SyncService from '../services/sync.service.js'; + +export const sync = async (req, reply) => { + try { + const result = await SyncService.syncWithWaniKani(req.user); + return reply.send(result); + } catch (error) { + return reply.code(500).send({ error: error.message }); + } +}; diff --git a/server/src/models/ReviewLog.js b/server/src/models/ReviewLog.js new file mode 100644 index 0000000..1aef20a --- /dev/null +++ b/server/src/models/ReviewLog.js @@ -0,0 +1,10 @@ +import mongoose from 'mongoose'; + +const reviewLogSchema = new mongoose.Schema({ + userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, + date: { type: String, required: true }, + count: { type: Number, default: 0 } +}); + +reviewLogSchema.index({ userId: 1, date: 1 }, { unique: true }); +export const ReviewLog = mongoose.model('ReviewLog', reviewLogSchema); diff --git a/server/src/models/StudyItem.js b/server/src/models/StudyItem.js new file mode 100644 index 0000000..005f8cf --- /dev/null +++ b/server/src/models/StudyItem.js @@ -0,0 +1,21 @@ +import mongoose from 'mongoose'; + +const studyItemSchema = new mongoose.Schema({ + userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, + wkSubjectId: { type: Number, required: true }, + char: { type: String, required: true }, + meaning: { type: String, required: true }, + level: { type: Number, required: true }, + srsLevel: { type: Number, default: 0 }, + nextReview: { type: Date, default: Date.now }, + onyomi: { type: [String], default: [] }, + kunyomi: { type: [String], default: [] }, + nanori: { type: [String], default: [] }, + stats: { + correct: { type: Number, default: 0 }, + total: { type: Number, default: 0 } + } +}); + +studyItemSchema.index({ userId: 1, wkSubjectId: 1 }, { unique: true }); +export const StudyItem = mongoose.model('StudyItem', studyItemSchema); diff --git a/server/src/models/User.js b/server/src/models/User.js new file mode 100644 index 0000000..816e586 --- /dev/null +++ b/server/src/models/User.js @@ -0,0 +1,21 @@ +import mongoose from 'mongoose'; + +const userSchema = new mongoose.Schema({ + wkApiKey: { type: String, required: true, unique: true }, + lastSync: { type: Date, default: Date.now }, + settings: { + batchSize: { type: Number, default: 20 }, + drawingAccuracy: { type: Number, default: 10 } + }, + tokenVersion: { type: Number, default: 0 }, + stats: { + totalReviews: { type: Number, default: 0 }, + correctReviews: { type: Number, default: 0 }, + currentStreak: { type: Number, default: 0 }, + maxStreak: { type: Number, default: 0 }, + lastStudyDate: { type: String, default: null }, + lastFreezeDate: { type: Date, default: null } + } +}); + +export const User = mongoose.model('User', userSchema); diff --git a/server/src/routes/v1.js b/server/src/routes/v1.js new file mode 100644 index 0000000..d75d6e1 --- /dev/null +++ b/server/src/routes/v1.js @@ -0,0 +1,22 @@ +import { login, logout } from '../controllers/auth.controller.js'; +import { sync } from '../controllers/sync.controller.js'; +import { submitReview } from '../controllers/review.controller.js'; +import { getStats, getQueue, getCollection, updateSettings } from '../controllers/collection.controller.js'; + +async function routes(fastify, options) { + fastify.post('/api/auth/login', login); + + fastify.register(async (privateParams) => { + privateParams.addHook('onRequest', fastify.authenticate); + + privateParams.post('/api/auth/logout', logout); + privateParams.post('/api/sync', sync); + privateParams.post('/api/review', submitReview); + privateParams.get('/api/stats', getStats); + privateParams.get('/api/queue', getQueue); + privateParams.get('/api/collection', getCollection); + privateParams.post('/api/settings', updateSettings); + }); +} + +export default routes; diff --git a/server/src/services/auth.service.js b/server/src/services/auth.service.js new file mode 100644 index 0000000..da80370 --- /dev/null +++ b/server/src/services/auth.service.js @@ -0,0 +1,29 @@ +import { User } from '../models/User.js'; + +export const loginUser = async (apiKey) => { + const response = await fetch('https://api.wanikani.com/v2/user', { + headers: { Authorization: `Bearer ${apiKey}` } + }); + + if (response.status !== 200) { + throw new Error('Invalid API Key'); + } + + let user = await User.findOne({ wkApiKey: apiKey }); + + if (!user) { + user = await User.create({ + wkApiKey: apiKey, + tokenVersion: 0, + stats: { totalReviews: 0, correctReviews: 0, currentStreak: 0, maxStreak: 0 }, + settings: { batchSize: 20 } + }); + } + + return user; +}; + +export const logoutUser = async (userId) => { + await User.findByIdAndUpdate(userId, { $inc: { tokenVersion: 1 } }); + return true; +}; diff --git a/server/src/services/review.service.js b/server/src/services/review.service.js new file mode 100644 index 0000000..67343df --- /dev/null +++ b/server/src/services/review.service.js @@ -0,0 +1,85 @@ +import { ReviewLog } from '../models/ReviewLog.js'; +import { StudyItem } from '../models/StudyItem.js'; +import { getDaysDiff, getSRSDate } from '../utils/dateUtils.js'; + +export const processReview = async (user, subjectId, success) => { + if (!user.stats) user.stats = { totalReviews: 0, correctReviews: 0, currentStreak: 0, maxStreak: 0 }; + user.stats.totalReviews += 1; + if (success) user.stats.correctReviews += 1; + + const todayStr = new Date().toISOString().split('T')[0]; + const lastStudyStr = user.stats.lastStudyDate; + + if (lastStudyStr !== todayStr) { + if (!lastStudyStr) { + user.stats.currentStreak = 1; + } else { + const diff = getDaysDiff(lastStudyStr, todayStr); + if (diff === 1) { + user.stats.currentStreak += 1; + } else if (diff > 1) { + const lastFreeze = user.stats.lastFreezeDate ? new Date(user.stats.lastFreezeDate) : null; + let daysSinceFreeze = 999; + if (lastFreeze) daysSinceFreeze = getDaysDiff(lastFreeze.toISOString().split('T')[0], todayStr); + + const canUseShield = daysSinceFreeze >= 7; + + if (canUseShield && diff === 2) { + console.log(`User ${user._id} saved by Zen Shield!`); + user.stats.lastFreezeDate = new Date(); + user.stats.currentStreak += 1; + } else { + user.stats.currentStreak = 1; + } + } + } + user.stats.lastStudyDate = todayStr; + if (user.stats.currentStreak > user.stats.maxStreak) user.stats.maxStreak = user.stats.currentStreak; + } + await user.save(); + + await ReviewLog.findOneAndUpdate( + { userId: user._id, date: todayStr }, + { $inc: { count: 1 } }, + { upsert: true, new: true } + ); + + const item = await StudyItem.findOne({ userId: user._id, wkSubjectId: subjectId }); + if (!item) throw new Error('Item not found'); + + if (!item.stats) item.stats = { correct: 0, total: 0 }; + item.stats.total += 1; + if (success) item.stats.correct += 1; + + if (success) { + const nextLevel = Math.min(item.srsLevel + 1, 10); + item.srsLevel = nextLevel; + item.nextReview = getSRSDate(nextLevel); + } else { + item.srsLevel = Math.max(1, item.srsLevel - 1); + item.nextReview = Date.now(); + } + + await item.save(); + return { nextReview: item.nextReview, srsLevel: item.srsLevel }; +}; + +export const getQueue = async (user, limit = 100, sortMode) => { + const query = { + userId: user._id, + srsLevel: { $lt: 10, $gt: 0 }, + nextReview: { $lte: new Date() } + }; + + let dueItems; + if (sortMode === 'priority') { + dueItems = await StudyItem.find(query).sort({ srsLevel: 1, level: 1 }).limit(limit); + } else { + dueItems = await StudyItem.find(query).limit(limit); + for (let i = dueItems.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [dueItems[i], dueItems[j]] = [dueItems[j], dueItems[i]]; + } + } + return dueItems; +}; diff --git a/server/src/services/stats.service.js b/server/src/services/stats.service.js new file mode 100644 index 0000000..2a57d6f --- /dev/null +++ b/server/src/services/stats.service.js @@ -0,0 +1,112 @@ +import { StudyItem } from '../models/StudyItem.js'; +import { ReviewLog } from '../models/ReviewLog.js'; +import { getDaysDiff } from '../utils/dateUtils.js'; + +export const getUserStats = async (user) => { + const userId = user._id; + + const srsCounts = await StudyItem.aggregate([ + { $match: { userId: userId } }, + { $group: { _id: "$srsLevel", count: { $sum: 1 } } } + ]); + const dist = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 }; + srsCounts.forEach(g => { if (dist[g._id] !== undefined) dist[g._id] = g.count; }); + + const now = new Date(); + const next24h = new Date(now.getTime() + 24 * 60 * 60 * 1000); + const upcoming = await StudyItem.find({ + userId: userId, + srsLevel: { $lt: 6, $gt: 0 }, + nextReview: { $lte: next24h } + }).select('nextReview'); + + const forecast = new Array(24).fill(0); + upcoming.forEach(item => { + const diff = Math.floor((new Date(item.nextReview) - now) / 3600000); + if (diff < 0) forecast[0]++; + else if (diff < 24) forecast[diff]++; + }); + + const queueItems = await StudyItem.find({ + userId: userId, + srsLevel: { $lt: 6, $gt: 0 }, + nextReview: { $lte: now } + }).select('srsLevel'); + const queueCount = queueItems.length; + + let hasLowerLevels = false; + let lowerLevelCount = 0; + if (queueCount > 0) { + const levels = queueItems.map(i => i.srsLevel); + const minSrs = Math.min(...levels); + const maxSrs = Math.max(...levels); + if (minSrs < maxSrs) { + hasLowerLevels = true; + lowerLevelCount = queueItems.filter(i => i.srsLevel === minSrs).length; + } + } + + const oneYearAgo = new Date(); + oneYearAgo.setDate(oneYearAgo.getDate() - 365); + const dateStr = oneYearAgo.toISOString().split('T')[0]; + const logs = await ReviewLog.find({ userId: userId, date: { $gte: dateStr } }); + const heatmap = {}; + logs.forEach(l => { heatmap[l.date] = l.count; }); + + const todayStr = new Date().toISOString().split('T')[0]; + const lastStudyStr = user.stats.lastStudyDate || null; + let displayStreak = user.stats.currentStreak || 0; + + if (lastStudyStr) { + const diff = getDaysDiff(lastStudyStr, todayStr); + if (diff > 1) displayStreak = 0; + } + + const lastFreeze = user.stats.lastFreezeDate ? new Date(user.stats.lastFreezeDate) : null; + let daysSinceFreeze = 999; + if (lastFreeze) { + daysSinceFreeze = getDaysDiff(lastFreeze.toISOString().split('T')[0], todayStr); + } + + const shieldReady = daysSinceFreeze >= 7; + const shieldCooldown = shieldReady ? 0 : (7 - daysSinceFreeze); + + const history7Days = []; + for (let i = 6; i >= 0; i--) { + const d = new Date(); + d.setDate(d.getDate() - i); + const dStr = d.toISOString().split('T')[0]; + const count = heatmap[dStr] || 0; + history7Days.push({ date: dStr, active: count > 0 }); + } + + const allGhosts = await StudyItem.find({ userId: userId, 'stats.total': { $gte: 2 } }) + .select('char meaning stats srsLevel'); + + const sortedGhosts = allGhosts.map(item => ({ + ...item.toObject(), + accuracy: Math.round((item.stats.correct / item.stats.total) * 100) + })).filter(i => i.accuracy < 85) + .sort((a, b) => a.accuracy - b.accuracy) + .slice(0, 4); + + return { + distribution: dist, + forecast: forecast, + queueLength: queueCount, + hasLowerLevels, + lowerLevelCount, + heatmap: heatmap, + ghosts: sortedGhosts, + streak: { + current: displayStreak, + best: user.stats.maxStreak || 0, + shield: { ready: shieldReady, cooldown: Math.max(0, shieldCooldown) }, + history: history7Days + }, + accuracy: { + total: user.stats.totalReviews || 0, + correct: user.stats.correctReviews || 0 + } + }; +}; diff --git a/server/src/services/sync.service.js b/server/src/services/sync.service.js new file mode 100644 index 0000000..9bd8557 --- /dev/null +++ b/server/src/services/sync.service.js @@ -0,0 +1,78 @@ +import { User } from '../models/User.js'; +import { StudyItem } from '../models/StudyItem.js'; + +export const syncWithWaniKani = async (user) => { + const apiKey = user.wkApiKey; + + if (!apiKey) { + throw new Error('User has no WaniKani API Key'); + } + + console.log(`Starting sync for user: ${user._id}`); + + let allSubjectIds = []; + let nextUrl = 'https://api.wanikani.com/v2/assignments?subject_types=kanji&started=true'; + + try { + while (nextUrl) { + const res = await fetch(nextUrl, { + headers: { Authorization: `Bearer ${apiKey}` } + }); + + if (!res.ok) { + throw new Error(`WaniKani API Error: ${res.statusText}`); + } + + const json = await res.json(); + allSubjectIds = allSubjectIds.concat(json.data.map(d => d.data.subject_id)); + nextUrl = json.pages.next_url; + } + } catch (err) { + console.error("Error fetching assignments:", err); + throw new Error("Failed to connect to WaniKani. Check your internet connection."); + } + + if (allSubjectIds.length === 0) { + return { count: 0, message: "No unlocked kanji found.", settings: user.settings }; + } + + const existingItems = await StudyItem.find({ userId: user._id }).select('wkSubjectId'); + const existingIds = new Set(existingItems.map(i => i.wkSubjectId)); + const newIds = allSubjectIds.filter(id => !existingIds.has(id)); + + console.log(`Found ${newIds.length} new items to download.`); + + const CHUNK_SIZE = 100; + for (let i = 0; i < newIds.length; i += CHUNK_SIZE) { + const chunk = newIds.slice(i, i + CHUNK_SIZE); + + const subRes = await fetch(`https://api.wanikani.com/v2/subjects?ids=${chunk.join(',')}`, { + headers: { Authorization: `Bearer ${apiKey}` } + }); + const subJson = await subRes.json(); + + const operations = subJson.data.map(d => { + const readings = d.data.readings || []; + return { + userId: user._id, + wkSubjectId: d.id, + char: d.data.characters, + meaning: d.data.meanings.find(m => m.primary)?.meaning || 'Unknown', + level: d.data.level, + srsLevel: 1, + nextReview: Date.now(), + onyomi: readings.filter(r => r.type === 'onyomi').map(r => r.reading), + kunyomi: readings.filter(r => r.type === 'kunyomi').map(r => r.reading), + nanori: readings.filter(r => r.type === 'nanori').map(r => r.reading), + stats: { correct: 0, total: 0 } + }; + }); + + if (operations.length > 0) { + await StudyItem.insertMany(operations); + } + } + + const finalCount = await StudyItem.countDocuments({ userId: user._id }); + return { success: true, count: finalCount, settings: user.settings }; +}; diff --git a/server/src/utils/dateUtils.js b/server/src/utils/dateUtils.js new file mode 100644 index 0000000..f3df4c8 --- /dev/null +++ b/server/src/utils/dateUtils.js @@ -0,0 +1,32 @@ +export const getDaysDiff = (date1Str, date2Str) => { + const d1 = new Date(date1Str); + const d2 = new Date(date2Str); + const diff = d2 - d1; + return Math.floor(diff / (1000 * 60 * 60 * 24)); +}; + +export const getSRSDate = (level) => { + const now = new Date(); + let hoursToAdd = 0; + + switch (level) { + case 1: hoursToAdd = 4; break; + case 2: hoursToAdd = 8; break; + case 3: hoursToAdd = 24; break; + case 4: hoursToAdd = 2 * 24; break; + case 5: hoursToAdd = 7 * 24; break; + case 6: hoursToAdd = 14 * 24; break; + + case 7: hoursToAdd = 7 * 24; break; + case 8: hoursToAdd = 30 * 24; break; + case 9: hoursToAdd = 90 * 24; break; + + case 10: break; + default: hoursToAdd = 4; + } + + if (hoursToAdd === 0) return null; + + now.setUTCHours(now.getUTCHours() + hoursToAdd); + return now; +}; diff --git a/server/tests/services/auth.service.test.js b/server/tests/services/auth.service.test.js new file mode 100644 index 0000000..3f5037a --- /dev/null +++ b/server/tests/services/auth.service.test.js @@ -0,0 +1,52 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { loginUser, logoutUser } from '../../src/services/auth.service.js'; +import { User } from '../../src/models/User.js'; + +vi.mock('../../src/models/User.js'); +global.fetch = vi.fn(); + +describe('Auth Service', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + describe('loginUser', () => { + it('should throw error for invalid API Key', async () => { + fetch.mockResolvedValue({ status: 401 }); + await expect(loginUser('bad_key')).rejects.toThrow('Invalid API Key'); + }); + + it('should return existing user if found', async () => { + fetch.mockResolvedValue({ status: 200 }); + const mockUser = { wkApiKey: 'valid_key', _id: '123' }; + User.findOne.mockResolvedValue(mockUser); + + const result = await loginUser('valid_key'); + expect(result).toEqual(mockUser); + expect(User.create).not.toHaveBeenCalled(); + }); + + it('should create new user if not found', async () => { + fetch.mockResolvedValue({ status: 200 }); + User.findOne.mockResolvedValue(null); + const newUser = { wkApiKey: 'valid_key', _id: 'new_id' }; + User.create.mockResolvedValue(newUser); + + const result = await loginUser('valid_key'); + expect(result).toEqual(newUser); + expect(User.create).toHaveBeenCalledWith(expect.objectContaining({ + wkApiKey: 'valid_key', + tokenVersion: 0 + })); + }); + }); + + describe('logoutUser', () => { + it('should increment token version', async () => { + User.findByIdAndUpdate.mockResolvedValue(true); + const result = await logoutUser('userId'); + expect(User.findByIdAndUpdate).toHaveBeenCalledWith('userId', { $inc: { tokenVersion: 1 } }); + expect(result).toBe(true); + }); + }); +}); diff --git a/server/tests/services/controllers.test.js b/server/tests/services/controllers.test.js new file mode 100644 index 0000000..4f6153d --- /dev/null +++ b/server/tests/services/controllers.test.js @@ -0,0 +1,142 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import * as AuthController from '../../src/controllers/auth.controller.js'; +import * as ReviewController from '../../src/controllers/review.controller.js'; +import * as SyncController from '../../src/controllers/sync.controller.js'; +import * as CollectionController from '../../src/controllers/collection.controller.js'; + +import * as AuthService from '../../src/services/auth.service.js'; +import * as ReviewService from '../../src/services/review.service.js'; +import * as SyncService from '../../src/services/sync.service.js'; +import * as StatsService from '../../src/services/stats.service.js'; +import { StudyItem } from '../../src/models/StudyItem.js'; + +vi.mock('../../src/services/auth.service.js'); +vi.mock('../../src/services/review.service.js'); +vi.mock('../../src/services/sync.service.js'); +vi.mock('../../src/services/stats.service.js'); +vi.mock('../../src/models/StudyItem.js'); + +const mockReq = (body = {}, user = {}, query = {}) => ({ body, user, query }); +const mockReply = () => { + const res = {}; + res.code = vi.fn().mockReturnValue(res); + res.send = vi.fn().mockReturnValue(res); + res.jwtSign = vi.fn().mockResolvedValue('token'); + return res; +}; + +describe('Controllers', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + describe('Auth Controller', () => { + it('login should fail without apiKey', async () => { + const reply = mockReply(); + await AuthController.login(mockReq({}), reply); + expect(reply.code).toHaveBeenCalledWith(400); + }); + + it('login should succeed', async () => { + const reply = mockReply(); + AuthService.loginUser.mockResolvedValue({ _id: 1, tokenVersion: 1 }); + await AuthController.login(mockReq({ apiKey: 'key' }), reply); + expect(reply.jwtSign).toHaveBeenCalled(); + expect(reply.code).not.toHaveBeenCalledWith(401); + }); + + it('login should catch errors', async () => { + const reply = mockReply(); + AuthService.loginUser.mockRejectedValue(new Error('fail')); + await AuthController.login(mockReq({ apiKey: 'k' }), reply); + expect(reply.code).toHaveBeenCalledWith(401); + }); + + it('logout should succeed', async () => { + const reply = mockReply(); + await AuthController.logout(mockReq({}, { _id: 1 }), reply); + expect(AuthService.logoutUser).toHaveBeenCalled(); + }); + }); + + describe('Review Controller', () => { + it('submitReview should succeed', async () => { + const reply = mockReply(); + ReviewService.processReview.mockResolvedValue({}); + await ReviewController.submitReview(mockReq({}), reply); + expect(reply.send).toHaveBeenCalled(); + }); + + it('submitReview should handle error', async () => { + const reply = mockReply(); + ReviewService.processReview.mockRejectedValue(new Error('err')); + await ReviewController.submitReview(mockReq({}), reply); + expect(reply.code).toHaveBeenCalledWith(404); + }); + }); + + describe('Sync Controller', () => { + it('sync should succeed', async () => { + const reply = mockReply(); + SyncService.syncWithWaniKani.mockResolvedValue({}); + await SyncController.sync(mockReq({}, {}), reply); + expect(reply.send).toHaveBeenCalled(); + }); + + it('sync should handle error', async () => { + const reply = mockReply(); + SyncService.syncWithWaniKani.mockRejectedValue(new Error('err')); + await SyncController.sync(mockReq({}, {}), reply); + expect(reply.code).toHaveBeenCalledWith(500); + }); + }); + + describe('Collection Controller', () => { + it('getCollection should return items', async () => { + const reply = mockReply(); + StudyItem.find.mockResolvedValue([]); + await CollectionController.getCollection(mockReq({}, { _id: 1 }), reply); + expect(reply.send).toHaveBeenCalledWith([]); + }); + + it('getQueue should call service with default limit', async () => { + const reply = mockReply(); + ReviewService.getQueue.mockResolvedValue([]); + await CollectionController.getQueue(mockReq({}, {}, {}), reply); + expect(ReviewService.getQueue).toHaveBeenCalledWith(expect.anything(), 20, undefined); + }); + + it('getQueue should call service with provided limit', async () => { + const reply = mockReply(); + ReviewService.getQueue.mockResolvedValue([]); + await CollectionController.getQueue(mockReq({}, {}, { limit: '50' }), reply); + expect(ReviewService.getQueue).toHaveBeenCalledWith(expect.anything(), 50, undefined); + }); + + it('getStats should call service', async () => { + const reply = mockReply(); + StatsService.getUserStats.mockResolvedValue({}); + await CollectionController.getStats(mockReq({}, {}), reply); + expect(StatsService.getUserStats).toHaveBeenCalled(); + }); + + it('updateSettings should initialize settings if missing', async () => { + const reply = mockReply(); + const save = vi.fn(); + const user = { save }; + await CollectionController.updateSettings(mockReq({ batchSize: 50 }, user), reply); + expect(user.settings).toBeDefined(); + expect(user.settings.batchSize).toBe(50); + expect(save).toHaveBeenCalled(); + }); + + it('updateSettings should update drawingAccuracy', async () => { + const reply = mockReply(); + const save = vi.fn(); + const user = { settings: {}, save }; + await CollectionController.updateSettings(mockReq({ drawingAccuracy: 5 }, user), reply); + expect(user.settings.drawingAccuracy).toBe(5); + expect(save).toHaveBeenCalled(); + }); + }); +}); diff --git a/server/tests/services/review.service.test.js b/server/tests/services/review.service.test.js new file mode 100644 index 0000000..f68dc5c --- /dev/null +++ b/server/tests/services/review.service.test.js @@ -0,0 +1,144 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import * as ReviewService from '../../src/services/review.service.js'; +import { User } from '../../src/models/User.js'; +import { ReviewLog } from '../../src/models/ReviewLog.js'; +import { StudyItem } from '../../src/models/StudyItem.js'; + +vi.mock('../../src/models/ReviewLog.js'); +vi.mock('../../src/models/StudyItem.js'); + +describe('Review Service', () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date('2023-01-10T00:00:00Z')); + }); + + afterEach(() => { + vi.useRealTimers(); + vi.resetAllMocks(); + }); + + describe('processReview', () => { + const mockUser = (stats = {}) => ({ + _id: 'u1', + stats: { ...stats }, + save: vi.fn() + }); + + const mockItem = (srs = 1) => ({ + userId: 'u1', + wkSubjectId: 100, + srsLevel: srs, + stats: { correct: 0, total: 0 }, + save: vi.fn(), + nextReview: null + }); + + it('should throw error if item not found', async () => { + const user = mockUser(); + StudyItem.findOne.mockResolvedValue(null); + + await expect(ReviewService.processReview(user, 999, true)) + .rejects.toThrow('Item not found'); + + expect(StudyItem.findOne).toHaveBeenCalledWith({ + userId: user._id, + wkSubjectId: 999 + }); + }); + + it('should handle standard success flow', async () => { + const user = mockUser(); + delete user.stats; + StudyItem.findOne.mockResolvedValue(mockItem()); + const res = await ReviewService.processReview(user, 100, true); + expect(user.save).toHaveBeenCalled(); + expect(res.srsLevel).toBe(2); + }); + + it('should handle failure flow', async () => { + const user = mockUser(); + const item = mockItem(2); + StudyItem.findOne.mockResolvedValue(item); + await ReviewService.processReview(user, 100, false); + expect(item.srsLevel).toBe(1); + }); + + it('should increment streak (diff = 1)', async () => { + const user = mockUser({ lastStudyDate: '2023-01-09', currentStreak: 5 }); + StudyItem.findOne.mockResolvedValue(mockItem()); + await ReviewService.processReview(user, 100, true); + expect(user.stats.currentStreak).toBe(6); + }); + + it('should maintain streak (diff = 0)', async () => { + const user = mockUser({ lastStudyDate: '2023-01-10', currentStreak: 5 }); + StudyItem.findOne.mockResolvedValue(mockItem()); + await ReviewService.processReview(user, 100, true); + expect(user.stats.currentStreak).toBe(5); + }); + + it('should reset streak (diff > 1, no shield)', async () => { + const user = mockUser({ lastStudyDate: '2023-01-08', currentStreak: 5, lastFreezeDate: '2023-01-09' }); + StudyItem.findOne.mockResolvedValue(mockItem()); + await ReviewService.processReview(user, 100, true); + expect(user.stats.currentStreak).toBe(1); + }); + + it('should use shield (diff = 2, shield ready)', async () => { + const user = mockUser({ lastStudyDate: '2023-01-08', currentStreak: 5, lastFreezeDate: '2022-01-01' }); + StudyItem.findOne.mockResolvedValue(mockItem()); + await ReviewService.processReview(user, 100, true); + expect(user.stats.currentStreak).toBe(6); + expect(user.stats.lastFreezeDate).toBeDefined(); + }); + + it('should use shield (diff = 2) when lastFreezeDate is undefined', async () => { + const user = mockUser({ lastStudyDate: '2023-01-08', currentStreak: 5 }); + user.stats.lastFreezeDate = null; + + StudyItem.findOne.mockResolvedValue(mockItem()); + + await ReviewService.processReview(user, 100, true); + + expect(user.stats.currentStreak).toBe(6); + expect(user.stats.lastFreezeDate).toBeDefined(); + }); + + it('should initialize item stats if missing', async () => { + const user = mockUser(); + const item = mockItem(); + delete item.stats; + StudyItem.findOne.mockResolvedValue(item); + + await ReviewService.processReview(user, 100, true); + + expect(item.stats).toEqual(expect.objectContaining({ correct: 1, total: 1 })); + }); + + it('should not break on time travel (diff < 0)', async () => { + const user = mockUser({ lastStudyDate: '2023-01-11', currentStreak: 5 }); + StudyItem.findOne.mockResolvedValue(mockItem()); + + await ReviewService.processReview(user, 100, true); + + expect(user.stats.lastStudyDate).toBe('2023-01-10'); + expect(user.stats.currentStreak).toBe(5); + }); + }); + + describe('getQueue', () => { + it('should sort by priority', async () => { + const mockFind = { sort: vi.fn().mockReturnThis(), limit: vi.fn().mockResolvedValue([]) }; + StudyItem.find.mockReturnValue(mockFind); + await ReviewService.getQueue({ _id: 'u1' }, 10, 'priority'); + expect(mockFind.sort).toHaveBeenCalled(); + }); + it('should shuffle (default)', async () => { + const mockFind = { limit: vi.fn().mockResolvedValue([1, 2]) }; + StudyItem.find.mockReturnValue(mockFind); + await ReviewService.getQueue({ _id: 'u1' }, 10, 'random'); + expect(mockFind.limit).toHaveBeenCalled(); + }); + }); +}); diff --git a/server/tests/services/stats.service.test.js b/server/tests/services/stats.service.test.js new file mode 100644 index 0000000..da16f92 --- /dev/null +++ b/server/tests/services/stats.service.test.js @@ -0,0 +1,147 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { getUserStats } from '../../src/services/stats.service.js'; +import { StudyItem } from '../../src/models/StudyItem.js'; +import { ReviewLog } from '../../src/models/ReviewLog.js'; + +vi.mock('../../src/models/StudyItem.js'); +vi.mock('../../src/models/ReviewLog.js'); + +describe('Stats Service', () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date('2023-01-10T12:00:00Z')); + }); + afterEach(() => { + vi.useRealTimers(); + vi.clearAllMocks(); + }); + + const mockUser = { + _id: 'u1', + stats: { + totalReviews: 10, + correctReviews: 8, + currentStreak: 5, + lastStudyDate: '2023-01-10', + lastFreezeDate: '2022-01-01' + } + }; + + it('should calculate stats correctly including ghosts, forecast, and unknown SRS levels', async () => { + StudyItem.aggregate.mockResolvedValue([ + { _id: 1, count: 5 }, + { _id: 8, count: 2 } + ]); + + StudyItem.find.mockImplementation(() => ({ + select: vi.fn().mockImplementation((fields) => { + if (fields.includes('nextReview')) { + const now = new Date(); + return Promise.resolve([ + { nextReview: new Date(now.getTime() - 1000) }, + { nextReview: new Date(now.getTime() + 3600000) }, + { nextReview: new Date(now.getTime() + 24 * 3600000) } + ]); + } + if (fields.includes('stats')) { + const mkGhost = (acc) => ({ + char: 'A', meaning: 'B', stats: { correct: acc, total: 100 }, srsLevel: 1, + toObject: () => ({ char: 'A', meaning: 'B', stats: { correct: acc, total: 100 }, srsLevel: 1 }) + }); + return Promise.resolve([mkGhost(60), mkGhost(50), mkGhost(90)]); + } + if (fields.includes('srsLevel')) { + return Promise.resolve([{ srsLevel: 1 }, { srsLevel: 4 }]); + } + return Promise.resolve([]); + }) + })); + + ReviewLog.find.mockResolvedValue([ + { date: '2023-01-09', count: 5 } + ]); + + const stats = await getUserStats(mockUser); + + expect(stats.forecast[0]).toBe(1); + expect(stats.forecast[1]).toBe(1); + + expect(stats.ghosts.length).toBe(2); + expect(stats.ghosts[0].accuracy).toBe(50); + expect(stats.ghosts[1].accuracy).toBe(60); + + expect(stats.distribution[1]).toBe(5); + expect(stats.distribution[8]).toBeUndefined(); + + expect(stats.heatmap['2023-01-09']).toBe(5); + }); + + it('should handle queue with same levels (hasLowerLevels = false)', async () => { + StudyItem.aggregate.mockResolvedValue([]); + StudyItem.find.mockImplementation(() => ({ + select: vi.fn().mockImplementation((fields) => { + if (fields.includes('stats')) { + return Promise.resolve([]); + } + + if (fields.includes('srsLevel')) { + return Promise.resolve([{ srsLevel: 2 }, { srsLevel: 2 }]); + } + return Promise.resolve([]); + }) + })); + ReviewLog.find.mockResolvedValue([]); + + const stats = await getUserStats(mockUser); + expect(stats.hasLowerLevels).toBe(false); + }); + + it('should calculate shield cooldown', async () => { + StudyItem.aggregate.mockResolvedValue([]); + StudyItem.find.mockReturnValue({ select: vi.fn().mockResolvedValue([]) }); + ReviewLog.find.mockResolvedValue([]); + + const frozenUser = { + ...mockUser, + stats: { ...mockUser.stats, lastFreezeDate: '2023-01-07' } + }; + + const stats = await getUserStats(frozenUser); + expect(stats.streak.shield.ready).toBe(false); + expect(stats.streak.shield.cooldown).toBe(4); + }); + + it('should handle streak logic when lastStudyDate is missing or old', async () => { + const userNoDate = { ...mockUser, stats: { ...mockUser.stats, lastStudyDate: null, currentStreak: 5 } }; + StudyItem.aggregate.mockResolvedValue([]); + StudyItem.find.mockReturnValue({ select: vi.fn().mockResolvedValue([]) }); + ReviewLog.find.mockResolvedValue([]); + + const res1 = await getUserStats(userNoDate); + expect(res1.streak.current).toBe(5); + + const userMissed = { ...mockUser, stats: { ...mockUser.stats, lastStudyDate: '2023-01-08' } }; + const res2 = await getUserStats(userMissed); + expect(res2.streak.current).toBe(0); + }); + + it('should handle missing user stats fields (null checks)', async () => { + const emptyUser = { + _id: 'u2', + stats: {} + }; + + StudyItem.aggregate.mockResolvedValue([]); + StudyItem.find.mockReturnValue({ select: vi.fn().mockResolvedValue([]) }); + ReviewLog.find.mockResolvedValue([]); + + const stats = await getUserStats(emptyUser); + + expect(stats.streak.current).toBe(0); + expect(stats.streak.best).toBe(0); + expect(stats.accuracy.total).toBe(0); + expect(stats.accuracy.correct).toBe(0); + + expect(stats.streak.shield.ready).toBe(true); + }); +}); diff --git a/server/tests/services/sync.service.test.js b/server/tests/services/sync.service.test.js new file mode 100644 index 0000000..27aa9c5 --- /dev/null +++ b/server/tests/services/sync.service.test.js @@ -0,0 +1,212 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { syncWithWaniKani } from '../../src/services/sync.service.js'; +import { StudyItem } from '../../src/models/StudyItem.js'; + +vi.mock('../../src/models/StudyItem.js'); +global.fetch = vi.fn(); + +describe('Sync Service', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + const mockUser = { _id: 'u1', wkApiKey: 'key', settings: {} }; + + it('should throw if no API key', async () => { + await expect(syncWithWaniKani({})) + .rejects.toThrow('User has no WaniKani API Key'); + }); + + it('should handle API fetch error', async () => { + fetch.mockResolvedValue({ ok: false, statusText: 'Unauthorized' }); + await expect(syncWithWaniKani(mockUser)) + .rejects.toThrow('Failed to connect to WaniKani'); + }); + + it('should return 0 if no unlocked kanji', async () => { + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: [], pages: { next_url: null } }) + }); + + const res = await syncWithWaniKani(mockUser); + expect(res.count).toBe(0); + expect(res.message).toContain('No unlocked kanji'); + }); + + it('should sync new items with full reading data', async () => { + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: [{ data: { subject_id: 101 } }], + pages: { next_url: null } + }) + }); + + StudyItem.find.mockReturnValue({ select: vi.fn().mockResolvedValue([]) }); + + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: [{ + id: 101, + data: { + characters: 'A', + meanings: [{ primary: true, meaning: 'A_Meaning' }], + level: 5, + readings: [ + { type: 'onyomi', reading: 'on' }, + { type: 'kunyomi', reading: 'kun' }, + { type: 'nanori', reading: 'nan' } + ] + } + }] + }) + }); + + StudyItem.insertMany.mockResolvedValue(true); + StudyItem.countDocuments.mockResolvedValue(1); + + await syncWithWaniKani(mockUser); + + expect(StudyItem.insertMany).toHaveBeenCalledWith(expect.arrayContaining([ + expect.objectContaining({ + wkSubjectId: 101, + onyomi: ['on'], + kunyomi: ['kun'], + nanori: ['nan'] + }) + ])); + }); + + it('should filter out existing items', async () => { + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: [ + { data: { subject_id: 101 } }, + { data: { subject_id: 102 } } + ], + pages: { next_url: null } + }) + }); + + StudyItem.find.mockReturnValue({ + select: vi.fn().mockResolvedValue([{ wkSubjectId: 102 }]) + }); + + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: [{ + id: 101, + data: { + characters: 'New', + meanings: [], + level: 1, + readings: [] + } + }] + }) + }); + + StudyItem.insertMany.mockResolvedValue(true); + StudyItem.countDocuments.mockResolvedValue(2); + + await syncWithWaniKani(mockUser); + + expect(StudyItem.insertMany).toHaveBeenCalledTimes(1); + expect(StudyItem.insertMany).toHaveBeenCalledWith(expect.arrayContaining([ + expect.objectContaining({ wkSubjectId: 101 }) + ])); + expect(StudyItem.insertMany).not.toHaveBeenCalledWith(expect.arrayContaining([ + expect.objectContaining({ wkSubjectId: 102 }) + ])); + }); + + it('should handle assignment pagination', async () => { + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: [{ data: { subject_id: 1 } }], + pages: { next_url: 'http://next-page' } + }) + }); + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: [{ data: { subject_id: 2 } }], + pages: { next_url: null } + }) + }); + + StudyItem.find.mockReturnValue({ select: vi.fn().mockResolvedValue([]) }); + + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: [] }) + }); + + StudyItem.countDocuments.mockResolvedValue(2); + + await syncWithWaniKani(mockUser); + + expect(fetch).toHaveBeenCalledTimes(3); + }); + + it('should skip insert if operations are empty (e.g. subject data missing)', async () => { + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: [{ data: { subject_id: 101 } }], + pages: { next_url: null } + }) + }); + + StudyItem.find.mockReturnValue({ select: vi.fn().mockResolvedValue([]) }); + + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: [] }) + }); + + StudyItem.countDocuments.mockResolvedValue(0); + + await syncWithWaniKani(mockUser); + + expect(StudyItem.insertMany).not.toHaveBeenCalled(); + }); + + it('should sync items in chunks', async () => { + const manyIds = Array.from({ length: 150 }, (_, i) => i + 1); + const subjectData = manyIds.map(id => ({ data: { subject_id: id } })); + + fetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: subjectData, + pages: { next_url: null } + }) + }); + + StudyItem.find.mockReturnValue({ select: vi.fn().mockResolvedValue([]) }); + + fetch + .mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: [{ id: 1, data: { characters: 'C', meanings: [], level: 1 } }] }) + }) + .mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: [{ id: 101, data: { characters: 'D', meanings: [], level: 1 } }] }) + }); + + StudyItem.insertMany.mockResolvedValue(true); + StudyItem.countDocuments.mockResolvedValue(150); + + await syncWithWaniKani(mockUser); + + expect(fetch).toHaveBeenCalledTimes(3); + expect(StudyItem.insertMany).toHaveBeenCalledTimes(2); + }); +}); diff --git a/server/tests/utils.test.js b/server/tests/utils.test.js new file mode 100644 index 0000000..28d3d6f --- /dev/null +++ b/server/tests/utils.test.js @@ -0,0 +1,54 @@ +import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest'; +import { getDaysDiff, getSRSDate } from '../src/utils/dateUtils.js'; + +describe('Date Utils', () => { + describe('getDaysDiff', () => { + it('should calculate difference between two dates correctly', () => { + const d1 = '2023-01-01'; + const d2 = '2023-01-03'; + expect(getDaysDiff(d1, d2)).toBe(2); + }); + + it('should return 0 for same day', () => { + expect(getDaysDiff('2023-01-01', '2023-01-01')).toBe(0); + }); + }); + + describe('getSRSDate', () => { + beforeAll(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date('2023-01-01T12:00:00Z')); + }); + + afterAll(() => { + vi.useRealTimers(); + }); + + it('should add correct hours for levels 1-6', () => { + const base = new Date('2023-01-01T12:00:00Z'); + + expect(getSRSDate(1).toISOString()).toBe(new Date(base.getTime() + 4 * 3600000).toISOString()); + expect(getSRSDate(2).toISOString()).toBe(new Date(base.getTime() + 8 * 3600000).toISOString()); + expect(getSRSDate(3).toISOString()).toBe(new Date(base.getTime() + 24 * 3600000).toISOString()); + expect(getSRSDate(4).toISOString()).toBe(new Date(base.getTime() + 48 * 3600000).toISOString()); + expect(getSRSDate(5).toISOString()).toBe(new Date(base.getTime() + 7 * 24 * 3600000).toISOString()); + expect(getSRSDate(6).toISOString()).toBe(new Date(base.getTime() + 14 * 24 * 3600000).toISOString()); + }); + + it('should add correct hours for levels 7-9', () => { + const base = new Date('2023-01-01T12:00:00Z'); + expect(getSRSDate(7).toISOString()).toBe(new Date(base.getTime() + 7 * 24 * 3600000).toISOString()); + expect(getSRSDate(8).toISOString()).toBe(new Date(base.getTime() + 30 * 24 * 3600000).toISOString()); + expect(getSRSDate(9).toISOString()).toBe(new Date(base.getTime() + 90 * 24 * 3600000).toISOString()); + }); + + it('should return null for level 10 (burned)', () => { + expect(getSRSDate(10)).toBeNull(); + }); + + it('should default to 4 hours for unknown levels', () => { + const base = new Date('2023-01-01T12:00:00Z'); + expect(getSRSDate(99).toISOString()).toBe(new Date(base.getTime() + 4 * 3600000).toISOString()); + }); + }); +});