From dae1a31b4c5ffc67c4acdceb6bac12ab0b11f314 Mon Sep 17 00:00:00 2001 From: li0nhunter Date: Tue, 19 Aug 2025 09:55:57 -0400 Subject: [PATCH] Initial commit --- .gitea/workflows/deploy.yml | 22 + .gitignore | 228 ++ .idea/.gitignore | 11 + .idea/Website-template.iml | 12 + .idea/compiler.xml | 6 + .idea/inspectionProfiles/Project_Default.xml | 32 + .idea/jsLibraryMappings.xml | 6 + .idea/modules.xml | 8 + .idea/sqldialects.xml | 6 + .idea/vcs.xml | 6 + .idea/watcherTasks.xml | 25 + Dockerfile | 44 + LICENSE | 18 + README.md | 51 + client/.gitignore | 24 + client/README.md | 5 + client/index.html | 13 + client/package-lock.json | 2252 +++++++++++++++++ client/package.json | 36 + client/src/App.vue | 70 + client/src/assets/css/base.css | 86 + client/src/assets/css/base.css.map | 1 + client/src/assets/css/base.scss | 121 + client/src/assets/css/jic.css | 64 + client/src/assets/css/main.css | 309 +++ client/src/assets/css/main.css.map | 1 + client/src/assets/css/main.scss | 322 +++ client/src/assets/img/Instagram_icon.png | Bin 0 -> 48995 bytes client/src/assets/img/L10n.png | Bin 0 -> 20724 bytes client/src/assets/img/Linkedin_icon.png | Bin 0 -> 10635 bytes client/src/assets/svg/edit.svg | 9 + client/src/assets/svg/eye-slash.svg | 8 + client/src/assets/svg/eye.svg | 9 + client/src/assets/svg/trash.svg | 17 + client/src/components/Modal.vue | 84 + client/src/components/Navbar.vue | 182 ++ client/src/components/Pagination.vue | 40 + client/src/components/Table.vue | 276 ++ .../readableComponents/ReadableButton.vue | 13 + .../readableComponents/ReadableDiv.vue | 13 + .../readableComponents/ReadableInput.vue | 15 + .../readableComponents/ReadableSVG.vue | 65 + client/src/directives/vRecolorSvg.ts | 56 + client/src/directives/vRecolorText.ts | 136 + client/src/main.ts | 26 + client/src/models/TransferTypes.ts | 12 + client/src/models/globals.ts | 11 + client/src/models/rest.ts | 30 + client/src/models/session.ts | 61 + client/src/models/toast.ts | 8 + client/src/router/index.ts | 78 + client/src/views/AboutPage.vue | 117 + client/src/views/ContactPage.vue | 102 + client/src/views/LoginPage.vue | 59 + client/src/views/MainPage.vue | 93 + client/src/vite-env.d.ts | 1 + client/tsconfig.app.json | 27 + client/tsconfig.json | 7 + client/tsconfig.node.json | 25 + client/vite.config.ts | 21 + server/app.js | 63 + server/controllers/emailController.js | 148 ++ server/controllers/userController.js | 161 ++ server/middleware/AuthHandler.js | 65 + server/middleware/ErrorHandler.js | 18 + server/models/db.js | 141 ++ server/models/users.js | 146 ++ server/package-lock.json | 2093 +++++++++++++++ server/package.json | 28 + 69 files changed, 8243 insertions(+) create mode 100644 .gitea/workflows/deploy.yml create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/Website-template.iml create mode 100644 .idea/compiler.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/jsLibraryMappings.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/sqldialects.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/watcherTasks.xml create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 client/.gitignore create mode 100644 client/README.md 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/css/base.css create mode 100644 client/src/assets/css/base.css.map create mode 100644 client/src/assets/css/base.scss create mode 100644 client/src/assets/css/jic.css create mode 100644 client/src/assets/css/main.css create mode 100644 client/src/assets/css/main.css.map create mode 100644 client/src/assets/css/main.scss create mode 100644 client/src/assets/img/Instagram_icon.png create mode 100644 client/src/assets/img/L10n.png create mode 100644 client/src/assets/img/Linkedin_icon.png create mode 100644 client/src/assets/svg/edit.svg create mode 100644 client/src/assets/svg/eye-slash.svg create mode 100644 client/src/assets/svg/eye.svg create mode 100644 client/src/assets/svg/trash.svg create mode 100644 client/src/components/Modal.vue create mode 100644 client/src/components/Navbar.vue create mode 100644 client/src/components/Pagination.vue create mode 100644 client/src/components/Table.vue create mode 100644 client/src/components/readableComponents/ReadableButton.vue create mode 100644 client/src/components/readableComponents/ReadableDiv.vue create mode 100644 client/src/components/readableComponents/ReadableInput.vue create mode 100644 client/src/components/readableComponents/ReadableSVG.vue create mode 100644 client/src/directives/vRecolorSvg.ts create mode 100644 client/src/directives/vRecolorText.ts create mode 100644 client/src/main.ts create mode 100644 client/src/models/TransferTypes.ts create mode 100644 client/src/models/globals.ts create mode 100644 client/src/models/rest.ts create mode 100644 client/src/models/session.ts create mode 100644 client/src/models/toast.ts create mode 100644 client/src/router/index.ts create mode 100644 client/src/views/AboutPage.vue create mode 100644 client/src/views/ContactPage.vue create mode 100644 client/src/views/LoginPage.vue create mode 100644 client/src/views/MainPage.vue create mode 100644 client/src/vite-env.d.ts create mode 100644 client/tsconfig.app.json create mode 100644 client/tsconfig.json create mode 100644 client/tsconfig.node.json create mode 100644 client/vite.config.ts create mode 100644 server/app.js create mode 100644 server/controllers/emailController.js create mode 100644 server/controllers/userController.js create mode 100644 server/middleware/AuthHandler.js create mode 100644 server/middleware/ErrorHandler.js create mode 100644 server/models/db.js create mode 100644 server/models/users.js create mode 100644 server/package-lock.json create mode 100644 server/package.json diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..b5233cd --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,22 @@ +name: 'Deploy To Dokku' +on: + push: + branches: + - master + - main + +jobs: + deploy: + runs-on: self-hosted + container: node:24 + steps: + - name: Cloning repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Push to dokku + uses: dokku/github-action@master + with: + git_remote_url: 'ssh://dokku@192.168.1.2:22/to-do-list-partner' + ssh_private_key: { secrets.DOKKU_DEPLOY_KEY } \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f8738c9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,228 @@ +# ---> Vue +# gitignore template for Vue.js projects +# +# Recommended template: Node.gitignore + +# TODO: where does this rule come from? +docs/_book + +# TODO: where does this rule come from? +test/ + +# ---> Node +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# vitepress build output +**/.vitepress/dist + +# vitepress cache directory +**/.vitepress/cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# ---> JetBrains +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..dfdf7aa --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,11 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +/dataSources.xml +/deployment.xml +/GitLink.xml diff --git a/.idea/Website-template.iml b/.idea/Website-template.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/Website-template.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..8ca546d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..0b9cdc6 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,32 @@ + + + + \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..d23208f --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..602423a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..6df4889 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml new file mode 100644 index 0000000..a3471d6 --- /dev/null +++ b/.idea/watcherTasks.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3b79db4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,44 @@ +# Use official Node.js image +LABEL authors="Ari Yeger" +### Client Stage +FROM node:24 AS client-build +# Set the working directory for the client +WORKDIR /app/client + +# Copy package files and install dependencies +COPY /client/package*.json ./ +RUN npm ci + +# Copy server source code +COPY /client . + +# Build the server (if using TypeScript or build step) +RUN npm run build + +### Server Stage +FROM node:24 AS server-build +# Set the working directory for the server +WORKDIR /app/server + +# Copy package files and install dependencies +COPY /server/package*.json ./ +RUN npm install + +# Copy server source code +COPY /server . + +# no build step for server, its already JavaScript + +# Production stage +FROM node:24-slim AS production +WORKDIR /app +# Copy built client files from client-build stage +COPY --from=client-build /app/client/dist ./client/dist +# Copy server files from server-build stage +COPY --from=server-build /app/server ./server +WORKDIR /app/server +# Expose the port your server runs on (change if needed) +EXPOSE 8000 + +# Start the server +CMD ["npm", "start"] \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ad431aa --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +MIT License + +Copyright (c) 2025 li0nhunter + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d8d4843 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# Website-template + +vue ts + vite frontend, express backend, with a dockerfile and a deploy script to my dokku + +### steps to get started on the dokku side +1. create a dokku app + ```bash + dokku apps:create to-do-list-partner + ``` +2. create postgres database + ```bash + dokku postgres:create to-do-list-partner-db + ``` +3. link the database to the app + ```bash + dokku postgres:link to-do-list-partner-db to-do-list-partner + ``` +4. setup db if applicable + - dump local db + ```bash + pg_dump -Fc --no-acl --no-owner -h localhost -U > db.dump + ``` + - restore to dokku db + ```bash + dokku postgres:import to-do-list-partner-db < db.dump + ``` +5. set app to use nginx + - set proxy to nginx + ```bash + dokku proxy:set to-do-list-partner nginx + ``` + + - map nginx port to internal docker port + ```bash + dokku ports:add to-do-list-partner :: + ``` +6. set repo dokku deploy key + - copy the private key from dokku into the repo secrets under the name `DOKKU_DEPLOY_KEY` +7. add the public key to known hosts on dokku + ```bash + dokku ssh-keys:add to-do-list-partner + ``` +8. set environment variables + - create a `.env` file on the dokku server + - add the variables to the `.env` file + - add the variables to the app + ```bash + cat .env | xargs dokku config:set --no-restart to-do-list-partner + ``` +it should be ready to go now, you can deploy with the deployment script + \ No newline at end of file diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/client/README.md b/client/README.md new file mode 100644 index 0000000..33895ab --- /dev/null +++ b/client/README.md @@ -0,0 +1,5 @@ +# Vue 3 + TypeScript + Vite + +This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` + + diff --git a/client/package-lock.json b/client/package-lock.json new file mode 100644 index 0000000..342e746 --- /dev/null +++ b/client/package-lock.json @@ -0,0 +1,2252 @@ +{ + "name": "client", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "client", + "version": "0.0.0", + "dependencies": { + "jwt-decode": "^4.0.0", + "vue": "^3.5.17", + "vue-router": "^4.5.1", + "vue-toast-notification": "^3.1.3" + }, + "devDependencies": { + "@types/node": "^24.0.10", + "@vitejs/plugin-vue": "^6.0.0", + "@volar/typescript": "2.4.23", + "@vue/tsconfig": "^0.7.0", + "bootstrap": "^5.3.3", + "npm-run-all2": "^7.0.2", + "sass": "^1.89.2", + "typescript": "~5.8.3", + "vite": "^7.0.4", + "vue-tsc": "^2.2.12" + } + }, + "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.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz", + "integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz", + "integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz", + "integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz", + "integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz", + "integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz", + "integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz", + "integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz", + "integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz", + "integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz", + "integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz", + "integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz", + "integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz", + "integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz", + "integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz", + "integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz", + "integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz", + "integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz", + "integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz", + "integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz", + "integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz", + "integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz", + "integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz", + "integrity": "sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz", + "integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz", + "integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz", + "integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz", + "integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "license": "MIT" + }, + "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/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.19", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", + "integrity": "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz", + "integrity": "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz", + "integrity": "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz", + "integrity": "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz", + "integrity": "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz", + "integrity": "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz", + "integrity": "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz", + "integrity": "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz", + "integrity": "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz", + "integrity": "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz", + "integrity": "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz", + "integrity": "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz", + "integrity": "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz", + "integrity": "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz", + "integrity": "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz", + "integrity": "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz", + "integrity": "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz", + "integrity": "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz", + "integrity": "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz", + "integrity": "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz", + "integrity": "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==", + "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/node": { + "version": "24.0.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.14.tgz", + "integrity": "sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.0.tgz", + "integrity": "sha512-iAliE72WsdhjzTOp2DtvKThq1VBC4REhwRcaA+zPAAph6I+OQhUXv+Xu2KS7ElxYtb7Zc/3R30Hwv1DxEo7NXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-beta.19" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.23", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.23.tgz", + "integrity": "sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.23" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.23", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.23.tgz", + "integrity": "sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.23", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.23.tgz", + "integrity": "sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.23", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.17.tgz", + "integrity": "sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@vue/shared": "3.5.17", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.17.tgz", + "integrity": "sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.17", + "@vue/shared": "3.5.17" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.17.tgz", + "integrity": "sha512-rQQxbRJMgTqwRugtjw0cnyQv9cP4/4BxWfTdRBkqsTfLOHWykLzbOc3C4GGzAmdMDxhzU/1Ija5bTjMVrddqww==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.5", + "@vue/compiler-core": "3.5.17", + "@vue/compiler-dom": "3.5.17", + "@vue/compiler-ssr": "3.5.17", + "@vue/shared": "3.5.17", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.17", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.17.tgz", + "integrity": "sha512-hkDbA0Q20ZzGgpj5uZjb9rBzQtIHLS78mMilwrlpWk2Ep37DYntUz0PonQ6kr113vfOEdM+zTBuJDaceNIW0tQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.17", + "@vue/shared": "3.5.17" + } + }, + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "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/language-core": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.12.tgz", + "integrity": "sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^1.0.3", + "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.17.tgz", + "integrity": "sha512-l/rmw2STIscWi7SNJp708FK4Kofs97zc/5aEPQh4bOsReD/8ICuBcEmS7KGwDj5ODQLYWVN2lNibKJL1z5b+Lw==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.17" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.17.tgz", + "integrity": "sha512-QQLXa20dHg1R0ri4bjKeGFKEkJA7MMBxrKo2G+gJikmumRS7PTD4BOU9FKrDQWMKowz7frJJGqBffYMgQYS96Q==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.17", + "@vue/shared": "3.5.17" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.17.tgz", + "integrity": "sha512-8El0M60TcwZ1QMz4/os2MdlQECgGoVHPuLnQBU3m9h3gdNRW9xRmI8iLS4t/22OQlOE6aJvNNlBiCzPHur4H9g==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.17", + "@vue/runtime-core": "3.5.17", + "@vue/shared": "3.5.17", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.17.tgz", + "integrity": "sha512-BOHhm8HalujY6lmC3DbqF6uXN/K00uWiEeF22LfEsm9Q93XeJ/plHTepGwf6tqFcF7GA5oGSSAAUock3VvzaCA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.17", + "@vue/shared": "3.5.17" + }, + "peerDependencies": { + "vue": "3.5.17" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.17.tgz", + "integrity": "sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg==", + "license": "MIT" + }, + "node_modules/@vue/tsconfig": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.7.0.tgz", + "integrity": "sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": "5.x", + "vue": "^3.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/alien-signals": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz", + "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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/bootstrap": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.7.tgz", + "integrity": "sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "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", + "optional": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/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/cross-spawn/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/cross-spawn/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/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, + "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/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/esbuild": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", + "integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.6", + "@esbuild/android-arm": "0.25.6", + "@esbuild/android-arm64": "0.25.6", + "@esbuild/android-x64": "0.25.6", + "@esbuild/darwin-arm64": "0.25.6", + "@esbuild/darwin-x64": "0.25.6", + "@esbuild/freebsd-arm64": "0.25.6", + "@esbuild/freebsd-x64": "0.25.6", + "@esbuild/linux-arm": "0.25.6", + "@esbuild/linux-arm64": "0.25.6", + "@esbuild/linux-ia32": "0.25.6", + "@esbuild/linux-loong64": "0.25.6", + "@esbuild/linux-mips64el": "0.25.6", + "@esbuild/linux-ppc64": "0.25.6", + "@esbuild/linux-riscv64": "0.25.6", + "@esbuild/linux-s390x": "0.25.6", + "@esbuild/linux-x64": "0.25.6", + "@esbuild/netbsd-arm64": "0.25.6", + "@esbuild/netbsd-x64": "0.25.6", + "@esbuild/openbsd-arm64": "0.25.6", + "@esbuild/openbsd-x64": "0.25.6", + "@esbuild/openharmony-arm64": "0.25.6", + "@esbuild/sunos-x64": "0.25.6", + "@esbuild/win32-arm64": "0.25.6", + "@esbuild/win32-ia32": "0.25.6", + "@esbuild/win32-x64": "0.25.6" + } + }, + "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/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "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", + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "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/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/immutable": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "dev": true, + "license": "MIT" + }, + "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", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/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", + "optional": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/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", + "optional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "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==", + "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-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/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-run-all2": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-7.0.2.tgz", + "integrity": "sha512-7tXR+r9hzRNOPNTvXegM+QzCuMjzUIIq66VDunL6j60O4RrExx32XUhlrS7UK4VcdGw5/Wxzb3kfNcFix9JKDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "cross-spawn": "^7.0.6", + "memorystream": "^0.3.1", + "minimatch": "^9.0.0", + "pidtree": "^0.6.0", + "read-package-json-fast": "^4.0.0", + "shell-quote": "^1.7.3", + "which": "^5.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "npm-run-all2": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0", + "npm": ">= 9" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "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/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": "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/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "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/read-package-json-fast": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", + "integrity": "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "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/rollup": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz", + "integrity": "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==", + "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.45.1", + "@rollup/rollup-android-arm64": "4.45.1", + "@rollup/rollup-darwin-arm64": "4.45.1", + "@rollup/rollup-darwin-x64": "4.45.1", + "@rollup/rollup-freebsd-arm64": "4.45.1", + "@rollup/rollup-freebsd-x64": "4.45.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", + "@rollup/rollup-linux-arm-musleabihf": "4.45.1", + "@rollup/rollup-linux-arm64-gnu": "4.45.1", + "@rollup/rollup-linux-arm64-musl": "4.45.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", + "@rollup/rollup-linux-riscv64-gnu": "4.45.1", + "@rollup/rollup-linux-riscv64-musl": "4.45.1", + "@rollup/rollup-linux-s390x-gnu": "4.45.1", + "@rollup/rollup-linux-x64-gnu": "4.45.1", + "@rollup/rollup-linux-x64-musl": "4.45.1", + "@rollup/rollup-win32-arm64-msvc": "4.45.1", + "@rollup/rollup-win32-ia32-msvc": "4.45.1", + "@rollup/rollup-win32-x64-msvc": "4.45.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/sass": { + "version": "1.89.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", + "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", + "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/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/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "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", + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.5.tgz", + "integrity": "sha512-1mncVwJxy2C9ThLwz0+2GKZyEXuC3MyWtAAlNftlZZXZDP3AJt5FmwcMit/IGGaNZ8ZOB2BNO/HFUB+CpN0NQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.6", + "picomatch": "^4.0.2", + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" + }, + "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/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.17.tgz", + "integrity": "sha512-LbHV3xPN9BeljML+Xctq4lbz2lVHCR6DtbpTf5XIO6gugpXUN49j2QQPcMj086r9+AkJ0FfUT8xjulKKBkkr9g==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.17", + "@vue/compiler-sfc": "3.5.17", + "@vue/runtime-dom": "3.5.17", + "@vue/server-renderer": "3.5.17", + "@vue/shared": "3.5.17" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", + "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vue-toast-notification": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vue-toast-notification/-/vue-toast-notification-3.1.3.tgz", + "integrity": "sha512-XNyWqwLIGBFfX5G9sK+clq3N3IPlhDjzNdbZaXkEElcotPlWs0wWZailk1vqhdtLYT/93Y4FHAVuzyatLmPZRA==", + "license": "MIT", + "engines": { + "node": ">=12.15.0" + }, + "peerDependencies": { + "vue": "^3.0" + } + }, + "node_modules/vue-tsc": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.12.tgz", + "integrity": "sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/language-core": "2.2.12" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + } + } +} diff --git a/client/package.json b/client/package.json new file mode 100644 index 0000000..3bb05a4 --- /dev/null +++ b/client/package.json @@ -0,0 +1,36 @@ +{ + "name": "client", + "private": true, + "version": "0.0.0", + "type": "module", + "description": "Client application for to-do-list-partner", + "author": "li0nhunter", + "scripts": { + "dev": "npm-run-all --parallel dev:client dev:server", + "dev:server": "cd ../server && npm run dev", + "dev:client": "vite", + "prod": "cd ../server && npm run start", + "build": "run-p build:vue build:sass", + "build:vue": "vue-tsc -b && vite build", + "build:sass": "sass src/assets/css/base.scss src/assets/css/base.css && sass src/assets/css/main.scss src/assets/css/main.css", + "preview": "vite preview" + }, + "dependencies": { + "jwt-decode": "^4.0.0", + "vue": "^3.5.17", + "vue-router": "^4.5.1", + "vue-toast-notification": "^3.1.3" + }, + "devDependencies": { + "@types/node": "^24.0.10", + "@vitejs/plugin-vue": "^6.0.0", + "@vue/tsconfig": "^0.7.0", + "@volar/typescript": "2.4.23", + "bootstrap": "^5.3.3", + "npm-run-all2": "^7.0.2", + "sass": "^1.89.2", + "typescript": "~5.8.3", + "vite": "^7.0.4", + "vue-tsc": "^2.2.12" + } +} diff --git a/client/src/App.vue b/client/src/App.vue new file mode 100644 index 0000000..e139985 --- /dev/null +++ b/client/src/App.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/client/src/assets/css/base.css b/client/src/assets/css/base.css new file mode 100644 index 0000000..dde5199 --- /dev/null +++ b/client/src/assets/css/base.css @@ -0,0 +1,86 @@ +/* semantic color variables for this project */ +@media (prefers-color-scheme: dark), (prefers-color-scheme: no-preference) { + :root { + --color-divider: rgba(84, 84, 84, 0.65); + --color-divider-alt: rgba(84, 84, 84, 0.48); + --color-text: #E7E7E7; + --color-text-alt: #e7e7e7; + --color-modal-background: #464646; + --color-modal-background-inverted: #b9b9b9; + --color-form-background: #222222; + --color-form-background-focus: rgb(56.1, 56.1, 56.1); + --color-border-1: #cccccc; + --color-border-2: rgb(163.2, 163.2, 163.2); + --color-nav-text: #a8a8a8; + --color-nav-text-hover: rgb(185.4, 185.4, 185.4); + --color-nav-text-active: rgb(202.8, 202.8, 202.8); + --color-nav-text-disabled: #909090ff; + --color-background: #181818; + --color-background-soft: rgb(70.2, 70.2, 70.2); + --color-background-mute: rgb(116.4, 116.4, 116.4); + --color-primary: #035768; + --color-primary-hover: rgb(5.2598130841, 152.5345794393, 182.3401869159); + --color-primary-active: rgb(19.9794392523, 209.8037383178, 248.2205607477); + --color-primary-disabled: #909090ff; + --color-secondary: #60aeae; + --color-secondary-hover: rgb(127.8, 190.2, 190.2); + --color-secondary-active: rgb(159.6, 206.4, 206.4); + --color-secondary-disabled: #909090ff; + --color-danger: #fd0000; + --color-danger-hover: rgb(255, 49.4, 49.4); + --color-danger-active: rgb(255, 100.8, 100.8); + --color-danger-disabled: #909090ff; + } +} +@media (prefers-color-scheme: light) { + :root { + --color-divider: rgba(60, 60, 60, 0.29); + --color-divider-alt: rgba(60, 60, 60, 0.12); + --color-text: #181818; + --color-text-alt: #181818; + --color-modal-background: #b9b9b9; + --color-modal-background-inverted: #464646; + --color-form-background: #cdcdcd; + --color-form-background-focus: #a4a4a4; + --color-border-1: #333333ff; + --color-border-2: #6D6D6Dff; + --color-nav-text: #178c85; + --color-nav-text-hover: rgb(18.4, 112, 106.4); + --color-nav-text-active: rgb(13.8, 84, 79.8); + --color-nav-text-disabled: #909090ff; + --color-primary: #99edcd; + --color-primary-hover: rgb(86.7, 225.3, 172.5); + --color-primary-active: rgb(35.1, 198.9, 136.5); + --color-primary-disabled: #909090ff; + --color-background: #f0f0f0; + --color-background-soft: silver; + --color-background-mute: #909090; + --color-secondary: #7fd9bf; + --color-secondary-hover: rgb(73.9493975904, 201.2506024096, 164.4746987952); + --color-secondary-active: rgb(47.2481927711, 159.1518072289, 126.8240963855); + --color-secondary-disabled: #909090ff; + --color-danger: #fd0000; + --color-danger-hover: rgb(202.4, 0, 0); + --color-danger-active: rgb(151.8, 0, 0); + --color-danger-disabled: #909090ff; + } +} +:root { + --color-background-reversion: var(--color-background); + --color-border: var(--color-border-1); + --color-border-invert: var(--color-border-2); + --color-border-hover: var(--color-divider); + --color-primary-reversion: var(--color-primary); + --color-secondary-reversion: var(--color-secondary); + --color-primary-font: var(--color-text); + --color-secondary-font: var(--color-text); + --color-background-font: var(--color-text); + --color-background-mute-font: var(--color-text); + --color-background-soft-font: var(--color-text); + --color-modal-background-font: var(--color-text); + --color-form-background-font: var(--color-text); + --color-modal-background-inverted-font: var(--color-text); + --color-heading: var(--color-nav-text); +} + +/*# sourceMappingURL=base.css.map */ diff --git a/client/src/assets/css/base.css.map b/client/src/assets/css/base.css.map new file mode 100644 index 0000000..6922aa7 --- /dev/null +++ b/client/src/assets/css/base.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["base.scss"],"names":[],"mappings":"AACA;AACA;EACE;IACE;IACA;IAGA;IACA;IAGA;IACA;IAGA;IACA;IAGA;IACA;IAGA;IACA;IACA;IACA;IAGA;IACA;IACA;IAGA;IACA;IACA;IACA;IAIA;IACA;IACA;IACA;IAGA;IACA;IACA;IACA;;;AAIJ;EACE;IACE;IACA;IAEA;IACA;IAGA;IACA;IAGA;IACA;IACA;IACA;IAGA;IACA;IACA;IACA;IAGA;IACA;IACA;IACA;IAGA;IACA;IACA;IAGA;IACA;IACA;IACA;IAGA;IACA;IACA;IACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"base.css"} \ No newline at end of file diff --git a/client/src/assets/css/base.scss b/client/src/assets/css/base.scss new file mode 100644 index 0000000..c8eb715 --- /dev/null +++ b/client/src/assets/css/base.scss @@ -0,0 +1,121 @@ +@use "sass:color"; +/* semantic color variables for this project */ +@media (prefers-color-scheme: dark), (prefers-color-scheme: no-preference) { + :root { + --color-divider: rgba(84, 84, 84, 0.65); + --color-divider-alt: rgba(84, 84, 84, 0.48); + + $color-text: #E7E7E7; + --color-text: #{$color-text}; + --color-text-alt: #{color.scale($color-text, $alpha: 64%)}; + + $color-modal-background: #464646ff; + --color-modal-background: #{$color-modal-background}; + --color-modal-background-inverted: #{color.invert($color-modal-background)}; + + $color-form-background: #222222ff; + --color-form-background: #{$color-form-background}; + --color-form-background-focus: #{color.scale($color-form-background, $lightness: 10%)}; + + $color-border-1: #ccccccff; + --color-border-1: #{$color-border-1}; + --color-border-2: #{color.scale($color-border-1, $lightness: -20%)}; + + $color-nav-text: #a8a8a8ff; + --color-nav-text: #{$color-nav-text}; + --color-nav-text-hover: #{color.scale($color-nav-text, $lightness: 20%)}; + --color-nav-text-active: #{color.scale($color-nav-text, $lightness: 40%)}; + --color-nav-text-disabled: #909090ff; + + $color-background: #181818ff; + --color-background: #{$color-background}; + --color-background-soft: #{color.scale($color-background, $lightness: 20%)}; + --color-background-mute: #{color.scale($color-background, $lightness: 40%)}; + + $color-primary: #035768ff; + --color-primary: #{$color-primary}; + --color-primary-hover: #{color.scale($color-primary, $lightness: 20%)}; + --color-primary-active: #{color.scale($color-primary, $lightness: 40%)}; + --color-primary-disabled: #909090ff; + + + $color-secondary: #60AEAEff; + --color-secondary: #{$color-secondary}; + --color-secondary-hover: #{color.scale($color-secondary, $lightness: 20%)}; + --color-secondary-active: #{color.scale($color-secondary, $lightness: 40%)}; + --color-secondary-disabled: #909090ff; + + $color-danger: #fd0000ff; + --color-danger: #{$color-danger}; + --color-danger-hover: #{color.scale($color-danger, $lightness: 20%)}; + --color-danger-active: #{color.scale($color-danger, $lightness: 40%)}; + --color-danger-disabled: #909090ff; + } +} + +@media (prefers-color-scheme: light) { + :root { + --color-divider: rgba(60, 60, 60, 0.29); + --color-divider-alt: rgba(60, 60, 60, 0.12); + $color-text: #181818; + --color-text: #{$color-text}; + --color-text-alt: #{color.scale($color-text, $alpha: 66%)}; + + $color-modal-background: #b9b9b9ff; + --color-modal-background: #{$color-modal-background}; + --color-modal-background-inverted: #{color.invert($color-modal-background)}; + + $color-form-background: #cdcdcdff; + --color-form-background: #{$color-form-background}; + --color-form-background-focus: #{color.scale($color-form-background, $lightness: -20%)}; + --color-border-1: #333333ff; + --color-border-2: #6D6D6Dff; + + $color-nav-text: #178c85ff; + --color-nav-text: #{$color-nav-text}; + --color-nav-text-hover: #{color.scale($color-nav-text, $lightness: -20%)}; + --color-nav-text-active: #{color.scale($color-nav-text, $lightness: -40%)}; + --color-nav-text-disabled: #909090ff; + + $color-primary: #99edcdff; + --color-primary: #{$color-primary}; + --color-primary-hover: #{color.scale($color-primary, $lightness: -20%)}; + --color-primary-active: #{color.scale($color-primary, $lightness: -40%)}; + --color-primary-disabled: #909090ff; + + $color-background: #f0f0f0ff; + --color-background: #{$color-background}; + --color-background-soft: #{color.scale($color-background, $lightness: -20%)}; + --color-background-mute: #{color.scale($color-background, $lightness: -40%)}; + + $color-secondary: #7fd9bfff; + --color-secondary: #{$color-secondary}; + --color-secondary-hover: #{color.scale($color-secondary, $lightness: -20%)}; + --color-secondary-active: #{color.scale($color-secondary, $lightness: -40%)}; + --color-secondary-disabled: #909090ff; + + $color-danger: #fd0000ff; + --color-danger: #{$color-danger}; + --color-danger-hover: #{color.scale($color-danger, $lightness: -20%)}; + --color-danger-active: #{color.scale($color-danger, $lightness: -40%)}; + --color-danger-disabled: #909090ff; + } +} + +:root { + --color-background-reversion: var(--color-background); + --color-border: var(--color-border-1); + --color-border-invert: var(--color-border-2); + --color-border-hover: var(--color-divider); + --color-primary-reversion: var(--color-primary); + --color-secondary-reversion: var(--color-secondary); + --color-primary-font: var(--color-text); + --color-secondary-font: var(--color-text); + --color-background-font: var(--color-text); + --color-background-mute-font: var(--color-text); + --color-background-soft-font: var(--color-text); + --color-modal-background-font: var(--color-text); + --color-form-background-font: var(--color-text); + --color-modal-background-inverted-font: var(--color-text); + --color-heading: var(--color-nav-text); +} \ No newline at end of file diff --git a/client/src/assets/css/jic.css b/client/src/assets/css/jic.css new file mode 100644 index 0000000..3e2335e --- /dev/null +++ b/client/src/assets/css/jic.css @@ -0,0 +1,64 @@ +.dp__input, +.dp__input:focus, +.dp__input:hover { + background-color: var(--color-background) !important; + color: var(--color-background-font) !important; + border-color: var(--color-modal-background-inverted) !important; +} + +.dp__theme_light { + background-color: transparent !important; + border-color: var(--color-modal-background-inverted) !important; + --dp-range-between-dates-background-color: var(--color-background) !important; + --dp-range-between-border-color: var(--color-background) !important; + --dp-hover-color: var(--color-form-background) !important; + --dp-background-color: var(--color-background-mute) !important; +} + +.dp__arrow_bottom { + background-color: var(--color-background-mute) !important; + color: var(--color-background-mute-font) !important; + border-color: var(--color-modal-background-inverted) !important; + --dp-range-between-dates-background-color: var(--color-background) !important; + --dp-range-between-border-color: var(--color-background) !important; + --dp-hover-color: var(--color-form-background) !important; + --dp-background-color: var(--color-background-mute) !important; +} + +.dp__input_icon, +.dp__clear_icon { + color: var(--color-background-font) !important; +} + + +.accordion-button, +.accordion-button:not(.collapsed) { + color: var(--color-background-mute-font); + background-color: var(--color-background-mute); +} + +.accordion-item { + border: 1px solid var(--color-modal-background-inverted); + background-color: var(--color-background); +} + +.dropdown-menu.show, +.dropdown-menu .dropdown-menu { + background-color: var(--color-background); + border: 1px solid var(--color-modal-background-inverted); +} + +.dropdown-item { + color: var(--color-nav-text); +} + +.dropdown-menu li a:hover, +.dropdown-item:hover, +.dropdown-submenu .dropdown-item:hover { + background-color: var(--color-background); + color: var(--color-background-font); +} + +.dropdown { + cursor: pointer; +} \ No newline at end of file diff --git a/client/src/assets/css/main.css b/client/src/assets/css/main.css new file mode 100644 index 0000000..67bf128 --- /dev/null +++ b/client/src/assets/css/main.css @@ -0,0 +1,309 @@ +@import url("../../../node_modules/bootstrap/dist/css/bootstrap.min.css"); +@import url("https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,100..900;1,100..900&display=swap"); +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; +} + +body { + min-height: 100vh; + width: 100vw; + color: var(--color-background-font); + background: var(--color-background); + transition: color 0.2s ease, background-color 0.2s ease; + line-height: 1.6; + font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + font-size: 1rem; + font-weight: 500; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-align: left; + overflow-x: hidden; + overflow-y: auto; + box-sizing: border-box; +} + +.media-content { + overflow: hidden; + position: absolute; + left: 175px; + margin-top: 1rem; + margin-bottom: 1rem; +} + +input, select, textarea { + color: var(--color-background-font); + background-color: var(--color-form-background); + border-color: var(--color-border); +} + +.input-group { + display: flex; + align-items: center; +} + +.input-group-text { + background-color: var(--color-form-background); + padding: 0.5rem; + display: flex; + align-items: center; +} + +input:disabled { + background-color: var(--color-primary-disabled); +} + +.container { + flex-direction: column; + align-items: center; + justify-content: center; +} + +.form-check-label { + user-select: none; +} + +.tooltip-modal { + position: relative; + display: inline-block; + opacity: 1; +} + +.tooltip { + position: absolute; + transform: translateY(-50%); + margin-left: 3rem; + padding: 6px 10px; + border-radius: 4px; + color: rgb(0, 0, 0); + font-size: 15px; + white-space: nowrap; + opacity: 0.9; +} + +.tooltip-modal .tooltiptext { + visibility: hidden; + opacity: 0; + transition: opacity 0.2s linear, visibility 0.2s linear 0.2s; + width: 200px; + background-color: var(--color-modal-background-inverted); + color: var(--color-background); + text-align: center; + border-radius: 6px; + padding: 5px 0; + position: absolute; + z-index: 10; + bottom: 125%; + left: 50%; + margin-left: -100px; +} + +.tooltip-modal .tooltiptext::after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: var(--color-modal-background-inverted) transparent transparent transparent; +} + +.tooltip-modal:hover .tooltiptext { + visibility: visible; + opacity: 1; + transition: opacity 0.2s linear; +} + +.tooltip-modal .tooltiptext:hover { + visibility: hidden; + opacity: 0; +} + +.btn { + user-select: none; +} + +.btn:hover { + cursor: pointer; +} + +.input-group:focus-within .input-group-text:not(:focus), +.form-check-input:focus, +.form-control:focus { + outline: none; + box-shadow: none; + border-color: var(--color-secondary-active); + color: var(--color-form-background-font); + background-color: var(--color-form-background-focus); + transition: border-color 0.2s ease-in-out; +} + +.input-group .input-group-text, +.input-group-text:focus { + border-color: var(--color-border); + transition: border-color 0.2s ease-in-out; +} + +.form-control { + color: var(--color-background-font); + background-color: var(--color-form-background); + border-color: var(--color-border); +} + +.form-control::placeholder { + color: rgba(128, 128, 128, 0.8156862745); +} + +select.form-control, +select#location { + appearance: none; + -webkit-appearance: none; + background-image: url("data:image/svg+xml;charset=UTF-8,"); + background-repeat: no-repeat; + background-position: right 0.25rem center; + background-size: 1.25em; + padding-right: 2em; + transition: background 0.2s, border-color 0.2s; +} + +select.form-control:hover, +select#location:hover, +select.form-control:focus, +select#location:focus { + border-color: var(--color-secondary-active); +} + +select.form-control:focus, +select#location:focus { + box-shadow: 0 0 0 0.2rem rgba(134, 223, 195, 0.25); +} + +.is-primary { + color: var(--color-primary-font); + background-color: var(--color-primary); + border-color: var(--color-primary); +} + +.is-secondary { + color: var(--color-secondary-font); + background-color: var(--color-secondary); + border-color: var(--color-secondary); +} + +.btn-primary { + --bs-btn-color: var(--color-primary-font); + --bs-btn-bg: var(--color-primary); + --bs-btn-border-color: var(--color-primary); + --bs-btn-hover-color: var(--color-primary-font); + --bs-btn-hover-bg: var(--color-primary-hover); + --bs-btn-hover-border-color: var(--color-primary-hover); + --bs-btn-focus-shadow-rgb: 49, 132, 253; + --bs-btn-active-color: var(--color-primary-font); + --bs-btn-active-bg: var(--color-primary-active); + --bs-btn-active-border-color: var(--color-primary-active); + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: var(--color-primary-font); + --bs-btn-disabled-bg: var(--color-primary-disabled); + --bs-btn-disabled-border-color: var(--color-primary-disabled); +} + +.btn-secondary { + --bs-btn-color: var(--color-secondary-font); + --bs-btn-bg: var(--color-secondary); + --bs-btn-border-color: var(--color-secondary); + --bs-btn-hover-color: var(--color-secondary-font); + --bs-btn-hover-bg: var(--color-secondary-hover); + --bs-btn-hover-border-color: var(--color-secondary-hover); + --bs-btn-focus-shadow-rgb: 49, 132, 253; + --bs-btn-active-color: var(--color-secondary-font); + --bs-btn-active-bg: var(--color-secondary-active); + --bs-btn-active-border-color: var(--color-secondary-active); + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: var(--color-secondary-font); + --bs-btn-disabled-bg: var(--color-secondary-disabled); + --bs-btn-disabled-border-color: var(--color-secondary-disabled); +} + +.btn-danger { + --bs-btn-bg: var(--color-danger); + --bs-btn-border-color: var(--color-danger); + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: var(--color-danger-hover); + --bs-btn-hover-border-color: var(--color-danger-hover); + --bs-btn-focus-shadow-rgb: 225, 83, 97; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: var(--color-danger-active); + --bs-btn-active-border-color: var(--color-danger-active); + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: var(--color-danger-disabled); + --bs-btn-disabled-border-color: var(--color-danger-disabled); +} + +.btn-submit { + --bs-btn-color: var(--color-primary-font); + --bs-btn-bg: var(--color-primary); + --bs-btn-border-color: var(--color-modal-background-inverted); + --bs-btn-hover-color: var(--color-primary-font); + --bs-btn-hover-bg: var(--color-primary-hover); + --bs-btn-hover-border-color: var(--color-modal-background-inverted); + --bs-btn-focus-shadow-rgb: 49, 132, 253; + --bs-btn-active-color: var(--color-primary-font); + --bs-btn-active-bg: var(--color-primary-active); + --bs-btn-active-border-color: var(--color-modal-background-inverted); + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: var(--color-primary-font); + --bs-btn-disabled-bg: var(--color-primary-disabled); + --bs-btn-disabled-border-color: var(--color-modal-background-inverted); +} + +.routerLink { + color: var(--color-primary); +} + +.routerLink:hover { + color: var(--color-primary-hover); +} + +.routerLink:active { + color: var(--color-primary-active); +} + +.alert { + --bs-alert-border: 1px solid #ad6060; + --bs-alert-bg: #e4b6b6; +} + +.offcanvas-header { + background-color: var(--color-background); + color: var(--color-background-font); + box-shadow: var(--color-text) 0, 0, 10px; +} + +.offcanvas-body { + background-color: var(--color-background); + color: var(--color-background-font); + position: relative; +} + +.ellipsis { + color: var(--color-background-font); +} + +.fade-enter-active, .fade-leave-active { + transition: opacity 0.5s; +} + +.fade-enter-from, .fade-leave-to { + opacity: 0; +} + +.fade-enter-to, .fade-leave-from { + opacity: 1; +} + +/*# sourceMappingURL=main.css.map */ diff --git a/client/src/assets/css/main.css.map b/client/src/assets/css/main.css.map new file mode 100644 index 0000000..f261302 --- /dev/null +++ b/client/src/assets/css/main.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["main.scss"],"names":[],"mappings":"AAAQ;AACA;AAER;AAAA;AAAA;EAGE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAYA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACI;EACA;;;AAGJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;EAEE;;;AAGF;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE","file":"main.css"} \ No newline at end of file diff --git a/client/src/assets/css/main.scss b/client/src/assets/css/main.scss new file mode 100644 index 0000000..2a3bb38 --- /dev/null +++ b/client/src/assets/css/main.scss @@ -0,0 +1,322 @@ +@import url('../../../node_modules/bootstrap/dist/css/bootstrap.min.css'); +@import url('https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,100..900;1,100..900&display=swap'); + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; +} + +body { + min-height: 100vh; + width: 100vw; + color: var(--color-background-font); + background: var(--color-background); + transition: color 0.2s ease, background-color 0.2s ease; + line-height: 1.6; + font-family: Inter, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Oxygen, + Ubuntu, + Cantarell, + 'Fira Sans', + 'Droid Sans', + 'Helvetica Neue', + sans-serif; + font-size: 1rem; + font-weight: 500; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-align: left; + overflow-x: hidden; + overflow-y: auto; + box-sizing: border-box; +} + +.media-content { + overflow: hidden; + position: absolute; + left: 175px; + margin-top: 1rem; + margin-bottom: 1rem; +} + +input, select, textarea { + color: var(--color-background-font); + background-color: var(--color-form-background); + border-color: var(--color-border); +} + +.input-group { + display: flex; + align-items: center; +} + +.input-group-text { + background-color: var(--color-form-background); + padding: 0.5rem; + display: flex; + align-items: center; +} + +input:disabled { + background-color: var(--color-primary-disabled); +} + +.container { + flex-direction: column; + align-items: center; + justify-content: center; +} + +.form-check-label { + user-select: none; +} + +.tooltip-modal { + position: relative; + display: inline-block; + opacity: 1; +} + +.tooltip { + position: absolute; + transform: translateY(-50%); + margin-left: 3rem; + padding: 6px 10px; + border-radius: 4px; + color: rgb(0, 0, 0); + font-size: 15px; + white-space: nowrap; + opacity: 0.9; +} + +.tooltip-modal .tooltiptext { + visibility: hidden; + opacity: 0; + transition: opacity 0.2s linear, + visibility 0.2s linear 0.2s; + width: 200px; + background-color: var(--color-modal-background-inverted); + color: var(--color-background); + text-align: center; + border-radius: 6px; + padding: 5px 0; + position: absolute; + z-index: 10; + bottom: 125%; + left: 50%; + margin-left: -100px; +} + +.tooltip-modal .tooltiptext::after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: var(--color-modal-background-inverted) transparent transparent transparent; +} + +.tooltip-modal:hover .tooltiptext { + visibility: visible; + opacity: 1; + transition: opacity 0.2s linear; +} + +.tooltip-modal .tooltiptext:hover { + visibility: hidden; + opacity: 0; +} + +.btn { + user-select: none; +} + +.btn:hover { + cursor: pointer; +} + + +.input-group:focus-within .input-group-text:not(:focus), +.form-check-input:focus, +.form-control:focus { + outline: none; + box-shadow: none; + border-color: var(--color-secondary-active); + color: var(--color-form-background-font); + background-color: var(--color-form-background-focus); + transition: border-color 0.2s ease-in-out; +} + +.input-group .input-group-text, +.input-group-text:focus { + border-color: var(--color-border); + transition: border-color 0.2s ease-in-out; +} + +.form-control { + color: var(--color-background-font); + background-color: var(--color-form-background); + border-color: var(--color-border) +} + +.form-control::placeholder { + color: #808080D0; +} + +select.form-control, +select#location { + appearance: none; + -webkit-appearance: none; + background-image: url("data:image/svg+xml;charset=UTF-8,"); + background-repeat: no-repeat; + background-position: right 0.25rem center; + background-size: 1.25em; + padding-right: 2em; + transition: background 0.2s, border-color 0.2s; +} + +select.form-control:hover, +select#location:hover, +select.form-control:focus, +select#location:focus { + border-color: var(--color-secondary-active) +} + +select.form-control:focus, +select#location:focus { + box-shadow: 0 0 0 0.2rem rgba(134, 223, 195, 0.25); +} + +.is-primary{ + color: var(--color-primary-font); + background-color: var(--color-primary); + border-color: var(--color-primary); +} + +.is-secondary{ + color: var(--color-secondary-font); + background-color: var(--color-secondary); + border-color: var(--color-secondary); +} + +.btn-primary { + --bs-btn-color: var(--color-primary-font); + --bs-btn-bg: var(--color-primary); + --bs-btn-border-color: var(--color-primary); + --bs-btn-hover-color: var(--color-primary-font); + --bs-btn-hover-bg: var(--color-primary-hover); + --bs-btn-hover-border-color: var(--color-primary-hover); + --bs-btn-focus-shadow-rgb: 49, 132, 253; + --bs-btn-active-color: var(--color-primary-font); + --bs-btn-active-bg: var(--color-primary-active); + --bs-btn-active-border-color: var(--color-primary-active); + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: var(--color-primary-font); + --bs-btn-disabled-bg: var(--color-primary-disabled); + --bs-btn-disabled-border-color: var(--color-primary-disabled); +} + +.btn-secondary { + --bs-btn-color: var(--color-secondary-font); + --bs-btn-bg: var(--color-secondary); + --bs-btn-border-color: var(--color-secondary); + --bs-btn-hover-color: var(--color-secondary-font); + --bs-btn-hover-bg: var(--color-secondary-hover); + --bs-btn-hover-border-color: var(--color-secondary-hover); + --bs-btn-focus-shadow-rgb: 49, 132, 253; + --bs-btn-active-color: var(--color-secondary-font); + --bs-btn-active-bg: var(--color-secondary-active); + --bs-btn-active-border-color: var(--color-secondary-active); + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: var(--color-secondary-font); + --bs-btn-disabled-bg: var(--color-secondary-disabled); + --bs-btn-disabled-border-color: var(--color-secondary-disabled); +} + +.btn-danger { + --bs-btn-bg: var(--color-danger); + --bs-btn-border-color: var(--color-danger); + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: var(--color-danger-hover); + --bs-btn-hover-border-color: var(--color-danger-hover); + --bs-btn-focus-shadow-rgb: 225, 83, 97; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: var(--color-danger-active); + --bs-btn-active-border-color: var(--color-danger-active); + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: var(--color-danger-disabled); + --bs-btn-disabled-border-color: var(--color-danger-disabled); +} + +.btn-submit { + --bs-btn-color: var(--color-primary-font); + --bs-btn-bg: var(--color-primary); + --bs-btn-border-color: var(--color-modal-background-inverted); + --bs-btn-hover-color: var(--color-primary-font); + --bs-btn-hover-bg: var(--color-primary-hover); + --bs-btn-hover-border-color: var(--color-modal-background-inverted); + --bs-btn-focus-shadow-rgb: 49, 132, 253; + --bs-btn-active-color: var(--color-primary-font); + --bs-btn-active-bg: var(--color-primary-active); + --bs-btn-active-border-color: var(--color-modal-background-inverted); + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: var(--color-primary-font); + --bs-btn-disabled-bg: var(--color-primary-disabled); + --bs-btn-disabled-border-color: var(--color-modal-background-inverted); +} + +.routerLink { + color: var(--color-primary); +} + +.routerLink:hover { + color: var(--color-primary-hover); +} + +.routerLink:active { + color: var(--color-primary-active); +} + +.alert { + --bs-alert-border: 1px solid #ad6060; + --bs-alert-bg: #e4b6b6; +} + +.offcanvas-header { + background-color: var(--color-background); + color: var(--color-background-font); + box-shadow: var(--color-text) 0, 0, 10px; +} + +.offcanvas-body { + background-color: var(--color-background); + color: var(--color-background-font); + position: relative; +} + +.ellipsis { + color: var(--color-background-font); +} + +.fade-enter-active, .fade-leave-active { + transition: opacity .5s; +} + +.fade-enter-from, .fade-leave-to { + opacity: 0; +} + +.fade-enter-to, .fade-leave-from { + opacity: 1; +} + diff --git a/client/src/assets/img/Instagram_icon.png b/client/src/assets/img/Instagram_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..081eb4d887ff02934d1c9500eecc7170c6d16bed GIT binary patch literal 48995 zcmV)ZK&!urP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 literal 0 HcmV?d00001 diff --git a/client/src/assets/img/L10n.png b/client/src/assets/img/L10n.png new file mode 100644 index 0000000000000000000000000000000000000000..98a3c3278d6131e061c72ea13f5ef4308d0e42be GIT binary patch literal 20724 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 literal 0 HcmV?d00001 diff --git a/client/src/assets/img/Linkedin_icon.png b/client/src/assets/img/Linkedin_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..96a7d9aadbf054650c3b4644baea50758f8074ee GIT binary patch literal 10635 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 I$v@%$0DY=lc>n+a literal 0 HcmV?d00001 diff --git a/client/src/assets/svg/edit.svg b/client/src/assets/svg/edit.svg new file mode 100644 index 0000000..260d1ca --- /dev/null +++ b/client/src/assets/svg/edit.svg @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/client/src/assets/svg/eye-slash.svg b/client/src/assets/svg/eye-slash.svg new file mode 100644 index 0000000..d3e2396 --- /dev/null +++ b/client/src/assets/svg/eye-slash.svg @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/client/src/assets/svg/eye.svg b/client/src/assets/svg/eye.svg new file mode 100644 index 0000000..033faf4 --- /dev/null +++ b/client/src/assets/svg/eye.svg @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/client/src/assets/svg/trash.svg b/client/src/assets/svg/trash.svg new file mode 100644 index 0000000..fe71de0 --- /dev/null +++ b/client/src/assets/svg/trash.svg @@ -0,0 +1,17 @@ + + + + + trash + Created with Sketch Beta. + + + + + + + + + + \ No newline at end of file diff --git a/client/src/components/Modal.vue b/client/src/components/Modal.vue new file mode 100644 index 0000000..80b99c3 --- /dev/null +++ b/client/src/components/Modal.vue @@ -0,0 +1,84 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/Navbar.vue b/client/src/components/Navbar.vue new file mode 100644 index 0000000..1396259 --- /dev/null +++ b/client/src/components/Navbar.vue @@ -0,0 +1,182 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/Pagination.vue b/client/src/components/Pagination.vue new file mode 100644 index 0000000..b3cd8a0 --- /dev/null +++ b/client/src/components/Pagination.vue @@ -0,0 +1,40 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/Table.vue b/client/src/components/Table.vue new file mode 100644 index 0000000..254f8d3 --- /dev/null +++ b/client/src/components/Table.vue @@ -0,0 +1,276 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/readableComponents/ReadableButton.vue b/client/src/components/readableComponents/ReadableButton.vue new file mode 100644 index 0000000..fb2db22 --- /dev/null +++ b/client/src/components/readableComponents/ReadableButton.vue @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/readableComponents/ReadableDiv.vue b/client/src/components/readableComponents/ReadableDiv.vue new file mode 100644 index 0000000..fc5443c --- /dev/null +++ b/client/src/components/readableComponents/ReadableDiv.vue @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/readableComponents/ReadableInput.vue b/client/src/components/readableComponents/ReadableInput.vue new file mode 100644 index 0000000..16d3a65 --- /dev/null +++ b/client/src/components/readableComponents/ReadableInput.vue @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/readableComponents/ReadableSVG.vue b/client/src/components/readableComponents/ReadableSVG.vue new file mode 100644 index 0000000..9907591 --- /dev/null +++ b/client/src/components/readableComponents/ReadableSVG.vue @@ -0,0 +1,65 @@ + + + + \ No newline at end of file diff --git a/client/src/directives/vRecolorSvg.ts b/client/src/directives/vRecolorSvg.ts new file mode 100644 index 0000000..b26defa --- /dev/null +++ b/client/src/directives/vRecolorSvg.ts @@ -0,0 +1,56 @@ +// client/src/directives/vUseReadableSvgColor.ts +import { useReadableTextColor } from './vRecolorText.ts'; // reuse your function +import { darkModeActive } from "@models/globals.ts"; +import { watch } from 'vue'; + +function updateSvgColor(el: SVGElement) { + let bgColor: string | null = window.getComputedStyle(el).backgroundColor; + if (!bgColor || bgColor === 'rgba(0, 0, 0, 0)' || bgColor === 'transparent') { + let parent = el.parentElement; + bgColor = parent ? window.getComputedStyle(parent).backgroundColor : null; + while (parent && !(bgColor && bgColor !== 'transparent' && bgColor !== 'rgba(0, 0, 0, 0)')) { + parent = parent.parentElement; + if (parent) bgColor = window.getComputedStyle(parent).backgroundColor; + else bgColor = null; + } + } + if (bgColor) { + el.style.fill = useReadableTextColor(bgColor); + } else { + const stopWatch = watch( + () => el.parentElement, + (parent) => { + if (parent) { + el.style.fill = useReadableTextColor(window.getComputedStyle(parent).backgroundColor); + stopWatch(); + } + } + ); + } +} + +export default { + mounted(el: SVGElement) { + const updateColor = () => updateSvgColor(el); + updateColor(); + el.addEventListener('click', updateColor); + el.addEventListener('mouseenter', updateColor); + el.addEventListener('mouseleave', updateColor); + el.addEventListener('transitionend', updateColor); + el.addEventListener('change', updateColor); + watch(() => darkModeActive.value, () => updateSvgColor(el)); + (el as any)._readableSvgListeners = [updateColor]; + }, + unmounted(el: SVGElement) { + const listeners = (el as any)._readableSvgListeners || []; + for (const listener of listeners) { + el.removeEventListener('click', listener); + el.removeEventListener('mouseenter', listener); + el.removeEventListener('mouseleave', listener); + el.removeEventListener('transitionend', listener); + el.removeEventListener('change', listener); + + } + delete (el as any)._readableSvgListeners; + } +} \ No newline at end of file diff --git a/client/src/directives/vRecolorText.ts b/client/src/directives/vRecolorText.ts new file mode 100644 index 0000000..0d11887 --- /dev/null +++ b/client/src/directives/vRecolorText.ts @@ -0,0 +1,136 @@ +import {watch} from "vue"; +import {darkModeActive} from "@models/globals.ts"; + +function getLuminance(color: string): number { + let r = 0, g = 0, b = 0; + //parse hex color to RGB + if(/^#.*$/.test(color)) { + if (/^#(|[0-9A-Fa-f]{6})$/.test(color)) { + // Parse hex color + r = parseInt(color.substring(1, 3), 16); + g = parseInt(color.substring(3, 5), 16); + b = parseInt(color.substring(5, 7), 16); + } else if (/^#([0-9A-Fa-f]{3})$/.test(color)) { + // Parse short hex color + r = parseInt(color[1] + color[1], 16); + g = parseInt(color[2] + color[2], 16); + b = parseInt(color[3] + color[3], 16); + } else if (/^#([0-9A-Fa-f]{8})$/.test(color)) { + // Parse hex with alpha + r = parseInt(color.substring(1, 3), 16); + g = parseInt(color.substring(3, 5), 16); + b = parseInt(color.substring(5, 7), 16); + } else { + throw new Error('Invalid color format: cause: ' + color); + } + } else if (/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([\d.]+)\s*)?\)$/.test(color)) { + // Parse RGB or RGBA + const rgbaMatch = color.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([\d.]+)\s*)?\)/); + if (rgbaMatch) { + r = parseInt(rgbaMatch[1], 10); + g = parseInt(rgbaMatch[2], 10); + b = parseInt(rgbaMatch[3], 10); + } + } else { + throw new Error('Invalid color format: cause: ' + color); + } + // RGB to sRGB conversion + r = r / 255; + g = g / 255; + b = b / 255; + + // sRBG to linear RGB conversion + r = r <= 0.04045 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4); + g = g <= 0.04045 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4); + b = b <= 0.04045 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4); + + // Calculate luminance + return (0.1726 * r + 0.7552 * g + 0.0722 * b); +} + +const blackTextColor = '#181818'; +const whiteTextColor = '#E7E7E7'; +const blackLuminance = getLuminance(blackTextColor); +const whiteLuminance = getLuminance(whiteTextColor); + +const blackTextColorDeep = '#0B0B0B'; +const whiteTextColorDeep = '#F4F4F4'; +const blackLuminanceDeep = getLuminance(blackTextColorDeep); +const whiteLuminanceDeep = getLuminance(whiteTextColorDeep); + +const blackTextColorAbsolute = '#000000'; +const whiteTextColorAbsolute = '#FFFFFF'; +const blackLuminanceAbsolute = getLuminance(blackTextColorAbsolute); +const whiteLuminanceAbsolute = getLuminance(whiteTextColorAbsolute); + +export function useReadableTextColor(bgColor: string): string { + const bgLuminance = getLuminance(bgColor); + + let blackLighter = Math.max(bgLuminance, blackLuminance); + let blackDarker = Math.min(bgLuminance, blackLuminance); + let whiteLighter = Math.max(bgLuminance, whiteLuminance); + let whiteDarker = Math.min(bgLuminance, whiteLuminance); + + // Calculate contrast ratio + let blackRatio = (blackLighter + 0.05) / (blackDarker + 0.05); + let whiteRatio = (whiteLighter + 0.05) / (whiteDarker + 0.05); + // Return black or white based on luminance + if (blackRatio >= 4.5 || whiteRatio >= 4.5) { + //console.debug("bgL:", bgLuminance, "bL:", blackLuminance, "wL:", whiteLuminance, "bR:", blackRatio, "wR:", whiteRatio); + return blackRatio > whiteRatio ? '#181818' : '#E7E7E7'; + } + // If contrast is not enough, use deep colors + blackLighter = Math.max(bgLuminance, blackLuminanceDeep); + blackDarker = Math.min(bgLuminance, blackLuminanceDeep); + whiteLighter = Math.max(bgLuminance, whiteLuminanceDeep); + whiteDarker = Math.min(bgLuminance, whiteLuminanceDeep); + blackRatio = (blackLighter + 0.05) / (blackDarker + 0.05); + whiteRatio = (whiteLighter + 0.05) / (whiteDarker + 0.05); + if (blackRatio >= 4.5 || whiteRatio >= 4.5) { + //console.debug("bgL:", bgLuminance, "bL:", blackLuminanceDeep, "wL:", whiteLuminanceDeep, "bR:", blackRatio, "wR:", whiteRatio); + return blackRatio > whiteRatio ? '#0B0B0B' : '#F4F4F4'; + } + // If still not enough, use absolute colors + blackLighter = Math.max(bgLuminance, blackLuminanceAbsolute); + blackDarker = Math.min(bgLuminance, blackLuminanceAbsolute); + whiteLighter = Math.max(bgLuminance, whiteLuminanceAbsolute); + whiteDarker = Math.min(bgLuminance, whiteLuminanceAbsolute); + blackRatio = (blackLighter + 0.05) / (blackDarker + 0.05); + whiteRatio = (whiteLighter + 0.05) / (whiteDarker + 0.05); + if (blackRatio >= 4.5 || whiteRatio >= 4.5) { + //console.debug("bgL:", bgLuminance, "bL:", blackLuminanceAbsolute, "wL:", whiteLuminanceAbsolute, "bR:", blackRatio, "wR:", whiteRatio); + return blackRatio > whiteRatio ? '#000000' : '#FFFFFF'; + } + //console.warn(`Not enough contrast for background color: ${bgColor}. Using fallback colors.`); + return bgLuminance > 0.5 ? blackTextColor : whiteTextColor; // Fallback to default colors +} + +function updateTextColor(el: HTMLElement) { + el.style.color = useReadableTextColor(window.getComputedStyle(el).backgroundColor); +} + +export default { + mounted(el: HTMLElement) { + const updateColor = () => updateTextColor(el); + // Initial color update + updateColor(); + // Listen for background color changes + el.addEventListener('click', updateColor); + el.addEventListener('mouseover', updateColor); + el.addEventListener('mouseout', updateColor); + el.addEventListener('transitionend', updateColor); + watch(() => darkModeActive.value, () => updateTextColor(el)); + (el as any)._readableTextListeners = [updateColor]; + }, + unmounted(el: HTMLElement) { + // Remove event listeners + const listeners = (el as any)._readableTextListeners || []; + for (const listener of listeners) { + el.removeEventListener('click', listener); + el.removeEventListener('mouseover', listener); + el.removeEventListener('mouseout', listener); + el.removeEventListener('transitionend', listener); + } + delete (el as any)._readableTextListeners; + } +} \ No newline at end of file diff --git a/client/src/main.ts b/client/src/main.ts new file mode 100644 index 0000000..1b39d53 --- /dev/null +++ b/client/src/main.ts @@ -0,0 +1,26 @@ +import {createApp} from "vue"; +import '@css/base.css' +import '@css/main.css' +import App from './App.vue' +import router from "@/router"; +import { useToast } from "vue-toast-notification"; +import 'vue-toast-notification/dist/theme-bootstrap.css'; +import { session } from "@models/session.ts"; +import {jwtDecode} from 'jwt-decode'; +import type {SecureUser} from "@models/session.ts"; + +if (localStorage.getItem("token") && localStorage.getItem("username")) { + const decode: SecureUser = jwtDecode(localStorage.getItem("token") || ""); + session.user = { + username: localStorage.getItem("username") || "", + token: localStorage.getItem("token") || "", + role: decode?.role || "user" + }; + session.token = localStorage.getItem("token"); + +} + +createApp(App) + .use(router) + .use(useToast) + .mount('#app') diff --git a/client/src/models/TransferTypes.ts b/client/src/models/TransferTypes.ts new file mode 100644 index 0000000..c6e06e4 --- /dev/null +++ b/client/src/models/TransferTypes.ts @@ -0,0 +1,12 @@ +export interface DataEnvelope { + data: T; + message?: string; + error?: Error; +} +export interface DataListEnvelope extends DataEnvelope{ + data: T[]; + totalItems?: number; + pageLimit?: number; +} + +export type DynamicDataEnvelope = T extends (infer U)[] ? DataListEnvelope : DataEnvelope; \ No newline at end of file diff --git a/client/src/models/globals.ts b/client/src/models/globals.ts new file mode 100644 index 0000000..c959054 --- /dev/null +++ b/client/src/models/globals.ts @@ -0,0 +1,11 @@ +import { ref } from "vue"; + +export const isMobile = ref(window.innerWidth <= 768); +export function updateIsMobile() {isMobile.value = window.innerWidth <= 768;} + +export const routerTransitioning = ref(false); +export const subTabTransitioning = ref(false); + +const darkModePreference = window.matchMedia('(prefers-color-scheme: dark)'); +export const darkModeActive = ref(darkModePreference.matches); +darkModePreference.addEventListener('change', (e) => e.matches ? darkModeActive.value = true : darkModeActive.value = false); diff --git a/client/src/models/rest.ts b/client/src/models/rest.ts new file mode 100644 index 0000000..baefc94 --- /dev/null +++ b/client/src/models/rest.ts @@ -0,0 +1,30 @@ +import type {DynamicDataEnvelope} from "@models/TransferTypes.ts"; + +export const API_ROOT = (import.meta.env.VITE_API_ROOT ?? window.location.origin) + "/api"; + +async function rest(url: string, body?: unknown, method?: string, headers?: HeadersInit) { + const isFormData = body instanceof FormData; + const options: RequestInit = { + method: method ?? (body ? "POST" : "GET"), + headers: { + ...headers + }, + body: isFormData ? body : JSON.stringify(body) + }; + + if (!isFormData) { + options.headers = options.headers || {}; + (options.headers as Record)['Content-Type'] = 'application/json'; + } + + return await fetch(url, options) + .then(response => response.ok ? response.json() : response.json().then(err => Promise.reject(err))) + .catch(err => Promise.reject(err)); +} + +export async function api(action: string, body?: unknown, method?: string, headers?: HeadersInit) { + return rest(`${API_ROOT}${action}`, body, method, headers).then(data => { + if (data && typeof data === 'object' && 'data' in data) return data as DynamicDataEnvelope; + else throw new Error("Invalid response format"); + }) as Promise>; +} \ No newline at end of file diff --git a/client/src/models/session.ts b/client/src/models/session.ts new file mode 100644 index 0000000..5120fd9 --- /dev/null +++ b/client/src/models/session.ts @@ -0,0 +1,61 @@ +import {reactive} from "vue"; +import {useRouter} from "vue-router"; +import {toast} from "@models/toast.ts"; +import { type DataEnvelope } from "./TransferTypes"; +import {api} from "@models/rest.ts"; + +export interface SecureUser { + username: string; + role?: string; + id?: number; + token?: string; +} + +export const session = reactive({ + user: null as SecureUser | null, + token: null as string | null, + redirectURL: null as string | null, + messages: [] as { + type: string, + message: string + }[], +}); + +export function useLogin() { + const router = useRouter(); + return { + async login(username: string, password: string): Promise { + return await api("/users/login", {username, password}, "POST") + .then((response: DataEnvelope ) => { + if (!response.data) throw new Error("Invalid login credentials. Please try again."); + session.user = response.data; + if (!session.user) throw new Error("Invalid login credentials. Please try again."); + session.token = response.data.token || null; + router.push(session.redirectURL ?? "/").then((r) => r); + session.redirectURL = null; + toast.success("Welcome " + session.user.username + "!\nYou are now logged in."); + localStorage.setItem("username", session.user.username); + localStorage.setItem("token", session.token ?? ""); + return session.user; + }) + .catch((envelope: DataEnvelope)=>{ + toast.error(envelope.message || envelope.error?.message || "An error occurred while trying to log in. Please try again later.") + }) as SecureUser; + }, + async logout(): Promise { + session.user = null; + session.token = null; + localStorage.removeItem("token"); + localStorage.removeItem("username"); + for(let i = 0; i < session.messages.length; i++) { + console.debug("Messages: "); + if(session.messages[i].type === "error") { + console.error(session.messages[i].message); + } else { + console.debug(session.messages[i].message); + } + } + router.push('/').then((r) => r); + } + } +} \ No newline at end of file diff --git a/client/src/models/toast.ts b/client/src/models/toast.ts new file mode 100644 index 0000000..e86a241 --- /dev/null +++ b/client/src/models/toast.ts @@ -0,0 +1,8 @@ +import { useToast } from "vue-toast-notification"; +export const toast = useToast({ + position: 'top', + duration: 5000, + dismissible: true, + pauseOnHover: true, + type: 'default', +}) \ No newline at end of file diff --git a/client/src/router/index.ts b/client/src/router/index.ts new file mode 100644 index 0000000..004a4b8 --- /dev/null +++ b/client/src/router/index.ts @@ -0,0 +1,78 @@ +import {createRouter, createWebHashHistory} from 'vue-router' +import {session} from '@models/session.ts'; +import { toast } from '@models/toast.ts'; + +import {jwtDecode} from 'jwt-decode'; + +const routes = [ + + { + path: '/', + name: 'Main Page', + component: () => import('@views/MainPage.vue') + }, + { + path: '/about', + name: 'About', + component: () => import('@views/AboutPage.vue') + }, + { + path: '/contact', + name: 'Contact', + component: () => import('@views/ContactPage.vue') + }, + { + path: '/login', + name: 'Login', + component: () => import('@views/LoginPage.vue') + } +] + +const router = createRouter({ + history: createWebHashHistory(), + routes +}) + +router.beforeEach((to, from, next) => { + if (to.meta.requiresAuth) { + const token = session.token ?? localStorage.getItem('token'); + if (!token) { + session.redirectURL = to.fullPath; // Save the intended route + return next("Login"); + } + try { + const decoded: any = jwtDecode(token); + if( !decoded ) { + toast.error("Invalid token. Please log in again."); + session.token = null; + localStorage.removeItem('token'); + session.user = null; + localStorage.removeItem('username'); + return next("Login"); + } + if (decoded.exp * 1000 < Date.now()) { + toast.error("Token expired. Please log in again."); + session.token = null; + localStorage.removeItem('token'); + session.user = null; + localStorage.removeItem('username'); + return next("Login"); + } + if (decoded.role === 'admin') { + return next(); + } else if (decoded.role === 'user') { + toast.error("You do not have permission to access this page."); + return from.fullPath; + } + else { + return next({name: 'NotFound'}); + } + } catch (e) { + return next({name: 'NotFound'}); + } + } + next(); +}); + + +export default router \ No newline at end of file diff --git a/client/src/views/AboutPage.vue b/client/src/views/AboutPage.vue new file mode 100644 index 0000000..92819fc --- /dev/null +++ b/client/src/views/AboutPage.vue @@ -0,0 +1,117 @@ + + + + + \ No newline at end of file diff --git a/client/src/views/ContactPage.vue b/client/src/views/ContactPage.vue new file mode 100644 index 0000000..74aad98 --- /dev/null +++ b/client/src/views/ContactPage.vue @@ -0,0 +1,102 @@ + + +