diff --git a/.dockerignore b/.dockerignore
index f7fcf12934..2ea288d039 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -9,5 +9,12 @@
/frontend/dist
/frontend/.env.*
/frontend/public/environment.*
+/frontend-prototype/data
+/frontend-prototype/dist
+/frontend-prototype/.env.*
+/frontend-vue3/data
+/frontend-vue3/dist
+/frontend-vue3/.env.*
+/frontend-vue3/public/environment.*
**/vendor/
**/node_modules/
diff --git a/docker-compose.yml b/docker-compose.yml
index f17e431786..d755b408c6 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,6 +2,28 @@ services:
frontend:
image: node:24.8.0
container_name: 'ecamp3-frontend'
+ stdin_open: true
+ tty: true
+ user: ${USER_ID:-1000}
+ volumes:
+ - ./.prettierrc:/.prettierrc:delegated
+ - ./frontend:/app:delegated
+ - ./common:/common:delegated
+ - ./pdf:/pdf:delegated
+ - ./.cache/npm:/home/node/.npm/_cacache:delegated
+ - ./.cache/npm/sentry-cli:/home/node/.npm/sentry-cli:delegated
+ environment:
+ - NODE_ENV=development
+ - NPM_CONFIG_UPDATE_NOTIFIER=false
+ - NPM_CONFIG_CACHE=/home/node/.npm
+ - CI=${CI}
+ working_dir: /app
+ command: ./docker-setup.sh
+ depends_on:
+ - pdf
+
+ frontend-vue3:
+ image: node:24.5.0
ports:
- '9229:9229' # jest debug
stdin_open: true
@@ -9,7 +31,29 @@ services:
user: ${USER_ID:-1000}
volumes:
- ./.prettierrc:/.prettierrc:delegated
- - ./frontend:/app:delegated
+ - ./frontend-vue3:/app:delegated
+ - ./common:/common:delegated
+ - ./pdf:/pdf:delegated
+ - ./.cache/npm:/home/node/.npm/_cacache:delegated
+ - ./.cache/npm/sentry-cli:/home/node/.npm/sentry-cli:delegated
+ environment:
+ - NODE_ENV=development
+ - NPM_CONFIG_UPDATE_NOTIFIER=false
+ - NPM_CONFIG_CACHE=/home/node/.npm
+ - CI=${CI}
+ working_dir: /app
+ command: ./docker-setup.sh
+ depends_on:
+ - pdf
+
+ frontend-prototype:
+ image: node:24.5.0
+ stdin_open: true
+ tty: true
+ user: ${USER_ID:-1000}
+ volumes:
+ - ./.prettierrc:/.prettierrc:delegated
+ - ./frontend-prototype:/app:delegated
- ./common:/common:delegated
- ./pdf:/pdf:delegated
- ./.cache/npm:/home/node/.npm/_cacache:delegated
@@ -201,6 +245,8 @@ services:
depends_on:
- frontend
- api
+ - frontend-vue3
+ - frontend-prototype
ports:
- target: 3000
published: 3000
diff --git a/frontend-prototype/.browserslistrc b/frontend-prototype/.browserslistrc
new file mode 100644
index 0000000000..dc3bc09a24
--- /dev/null
+++ b/frontend-prototype/.browserslistrc
@@ -0,0 +1,4 @@
+> 1%
+last 2 versions
+not dead
+not ie 11
diff --git a/frontend-prototype/.editorconfig b/frontend-prototype/.editorconfig
new file mode 100644
index 0000000000..7053c49a04
--- /dev/null
+++ b/frontend-prototype/.editorconfig
@@ -0,0 +1,5 @@
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/frontend-prototype/.eslintrc-auto-import.json b/frontend-prototype/.eslintrc-auto-import.json
new file mode 100644
index 0000000000..7ea7de726a
--- /dev/null
+++ b/frontend-prototype/.eslintrc-auto-import.json
@@ -0,0 +1,82 @@
+{
+ "globals": {
+ "Component": true,
+ "ComponentPublicInstance": true,
+ "ComputedRef": true,
+ "DirectiveBinding": true,
+ "EffectScope": true,
+ "ExtractDefaultPropTypes": true,
+ "ExtractPropTypes": true,
+ "ExtractPublicPropTypes": true,
+ "InjectionKey": true,
+ "MaybeRef": true,
+ "MaybeRefOrGetter": true,
+ "PropType": true,
+ "Ref": true,
+ "Slot": true,
+ "Slots": true,
+ "VNode": true,
+ "WritableComputedRef": true,
+ "computed": true,
+ "createApp": true,
+ "customRef": true,
+ "defineAsyncComponent": true,
+ "defineComponent": true,
+ "defineStore": true,
+ "effectScope": true,
+ "getCurrentInstance": true,
+ "getCurrentScope": true,
+ "h": true,
+ "inject": true,
+ "isProxy": true,
+ "isReactive": true,
+ "isReadonly": true,
+ "isRef": true,
+ "markRaw": true,
+ "nextTick": true,
+ "onActivated": true,
+ "onBeforeMount": true,
+ "onBeforeRouteLeave": true,
+ "onBeforeRouteUpdate": true,
+ "onBeforeUnmount": true,
+ "onBeforeUpdate": true,
+ "onDeactivated": true,
+ "onErrorCaptured": true,
+ "onMounted": true,
+ "onRenderTracked": true,
+ "onRenderTriggered": true,
+ "onScopeDispose": true,
+ "onServerPrefetch": true,
+ "onUnmounted": true,
+ "onUpdated": true,
+ "onWatcherCleanup": true,
+ "provide": true,
+ "reactive": true,
+ "readonly": true,
+ "ref": true,
+ "resolveComponent": true,
+ "shallowReactive": true,
+ "shallowReadonly": true,
+ "shallowRef": true,
+ "storeToRefs": true,
+ "toRaw": true,
+ "toRef": true,
+ "toRefs": true,
+ "toValue": true,
+ "triggerRef": true,
+ "unref": true,
+ "useAttrs": true,
+ "useCssModule": true,
+ "useCssVars": true,
+ "useId": true,
+ "useModel": true,
+ "useRoute": true,
+ "useRouter": true,
+ "useSlots": true,
+ "useTemplateRef": true,
+ "watch": true,
+ "watchEffect": true,
+ "watchPostEffect": true,
+ "watchSyncEffect": true
+ }
+}
diff --git a/frontend-prototype/.gitignore b/frontend-prototype/.gitignore
new file mode 100644
index 0000000000..11f5d71423
--- /dev/null
+++ b/frontend-prototype/.gitignore
@@ -0,0 +1,22 @@
+.DS_Store
+node_modules
+/dist
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/frontend-prototype/README.md b/frontend-prototype/README.md
new file mode 100644
index 0000000000..f58f67680a
--- /dev/null
+++ b/frontend-prototype/README.md
@@ -0,0 +1,79 @@
+# Vuetify (Default)
+
+This is the official scaffolding tool for Vuetify, designed to give you a head start in building your new Vuetify application. It sets up a base template with all the necessary configurations and standard directory structure, enabling you to begin development without the hassle of setting up the project from scratch.
+
+## ❗️ Important Links
+
+- 📄 [Docs](https://vuetifyjs.com/)
+- 🚨 [Issues](https://issues.vuetifyjs.com/)
+- 🏬 [Store](https://store.vuetifyjs.com/)
+- 🎮 [Playground](https://play.vuetifyjs.com/)
+- 💬 [Discord](https://community.vuetifyjs.com)
+
+## 💿 Install
+
+Set up your project using your preferred package manager. Use the corresponding command to install the dependencies:
+
+| Package Manager | Command |
+|---------------------------------------------------------------|----------------|
+| [yarn](https://yarnpkg.com/getting-started) | `yarn install` |
+| [npm](https://docs.npmjs.com/cli/v7/commands/npm-install) | `npm install` |
+| [pnpm](https://pnpm.io/installation) | `pnpm install` |
+| [bun](https://bun.sh/#getting-started) | `bun install` |
+
+After completing the installation, your environment is ready for Vuetify development.
+
+## ✨ Features
+
+- 🖼️ **Optimized Front-End Stack**: Leverage the latest Vue 3 and Vuetify 3 for a modern, reactive UI development experience. [Vue 3](https://v3.vuejs.org/) | [Vuetify 3](https://vuetifyjs.com/en/)
+- 🗃️ **State Management**: Integrated with [Pinia](https://pinia.vuejs.org/), the intuitive, modular state management solution for Vue.
+- 🚦 **Routing and Layouts**: Utilizes Vue Router for SPA navigation and vite-plugin-vue-layouts for organizing Vue file layouts. [Vue Router](https://router.vuejs.org/) | [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts)
+- ⚡ **Next-Gen Tooling**: Powered by Vite, experience fast cold starts and instant HMR (Hot Module Replacement). [Vite](https://vitejs.dev/)
+- 🧩 **Automated Component Importing**: Streamline your workflow with unplugin-vue-components, automatically importing components as you use them. [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components)
+
+These features are curated to provide a seamless development experience from setup to deployment, ensuring that your Vuetify application is both powerful and maintainable.
+
+## 💡 Usage
+
+This section covers how to start the development server and build your project for production.
+
+### Starting the Development Server
+
+To start the development server with hot-reload, run the following command. The server will be accessible at [http://localhost:3000](http://localhost:3000):
+
+```bash
+yarn dev
+```
+
+(Repeat for npm, pnpm, and bun with respective commands.)
+
+> Add NODE_OPTIONS='--no-warnings' to suppress the JSON import warnings that happen as part of the Vuetify import mapping. If you are on Node [v21.3.0](https://nodejs.org/en/blog/release/v21.3.0) or higher, you can change this to NODE_OPTIONS='--disable-warning=5401'. If you don't mind the warning, you can remove this from your package.json dev script.
+
+### Building for Production
+
+To build your project for production, use:
+
+```bash
+yarn build
+```
+
+(Repeat for npm, pnpm, and bun with respective commands.)
+
+Once the build process is completed, your application will be ready for deployment in a production environment.
+
+## 💪 Support Vuetify Development
+
+This project is built with [Vuetify](https://vuetifyjs.com/en/), a UI Library with a comprehensive collection of Vue components. Vuetify is an MIT licensed Open Source project that has been made possible due to the generous contributions by our [sponsors and backers](https://vuetifyjs.com/introduction/sponsors-and-backers/). If you are interested in supporting this project, please consider:
+
+- [Requesting Enterprise Support](https://support.vuetifyjs.com/)
+- [Sponsoring John on Github](https://github.com/users/johnleider/sponsorship)
+- [Sponsoring Kael on Github](https://github.com/users/kaelwd/sponsorship)
+- [Supporting the team on Open Collective](https://opencollective.com/vuetify)
+- [Becoming a sponsor on Patreon](https://www.patreon.com/vuetify)
+- [Becoming a subscriber on Tidelift](https://tidelift.com/subscription/npm/vuetify)
+- [Making a one-time donation with Paypal](https://paypal.me/vuetify)
+
+## 📑 License
+[MIT](http://opensource.org/licenses/MIT)
+
+Copyright (c) 2016-present Vuetify, LLC
diff --git a/frontend-prototype/auto-imports.d.ts b/frontend-prototype/auto-imports.d.ts
new file mode 100644
index 0000000000..8f3b17e064
--- /dev/null
+++ b/frontend-prototype/auto-imports.d.ts
@@ -0,0 +1,147 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// noinspection JSUnusedGlobalSymbols
+// Generated by unplugin-auto-import
+// biome-ignore lint: disable
+export {}
+declare global {
+ const EffectScope: typeof import('vue')['EffectScope']
+ const computed: typeof import('vue')['computed']
+ const createApp: typeof import('vue')['createApp']
+ const customRef: typeof import('vue')['customRef']
+ const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
+ const defineComponent: typeof import('vue')['defineComponent']
+ const defineStore: typeof import('pinia')['defineStore']
+ const effectScope: typeof import('vue')['effectScope']
+ const getCurrentInstance: typeof import('vue')['getCurrentInstance']
+ const getCurrentScope: typeof import('vue')['getCurrentScope']
+ const h: typeof import('vue')['h']
+ const inject: typeof import('vue')['inject']
+ const isProxy: typeof import('vue')['isProxy']
+ const isReactive: typeof import('vue')['isReactive']
+ const isReadonly: typeof import('vue')['isReadonly']
+ const isRef: typeof import('vue')['isRef']
+ const markRaw: typeof import('vue')['markRaw']
+ const nextTick: typeof import('vue')['nextTick']
+ const onActivated: typeof import('vue')['onActivated']
+ const onBeforeMount: typeof import('vue')['onBeforeMount']
+ const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
+ const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
+ const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
+ const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
+ const onDeactivated: typeof import('vue')['onDeactivated']
+ const onErrorCaptured: typeof import('vue')['onErrorCaptured']
+ const onMounted: typeof import('vue')['onMounted']
+ const onRenderTracked: typeof import('vue')['onRenderTracked']
+ const onRenderTriggered: typeof import('vue')['onRenderTriggered']
+ const onScopeDispose: typeof import('vue')['onScopeDispose']
+ const onServerPrefetch: typeof import('vue')['onServerPrefetch']
+ const onUnmounted: typeof import('vue')['onUnmounted']
+ const onUpdated: typeof import('vue')['onUpdated']
+ const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
+ const provide: typeof import('vue')['provide']
+ const reactive: typeof import('vue')['reactive']
+ const readonly: typeof import('vue')['readonly']
+ const ref: typeof import('vue')['ref']
+ const resolveComponent: typeof import('vue')['resolveComponent']
+ const shallowReactive: typeof import('vue')['shallowReactive']
+ const shallowReadonly: typeof import('vue')['shallowReadonly']
+ const shallowRef: typeof import('vue')['shallowRef']
+ const storeToRefs: typeof import('pinia')['storeToRefs']
+ const toRaw: typeof import('vue')['toRaw']
+ const toRef: typeof import('vue')['toRef']
+ const toRefs: typeof import('vue')['toRefs']
+ const toValue: typeof import('vue')['toValue']
+ const triggerRef: typeof import('vue')['triggerRef']
+ const unref: typeof import('vue')['unref']
+ const useAttrs: typeof import('vue')['useAttrs']
+ const useCssModule: typeof import('vue')['useCssModule']
+ const useCssVars: typeof import('vue')['useCssVars']
+ const useId: typeof import('vue')['useId']
+ const useModel: typeof import('vue')['useModel']
+ const useRoute: typeof import('vue-router')['useRoute']
+ const useRouter: typeof import('vue-router')['useRouter']
+ const useSlots: typeof import('vue')['useSlots']
+ const useTemplateRef: typeof import('vue')['useTemplateRef']
+ const watch: typeof import('vue')['watch']
+ const watchEffect: typeof import('vue')['watchEffect']
+ const watchPostEffect: typeof import('vue')['watchPostEffect']
+ const watchSyncEffect: typeof import('vue')['watchSyncEffect']
+}
+// for type re-export
+declare global {
+ // @ts-ignore
+ export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
+ import('vue')
+}
+
+// for vue template auto import
+import { UnwrapRef } from 'vue'
+declare module 'vue' {
+ interface GlobalComponents {}
+ interface ComponentCustomProperties {
+ readonly EffectScope: UnwrapRef
+ readonly computed: UnwrapRef
+ readonly createApp: UnwrapRef
+ readonly customRef: UnwrapRef
+ readonly defineAsyncComponent: UnwrapRef
+ readonly defineComponent: UnwrapRef
+ readonly defineStore: UnwrapRef
+ readonly effectScope: UnwrapRef
+ readonly getCurrentInstance: UnwrapRef
+ readonly getCurrentScope: UnwrapRef
+ readonly h: UnwrapRef
+ readonly inject: UnwrapRef
+ readonly isProxy: UnwrapRef
+ readonly isReactive: UnwrapRef
+ readonly isReadonly: UnwrapRef
+ readonly isRef: UnwrapRef
+ readonly markRaw: UnwrapRef
+ readonly nextTick: UnwrapRef
+ readonly onActivated: UnwrapRef
+ readonly onBeforeMount: UnwrapRef
+ readonly onBeforeRouteLeave: UnwrapRef
+ readonly onBeforeRouteUpdate: UnwrapRef
+ readonly onBeforeUnmount: UnwrapRef
+ readonly onBeforeUpdate: UnwrapRef
+ readonly onDeactivated: UnwrapRef
+ readonly onErrorCaptured: UnwrapRef
+ readonly onMounted: UnwrapRef
+ readonly onRenderTracked: UnwrapRef
+ readonly onRenderTriggered: UnwrapRef
+ readonly onScopeDispose: UnwrapRef
+ readonly onServerPrefetch: UnwrapRef
+ readonly onUnmounted: UnwrapRef
+ readonly onUpdated: UnwrapRef
+ readonly onWatcherCleanup: UnwrapRef
+ readonly provide: UnwrapRef
+ readonly reactive: UnwrapRef
+ readonly readonly: UnwrapRef
+ readonly ref: UnwrapRef
+ readonly resolveComponent: UnwrapRef
+ readonly shallowReactive: UnwrapRef
+ readonly shallowReadonly: UnwrapRef
+ readonly shallowRef: UnwrapRef
+ readonly storeToRefs: UnwrapRef
+ readonly toRaw: UnwrapRef
+ readonly toRef: UnwrapRef
+ readonly toRefs: UnwrapRef
+ readonly toValue: UnwrapRef
+ readonly triggerRef: UnwrapRef
+ readonly unref: UnwrapRef
+ readonly useAttrs: UnwrapRef
+ readonly useCssModule: UnwrapRef
+ readonly useCssVars: UnwrapRef
+ readonly useId: UnwrapRef
+ readonly useModel: UnwrapRef
+ readonly useRoute: UnwrapRef
+ readonly useRouter: UnwrapRef
+ readonly useSlots: UnwrapRef
+ readonly useTemplateRef: UnwrapRef
+ readonly watch: UnwrapRef
+ readonly watchEffect: UnwrapRef
+ readonly watchPostEffect: UnwrapRef
+ readonly watchSyncEffect: UnwrapRef
+ }
+}
\ No newline at end of file
diff --git a/frontend-prototype/components.d.ts b/frontend-prototype/components.d.ts
new file mode 100644
index 0000000000..46aff5f878
--- /dev/null
+++ b/frontend-prototype/components.d.ts
@@ -0,0 +1,19 @@
+/* eslint-disable */
+// @ts-nocheck
+// Generated by unplugin-vue-components
+// Read more: https://github.com/vuejs/core/pull/3399
+// biome-ignore lint: disable
+export {}
+
+/* prettier-ignore */
+declare module 'vue' {
+ export interface GlobalComponents {
+ AppBarItem: typeof import('./src/components/AppBarItem.vue')['default']
+ AppFooter: typeof import('./src/components/AppFooter.vue')['default']
+ HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
+ Logo: typeof import('./src/components/Logo.vue')['default']
+ RouterLink: typeof import('vue-router')['RouterLink']
+ RouterView: typeof import('vue-router')['RouterView']
+ UserMeta: typeof import('./src/components/UserMeta.vue')['default']
+ }
+}
diff --git a/frontend-prototype/docker-setup.sh b/frontend-prototype/docker-setup.sh
new file mode 100755
index 0000000000..f0d3b16631
--- /dev/null
+++ b/frontend-prototype/docker-setup.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -euo pipefail
+
+BASEDIR=$(dirname "$0")
+
+if [ "$CI" = 'true' ] ; then
+ npm ci --verbose
+ npm run build
+ npm run preview
+else
+ npm install
+ npm run dev
+fi
diff --git a/frontend-prototype/eslint.config.js b/frontend-prototype/eslint.config.js
new file mode 100644
index 0000000000..bb027414d0
--- /dev/null
+++ b/frontend-prototype/eslint.config.js
@@ -0,0 +1,3 @@
+import vuetify from 'eslint-config-vuetify'
+
+export default vuetify()
diff --git a/frontend-prototype/index.html b/frontend-prototype/index.html
new file mode 100644
index 0000000000..0a84a1cdd1
--- /dev/null
+++ b/frontend-prototype/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Welcome to Vuetify 3
+
+
+
+
+
+
diff --git a/frontend-prototype/jsconfig.json b/frontend-prototype/jsconfig.json
new file mode 100644
index 0000000000..dad0634ca4
--- /dev/null
+++ b/frontend-prototype/jsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "allowJs": true,
+ "target": "es5",
+ "module": "esnext",
+ "baseUrl": "./",
+ "moduleResolution": "bundler",
+ "paths": {
+ "@/*": [
+ "src/*"
+ ]
+ },
+ "lib": [
+ "esnext",
+ "dom",
+ "dom.iterable",
+ "scripthost"
+ ]
+ }
+}
diff --git a/frontend-prototype/package-lock.json b/frontend-prototype/package-lock.json
new file mode 100644
index 0000000000..de6fa429bf
--- /dev/null
+++ b/frontend-prototype/package-lock.json
@@ -0,0 +1,5780 @@
+{
+ "name": "frontend-prototype",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "frontend-prototype",
+ "version": "0.0.0",
+ "dependencies": {
+ "@fontsource/roboto": "5.2.7",
+ "@mdi/font": "7.4.47",
+ "inter-ui": "3.19.3",
+ "pinia": "^3.0.3",
+ "vue": "^3.5.21",
+ "vue-router": "^4.5.1",
+ "vuetify": "^3.10.1"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^6.0.1",
+ "eslint": "^9.35.0",
+ "eslint-config-vuetify": "^4.2.0",
+ "sass-embedded": "^1.92.1",
+ "unplugin-auto-import": "^19.3.0",
+ "unplugin-fonts": "^1.4.0",
+ "unplugin-vue-components": "^29.0.0",
+ "unplugin-vue-router": "^0.15.0",
+ "vite": "^7.1.5",
+ "vite-plugin-vue-layouts-next": "^1.0.0",
+ "vite-plugin-vuetify": "^2.1.2"
+ }
+ },
+ "node_modules/@apidevtools/json-schema-ref-parser": {
+ "version": "14.2.1",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-14.2.1.tgz",
+ "integrity": "sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-yaml": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/philsturgeon"
+ },
+ "peerDependencies": {
+ "@types/json-schema": "^7.0.15"
+ }
+ },
+ "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.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
+ "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.4"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
+ "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bufbuild/protobuf": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.9.0.tgz",
+ "integrity": "sha512-rnJenoStJ8nvmt9Gzye8nkYd6V22xUAnu4086ER7h1zJ508vStko4pMvDeQ446ilDTFpV5wnoc5YS7XvMwwMqA==",
+ "devOptional": true,
+ "license": "(Apache-2.0 AND BSD-3-Clause)"
+ },
+ "node_modules/@clack/core": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz",
+ "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picocolors": "^1.0.0",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "node_modules/@clack/prompts": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz",
+ "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@clack/core": "0.5.0",
+ "picocolors": "^1.0.0",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz",
+ "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz",
+ "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz",
+ "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz",
+ "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz",
+ "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz",
+ "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz",
+ "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz",
+ "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz",
+ "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz",
+ "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz",
+ "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz",
+ "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz",
+ "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz",
+ "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz",
+ "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz",
+ "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz",
+ "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz",
+ "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz",
+ "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz",
+ "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz",
+ "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz",
+ "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz",
+ "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/compat": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.4.0.tgz",
+ "integrity": "sha512-DEzm5dKeDBPm3r08Ixli/0cmxr8LkRdwxMRUIJBlSCpAwSrvFEJpVBzV+66JhDxiaqKxnRzCXhtiMiczF7Hglg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.16.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "peerDependencies": {
+ "eslint": "^8.40 || 9"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/compat/node_modules/@eslint/core": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz",
+ "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.36.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz",
+ "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.15.2",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@fontsource/roboto": {
+ "version": "5.2.7",
+ "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.2.7.tgz",
+ "integrity": "sha512-fca6Jtyxn6kPR51+TTTMCFm0FOhnKaLEYYiAQc8P/4iFCKoKGR0aX89QR4CfP+N64RPXJus64UxhJaVENnSM6Q==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@mdi/font": {
+ "version": "7.4.47",
+ "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz",
+ "integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@parcel/watcher": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
+ "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
+ "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.29",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.29.tgz",
+ "integrity": "sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz",
+ "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz",
+ "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz",
+ "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz",
+ "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz",
+ "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz",
+ "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz",
+ "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz",
+ "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz",
+ "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz",
+ "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz",
+ "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz",
+ "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz",
+ "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz",
+ "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz",
+ "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz",
+ "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz",
+ "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz",
+ "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz",
+ "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz",
+ "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz",
+ "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz",
+ "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@stylistic/eslint-plugin": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.4.0.tgz",
+ "integrity": "sha512-UG8hdElzuBDzIbjG1QDwnYH0MQ73YLXDFHgZzB4Zh/YJfnw8XNsloVtytqzx0I2Qky9THSdpTmi8Vjn/pf/Lew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.9.0",
+ "@typescript-eslint/types": "^8.44.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "estraverse": "^5.3.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=9.0.0"
+ }
+ },
+ "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==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.45.0.tgz",
+ "integrity": "sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.45.0",
+ "@typescript-eslint/type-utils": "8.45.0",
+ "@typescript-eslint/utils": "8.45.0",
+ "@typescript-eslint/visitor-keys": "8.45.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.45.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.45.0.tgz",
+ "integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.45.0",
+ "@typescript-eslint/types": "8.45.0",
+ "@typescript-eslint/typescript-estree": "8.45.0",
+ "@typescript-eslint/visitor-keys": "8.45.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.45.0.tgz",
+ "integrity": "sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.45.0",
+ "@typescript-eslint/types": "^8.45.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz",
+ "integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.45.0",
+ "@typescript-eslint/visitor-keys": "8.45.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz",
+ "integrity": "sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.45.0.tgz",
+ "integrity": "sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.45.0",
+ "@typescript-eslint/typescript-estree": "8.45.0",
+ "@typescript-eslint/utils": "8.45.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
+ "integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz",
+ "integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.45.0",
+ "@typescript-eslint/tsconfig-utils": "8.45.0",
+ "@typescript-eslint/types": "8.45.0",
+ "@typescript-eslint/visitor-keys": "8.45.0",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/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/@typescript-eslint/utils": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz",
+ "integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.45.0",
+ "@typescript-eslint/types": "8.45.0",
+ "@typescript-eslint/typescript-estree": "8.45.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz",
+ "integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.45.0",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.1.tgz",
+ "integrity": "sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rolldown/pluginutils": "1.0.0-beta.29"
+ },
+ "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/@vue-macros/common": {
+ "version": "3.0.0-beta.16",
+ "resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-3.0.0-beta.16.tgz",
+ "integrity": "sha512-8O2gWxWFiaoNkk7PGi0+p7NPGe/f8xJ3/INUufvje/RZOs7sJvlI1jnR4lydtRFa/mU0ylMXUXXjSK0fHDEYTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-sfc": "^3.5.17",
+ "ast-kit": "^2.1.1",
+ "local-pkg": "^1.1.1",
+ "magic-string-ast": "^1.0.0",
+ "unplugin-utils": "^0.2.4"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/vue-macros"
+ },
+ "peerDependencies": {
+ "vue": "^2.7.0 || ^3.2.25"
+ },
+ "peerDependenciesMeta": {
+ "vue": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz",
+ "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.4",
+ "@vue/shared": "3.5.22",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz",
+ "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.22",
+ "@vue/shared": "3.5.22"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz",
+ "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.4",
+ "@vue/compiler-core": "3.5.22",
+ "@vue/compiler-dom": "3.5.22",
+ "@vue/compiler-ssr": "3.5.22",
+ "@vue/shared": "3.5.22",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.19",
+ "postcss": "^8.5.6",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz",
+ "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.22",
+ "@vue/shared": "3.5.22"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz",
+ "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.7"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz",
+ "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.7",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz",
+ "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==",
+ "license": "MIT",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/language-core": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.1.0.tgz",
+ "integrity": "sha512-a7ns+X9vTbdmk7QLrvnZs8s4E1wwtxG/sELzr6F2j4pU+r/OoAv6jJGSz+5tVTU6e4+3rjepGhSP8jDmBBcb3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/language-core": "2.4.23",
+ "@vue/compiler-dom": "^3.5.0",
+ "@vue/shared": "^3.5.0",
+ "alien-signals": "^3.0.0",
+ "muggle-string": "^0.4.1",
+ "path-browserify": "^1.0.1",
+ "picomatch": "^4.0.2"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.22.tgz",
+ "integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.22"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.22.tgz",
+ "integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.22",
+ "@vue/shared": "3.5.22"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz",
+ "integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.22",
+ "@vue/runtime-core": "3.5.22",
+ "@vue/shared": "3.5.22",
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.22.tgz",
+ "integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.22",
+ "@vue/shared": "3.5.22"
+ },
+ "peerDependencies": {
+ "vue": "3.5.22"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz",
+ "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==",
+ "license": "MIT"
+ },
+ "node_modules/@vuetify/loader-shared": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@vuetify/loader-shared/-/loader-shared-2.1.1.tgz",
+ "integrity": "sha512-jSZTzTYaoiv8iwonFCVZQ0YYX/M+Uyl4ng+C4egMJT0Hcmh9gIxJL89qfZICDeo3g0IhqrvipW2FFKKRDMtVcA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "upath": "^2.0.1"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0",
+ "vuetify": "^3.0.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/alien-signals": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.0.0.tgz",
+ "integrity": "sha512-JHoRJf18Y6HN4/KZALr3iU+0vW9LKG+8FMThQlbn4+gv8utsLIkwpomjElGPccGeNwh0FI2HN6BLnyFLo6OyLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/anymatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/ast-kit": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.1.2.tgz",
+ "integrity": "sha512-cl76xfBQM6pztbrFWRnxbrDm9EOqDr1BF6+qQnnDZG2Co2LjyUktkN9GTJfBAfdae+DbT2nJf2nCGAdDDN7W2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.0",
+ "pathe": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/ast-walker-scope": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.8.2.tgz",
+ "integrity": "sha512-3pYeLyDZ6nJew9QeBhS4Nly02269Dkdk32+zdbbKmL6n4ZuaGorwwA+xx12xgOciA8BF1w9x+dlH7oUkFTW91w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.3",
+ "ast-kit": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "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/baseline-browser-mapping": {
+ "version": "2.8.11",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.11.tgz",
+ "integrity": "sha512-i+sRXGhz4+QW8aACZ3+r1GAKMt0wlFpeA8M5rOQd0HEYw9zhDrlx9Wc8uQ0IdXakjJRthzglEwfB/yqIjO6iDg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/birpc": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.6.1.tgz",
+ "integrity": "sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.26.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz",
+ "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.8.9",
+ "caniuse-lite": "^1.0.30001746",
+ "electron-to-chromium": "^1.5.227",
+ "node-releases": "^2.0.21",
+ "update-browserslist-db": "^1.1.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer-builder": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz",
+ "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==",
+ "devOptional": true,
+ "license": "MIT/X11"
+ },
+ "node_modules/builtin-modules": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz",
+ "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001747",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001747.tgz",
+ "integrity": "sha512-mzFa2DGIhuc5490Nd/G31xN1pnBnYMadtkyTjefPI7wzypqgCEpeWu9bJr0OnDsyKrW75zA9ZAt7pbQFmwLsQg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/change-case": {
+ "version": "5.4.4",
+ "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz",
+ "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz",
+ "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/citty": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz",
+ "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "consola": "^3.2.3"
+ }
+ },
+ "node_modules/clean-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
+ "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/clean-regexp/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colorjs.io": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz",
+ "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/comment-parser": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+ "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12.0.0"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/confbox": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
+ "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/consola": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0"
+ }
+ },
+ "node_modules/copy-anything": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
+ "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
+ "license": "MIT",
+ "dependencies": {
+ "is-what": "^4.1.8"
+ },
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.45.1",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz",
+ "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.25.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "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/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/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==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.230",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.230.tgz",
+ "integrity": "sha512-A6A6Fd3+gMdaed9wX83CvHYJb4UuapPD5X5SLq72VZJzxHSY0/LUweGXRWmQlh2ln7KV7iw7jnwXK7dlPoOnHQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/empathic": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz",
+ "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "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.10",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
+ "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.10",
+ "@esbuild/android-arm": "0.25.10",
+ "@esbuild/android-arm64": "0.25.10",
+ "@esbuild/android-x64": "0.25.10",
+ "@esbuild/darwin-arm64": "0.25.10",
+ "@esbuild/darwin-x64": "0.25.10",
+ "@esbuild/freebsd-arm64": "0.25.10",
+ "@esbuild/freebsd-x64": "0.25.10",
+ "@esbuild/linux-arm": "0.25.10",
+ "@esbuild/linux-arm64": "0.25.10",
+ "@esbuild/linux-ia32": "0.25.10",
+ "@esbuild/linux-loong64": "0.25.10",
+ "@esbuild/linux-mips64el": "0.25.10",
+ "@esbuild/linux-ppc64": "0.25.10",
+ "@esbuild/linux-riscv64": "0.25.10",
+ "@esbuild/linux-s390x": "0.25.10",
+ "@esbuild/linux-x64": "0.25.10",
+ "@esbuild/netbsd-arm64": "0.25.10",
+ "@esbuild/netbsd-x64": "0.25.10",
+ "@esbuild/openbsd-arm64": "0.25.10",
+ "@esbuild/openbsd-x64": "0.25.10",
+ "@esbuild/openharmony-arm64": "0.25.10",
+ "@esbuild/sunos-x64": "0.25.10",
+ "@esbuild/win32-arm64": "0.25.10",
+ "@esbuild/win32-ia32": "0.25.10",
+ "@esbuild/win32-x64": "0.25.10"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.36.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz",
+ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.36.0",
+ "@eslint/plugin-kit": "^0.3.5",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-compat-utils": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz",
+ "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/eslint-config-flat-gitignore": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-2.1.0.tgz",
+ "integrity": "sha512-cJzNJ7L+psWp5mXM7jBX+fjHtBvvh06RBlcweMhKD8jWqQw0G78hOW5tpVALGHGFPsBV+ot2H+pdDGJy6CV8pA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint/compat": "^1.2.5"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "eslint": "^9.5.0"
+ }
+ },
+ "node_modules/eslint-config-vuetify": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-vuetify/-/eslint-config-vuetify-4.2.0.tgz",
+ "integrity": "sha512-+Ffgv5IUiobXEbKq2fJpsYeb67XU3ttisyaOeav41P0MJec+JucUIBxvmt36rdI3RrKgWDMBwwuYpyFncUQJag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@clack/prompts": "^0.11.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "^9.35.0",
+ "@stylistic/eslint-plugin": "^5.3.1",
+ "@typescript-eslint/parser": "^8.43.0",
+ "eslint-config-flat-gitignore": "^2.1.0",
+ "eslint-flat-config-utils": "^2.1.1",
+ "eslint-plugin-antfu": "^3.1.1",
+ "eslint-plugin-import-lite": "^0.3.0",
+ "eslint-plugin-jsonc": "^2.20.1",
+ "eslint-plugin-perfectionist": "^4.15.0",
+ "eslint-plugin-pnpm": "^1.1.1",
+ "eslint-plugin-regexp": "^2.10.0",
+ "eslint-plugin-unicorn": "^61.0.2",
+ "eslint-plugin-vue": "^10.4.0",
+ "eslint-typegen": "^2.3.0",
+ "exsolve": "^1.0.7",
+ "globals": "^16.4.0",
+ "jsonc-eslint-parser": "^2.4.0",
+ "kolorist": "^1.8.0",
+ "local-pkg": "^1.1.2",
+ "nypm": "^0.6.1",
+ "package-manager-detector": "^1.3.0",
+ "tinyexec": "^1.0.1",
+ "typescript-eslint": "^8.43.0",
+ "vue-eslint-parser": "^10.2.0",
+ "yaml-eslint-parser": "^1.3.0"
+ },
+ "bin": {
+ "eslint-config-vuetify": "bin/cli.mjs"
+ },
+ "peerDependencies": {
+ "@vitest/eslint-plugin": "^1.1.42",
+ "eslint": "^9.5.0",
+ "eslint-plugin-jest": "^29.0.1",
+ "eslint-plugin-no-only-tests": "^3.3.0",
+ "eslint-plugin-vuejs-accessibility": "^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@vitest/eslint-plugin": {
+ "optional": true
+ },
+ "eslint-plugin-jest": {
+ "optional": true
+ },
+ "eslint-plugin-no-only-tests": {
+ "optional": true
+ },
+ "eslint-plugin-vuejs-accessibility": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-vuetify/node_modules/globals": {
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
+ "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-flat-config-utils": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-2.1.4.tgz",
+ "integrity": "sha512-bEnmU5gqzS+4O+id9vrbP43vByjF+8KOs+QuuV4OlqAuXmnRW2zfI/Rza1fQvdihQ5h4DUo0NqFAiViD4mSrzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/eslint-json-compat-utils": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz",
+ "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esquery": "^1.6.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "jsonc-eslint-parser": "^2.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@eslint/json": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-antfu": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-3.1.1.tgz",
+ "integrity": "sha512-7Q+NhwLfHJFvopI2HBZbSxWXngTwBLKxW1AGXLr2lEGxcEIK/AsDs8pn8fvIizl5aZjBbVbVK5ujmMpBe4Tvdg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "eslint": "*"
+ }
+ },
+ "node_modules/eslint-plugin-import-lite": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import-lite/-/eslint-plugin-import-lite-0.3.0.tgz",
+ "integrity": "sha512-dkNBAL6jcoCsXZsQ/Tt2yXmMDoNt5NaBh/U7yvccjiK8cai6Ay+MK77bMykmqQA2bTF6lngaLCDij6MTO3KkvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/types": "^8.34.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=9.0.0",
+ "typescript": ">=4.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-jsonc": {
+ "version": "2.20.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.20.1.tgz",
+ "integrity": "sha512-gUzIwQHXx7ZPypUoadcyRi4WbHW2TPixDr0kqQ4miuJBU0emJmyGTlnaT3Og9X2a8R1CDayN9BFSq5weGWbTng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.5.1",
+ "eslint-compat-utils": "^0.6.4",
+ "eslint-json-compat-utils": "^0.2.1",
+ "espree": "^9.6.1 || ^10.3.0",
+ "graphemer": "^1.4.0",
+ "jsonc-eslint-parser": "^2.4.0",
+ "natural-compare": "^1.4.0",
+ "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ota-meshi"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-perfectionist": {
+ "version": "4.15.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-4.15.0.tgz",
+ "integrity": "sha512-pC7PgoXyDnEXe14xvRUhBII8A3zRgggKqJFx2a82fjrItDs1BSI7zdZnQtM2yQvcyod6/ujmzb7ejKPx8lZTnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "^8.34.1",
+ "@typescript-eslint/utils": "^8.34.1",
+ "natural-orderby": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=8.45.0"
+ }
+ },
+ "node_modules/eslint-plugin-pnpm": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-pnpm/-/eslint-plugin-pnpm-1.2.0.tgz",
+ "integrity": "sha512-HKIFEmRGVxXvPx/hCpZY0qUGCYoaSYO6EVut4Hf9bckC0qP6F23mBgdoIExRZIWoViHuMznSaDU1FpQmc2xpgw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "empathic": "^2.0.0",
+ "jsonc-eslint-parser": "^2.4.1",
+ "pathe": "^2.0.3",
+ "pnpm-workspace-yaml": "1.2.0",
+ "tinyglobby": "^0.2.15",
+ "yaml-eslint-parser": "^1.3.0"
+ },
+ "peerDependencies": {
+ "eslint": "^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-regexp": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.10.0.tgz",
+ "integrity": "sha512-ovzQT8ESVn5oOe5a7gIDPD5v9bCSjIFJu57sVPDqgPRXicQzOnYfFN21WoQBQF18vrhT5o7UMKFwJQVVjyJ0ng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.11.0",
+ "comment-parser": "^1.4.0",
+ "jsdoc-type-pratt-parser": "^4.0.0",
+ "refa": "^0.12.1",
+ "regexp-ast-analysis": "^0.7.1",
+ "scslre": "^0.3.0"
+ },
+ "engines": {
+ "node": "^18 || >=20"
+ },
+ "peerDependencies": {
+ "eslint": ">=8.44.0"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn": {
+ "version": "61.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-61.0.2.tgz",
+ "integrity": "sha512-zLihukvneYT7f74GNbVJXfWIiNQmkc/a9vYBTE4qPkQZswolWNdu+Wsp9sIXno1JOzdn6OUwLPd19ekXVkahRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@eslint/plugin-kit": "^0.3.3",
+ "change-case": "^5.4.4",
+ "ci-info": "^4.3.0",
+ "clean-regexp": "^1.0.0",
+ "core-js-compat": "^3.44.0",
+ "esquery": "^1.6.0",
+ "find-up-simple": "^1.0.1",
+ "globals": "^16.3.0",
+ "indent-string": "^5.0.0",
+ "is-builtin-module": "^5.0.0",
+ "jsesc": "^3.1.0",
+ "pluralize": "^8.0.0",
+ "regexp-tree": "^0.1.27",
+ "regjsparser": "^0.12.0",
+ "semver": "^7.7.2",
+ "strip-indent": "^4.0.0"
+ },
+ "engines": {
+ "node": "^20.10.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
+ },
+ "peerDependencies": {
+ "eslint": ">=9.29.0"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn/node_modules/globals": {
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
+ "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-plugin-vue": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.5.0.tgz",
+ "integrity": "sha512-7BZHsG3kC2vei8F2W8hnfDi9RK+cv5eKPMvzBdrl8Vuc0hR5odGQRli8VVzUkrmUHkxFEm4Iio1r5HOKslO0Aw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "natural-compare": "^1.4.0",
+ "nth-check": "^2.1.1",
+ "postcss-selector-parser": "^6.0.15",
+ "semver": "^7.6.3",
+ "xml-name-validator": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "peerDependencies": {
+ "@stylistic/eslint-plugin": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0",
+ "@typescript-eslint/parser": "^7.0.0 || ^8.0.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "vue-eslint-parser": "^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@stylistic/eslint-plugin": {
+ "optional": true
+ },
+ "@typescript-eslint/parser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-typegen": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-typegen/-/eslint-typegen-2.3.0.tgz",
+ "integrity": "sha512-azYgAvhlz1AyTpeLfVSKcrNJInuIsRrcUrOcHmEl8T9oMKesePVUPrF8gRgE6azV8CAlFzxJDTyaXAAbA/BYiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-schema-to-typescript-lite": "^15.0.0",
+ "ohash": "^2.0.11"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "eslint": "^9.0.0"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "license": "MIT"
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/exsolve": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz",
+ "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-up-simple": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz",
+ "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "license": "MIT"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz",
+ "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inter-ui": {
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/inter-ui/-/inter-ui-3.19.3.tgz",
+ "integrity": "sha512-5FG9fjuYOXocIfjzcCBhICL5cpvwEetseL3FU6tP3d6Bn7g8wODhB+I9RNGRTizCT7CUG4GOK54OPxqq3msQgg==",
+ "license": "OFL-1.1"
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-builtin-module": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz",
+ "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "builtin-modules": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "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==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-what": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
+ "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdoc-type-pratt-parser": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.8.0.tgz",
+ "integrity": "sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-to-typescript-lite": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-to-typescript-lite/-/json-schema-to-typescript-lite-15.0.0.tgz",
+ "integrity": "sha512-5mMORSQm9oTLyjM4mWnyNBi2T042Fhg1/0gCIB6X8U/LVpM2A+Nmj2yEyArqVouDmFThDxpEXcnTgSrjkGJRFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@apidevtools/json-schema-ref-parser": "^14.1.1",
+ "@types/json-schema": "^7.0.15"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsonc-eslint-parser": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.1.tgz",
+ "integrity": "sha512-uuPNLJkKN8NXAlZlQ6kmUF9qO+T6Kyd7oV4+/7yy8Jz6+MZNyhPq8EdLpdfnPVzUC8qSf1b4j1azKaGnFsjmsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.5.0",
+ "eslint-visitor-keys": "^3.0.0",
+ "espree": "^9.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ota-meshi"
+ }
+ },
+ "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/jsonc-eslint-parser/node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/kolorist": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
+ "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/local-pkg": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
+ "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mlly": "^1.7.4",
+ "pkg-types": "^2.3.0",
+ "quansync": "^0.2.11"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.19",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz",
+ "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/magic-string-ast": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/magic-string-ast/-/magic-string-ast-1.0.2.tgz",
+ "integrity": "sha512-8ngQgLhcT0t3YBdn9CGkZqCYlvwW9pm7aWJwd7AxseVWf1RU8ZHCQvG1mt3N5vvUme+pXTcHB8G/7fE666U8Vw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "magic-string": "^0.30.17"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "devOptional": true,
+ "license": "MIT",
+ "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==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
+ "license": "MIT"
+ },
+ "node_modules/mlly": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
+ "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "pathe": "^2.0.3",
+ "pkg-types": "^1.3.1",
+ "ufo": "^1.6.1"
+ }
+ },
+ "node_modules/mlly/node_modules/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mlly/node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "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/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/natural-orderby": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-5.0.0.tgz",
+ "integrity": "sha512-kKHJhxwpR/Okycz4HhQKKlhWe4ASEfPgkSWNmKFHd7+ezuQlxkA5cM3+XkBPvm1gmHen3w53qsYAv+8GwRrBlg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.21",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz",
+ "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/nypm": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz",
+ "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "citty": "^0.1.6",
+ "consola": "^3.4.2",
+ "pathe": "^2.0.3",
+ "pkg-types": "^2.3.0",
+ "tinyexec": "^1.0.1"
+ },
+ "bin": {
+ "nypm": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": "^14.16.0 || >=16.10.0"
+ }
+ },
+ "node_modules/ohash": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz",
+ "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-manager-detector": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz",
+ "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/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-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pinia": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz",
+ "integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-api": "^7.7.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.4.4",
+ "vue": "^2.7.0 || ^3.5.11"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pkg-types": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
+ "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.2.2",
+ "exsolve": "^1.0.7",
+ "pathe": "^2.0.3"
+ }
+ },
+ "node_modules/pluralize": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
+ "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pnpm-workspace-yaml": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pnpm-workspace-yaml/-/pnpm-workspace-yaml-1.2.0.tgz",
+ "integrity": "sha512-4CnZHmLSaprRnIm2iQ27Zl1cWPRHdX7Ehw7ckRwujoPKCk2QAz4agsA2MbTodg4sgbqYfJ68ULT+Q5A8dU+Mow==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "yaml": "^2.8.1"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/quansync": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
+ "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/refa": {
+ "version": "0.12.1",
+ "resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz",
+ "integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.8.0"
+ },
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/regexp-ast-analysis": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz",
+ "integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.8.0",
+ "refa": "^0.12.1"
+ },
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/regexp-tree": {
+ "version": "0.1.27",
+ "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
+ "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "regexp-tree": "bin/regexp-tree"
+ }
+ },
+ "node_modules/regjsparser": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "jsesc": "~3.0.2"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "license": "MIT"
+ },
+ "node_modules/rollup": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz",
+ "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==",
+ "devOptional": 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.52.4",
+ "@rollup/rollup-android-arm64": "4.52.4",
+ "@rollup/rollup-darwin-arm64": "4.52.4",
+ "@rollup/rollup-darwin-x64": "4.52.4",
+ "@rollup/rollup-freebsd-arm64": "4.52.4",
+ "@rollup/rollup-freebsd-x64": "4.52.4",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.52.4",
+ "@rollup/rollup-linux-arm-musleabihf": "4.52.4",
+ "@rollup/rollup-linux-arm64-gnu": "4.52.4",
+ "@rollup/rollup-linux-arm64-musl": "4.52.4",
+ "@rollup/rollup-linux-loong64-gnu": "4.52.4",
+ "@rollup/rollup-linux-ppc64-gnu": "4.52.4",
+ "@rollup/rollup-linux-riscv64-gnu": "4.52.4",
+ "@rollup/rollup-linux-riscv64-musl": "4.52.4",
+ "@rollup/rollup-linux-s390x-gnu": "4.52.4",
+ "@rollup/rollup-linux-x64-gnu": "4.52.4",
+ "@rollup/rollup-linux-x64-musl": "4.52.4",
+ "@rollup/rollup-openharmony-arm64": "4.52.4",
+ "@rollup/rollup-win32-arm64-msvc": "4.52.4",
+ "@rollup/rollup-win32-ia32-msvc": "4.52.4",
+ "@rollup/rollup-win32-x64-gnu": "4.52.4",
+ "@rollup/rollup-win32-x64-msvc": "4.52.4",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/sass": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.93.2.tgz",
+ "integrity": "sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "chokidar": "^4.0.0",
+ "immutable": "^5.0.2",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher": "^2.4.1"
+ }
+ },
+ "node_modules/sass-embedded": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.93.2.tgz",
+ "integrity": "sha512-FvQdkn2dZ8DGiLgi0Uf4zsj7r/BsiLImNa5QJ10eZalY6NfZyjrmWGFcuCN5jNwlDlXFJnftauv+UtvBKLvepQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "@bufbuild/protobuf": "^2.5.0",
+ "buffer-builder": "^0.2.0",
+ "colorjs.io": "^0.5.0",
+ "immutable": "^5.0.2",
+ "rxjs": "^7.4.0",
+ "supports-color": "^8.1.1",
+ "sync-child-process": "^1.0.2",
+ "varint": "^6.0.0"
+ },
+ "bin": {
+ "sass": "dist/bin/sass.js"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "optionalDependencies": {
+ "sass-embedded-all-unknown": "1.93.2",
+ "sass-embedded-android-arm": "1.93.2",
+ "sass-embedded-android-arm64": "1.93.2",
+ "sass-embedded-android-riscv64": "1.93.2",
+ "sass-embedded-android-x64": "1.93.2",
+ "sass-embedded-darwin-arm64": "1.93.2",
+ "sass-embedded-darwin-x64": "1.93.2",
+ "sass-embedded-linux-arm": "1.93.2",
+ "sass-embedded-linux-arm64": "1.93.2",
+ "sass-embedded-linux-musl-arm": "1.93.2",
+ "sass-embedded-linux-musl-arm64": "1.93.2",
+ "sass-embedded-linux-musl-riscv64": "1.93.2",
+ "sass-embedded-linux-musl-x64": "1.93.2",
+ "sass-embedded-linux-riscv64": "1.93.2",
+ "sass-embedded-linux-x64": "1.93.2",
+ "sass-embedded-unknown-all": "1.93.2",
+ "sass-embedded-win32-arm64": "1.93.2",
+ "sass-embedded-win32-x64": "1.93.2"
+ }
+ },
+ "node_modules/sass-embedded-all-unknown": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.93.2.tgz",
+ "integrity": "sha512-GdEuPXIzmhRS5J7UKAwEvtk8YyHQuFZRcpnEnkA3rwRUI27kwjyXkNeIj38XjUQ3DzrfMe8HcKFaqWGHvblS7Q==",
+ "cpu": [
+ "!arm",
+ "!arm64",
+ "!riscv64",
+ "!x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "sass": "1.93.2"
+ }
+ },
+ "node_modules/sass-embedded-android-arm": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.93.2.tgz",
+ "integrity": "sha512-I8bpO8meZNo5FvFx5FIiE7DGPVOYft0WjuwcCCdeJ6duwfkl6tZdatex1GrSigvTsuz9L0m4ngDcX/Tj/8yMow==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-android-arm64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.93.2.tgz",
+ "integrity": "sha512-346f4iVGAPGcNP6V6IOOFkN5qnArAoXNTPr5eA/rmNpeGwomdb7kJyQ717r9rbJXxOG8OAAUado6J0qLsjnjXQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-android-riscv64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.93.2.tgz",
+ "integrity": "sha512-hSMW1s4yJf5guT9mrdkumluqrwh7BjbZ4MbBW9tmi1DRDdlw1Wh9Oy1HnnmOG8x9XcI1qkojtPL6LUuEJmsiDg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-android-x64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.93.2.tgz",
+ "integrity": "sha512-JqktiHZduvn+ldGBosE40ALgQ//tGCVNAObgcQ6UIZznEJbsHegqStqhRo8UW3x2cgOO2XYJcrInH6cc7wdKbw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-darwin-arm64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.93.2.tgz",
+ "integrity": "sha512-qI1X16qKNeBJp+M/5BNW7v/JHCDYWr1/mdoJ7+UMHmP0b5AVudIZtimtK0hnjrLnBECURifd6IkulybR+h+4UA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-darwin-x64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.93.2.tgz",
+ "integrity": "sha512-4KeAvlkQ0m0enKUnDGQJZwpovYw99iiMb8CTZRSsQm8Eh7halbJZVmx67f4heFY/zISgVOCcxNg19GrM5NTwtA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-arm": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.93.2.tgz",
+ "integrity": "sha512-N3+D/ToHtzwLDO+lSH05Wo6/KRxFBPnbjVHASOlHzqJnK+g5cqex7IFAp6ozzlRStySk61Rp6d+YGrqZ6/P0PA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-arm64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.93.2.tgz",
+ "integrity": "sha512-9ftX6nd5CsShJqJ2WRg+ptaYvUW+spqZfJ88FbcKQBNFQm6L87luj3UI1rB6cP5EWrLwHA754OKxRJyzWiaN6g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-musl-arm": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.93.2.tgz",
+ "integrity": "sha512-XBTvx66yRenvEsp3VaJCb3HQSyqCsUh7R+pbxcN5TuzueybZi0LXvn9zneksdXcmjACMlMpIVXi6LyHPQkYc8A==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-musl-arm64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.93.2.tgz",
+ "integrity": "sha512-+3EHuDPkMiAX5kytsjEC1bKZCawB9J6pm2eBIzzLMPWbf5xdx++vO1DpT7hD4bm4ZGn0eVHgSOKIfP6CVz6tVg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-musl-riscv64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.93.2.tgz",
+ "integrity": "sha512-0sB5kmVZDKTYzmCSlTUnjh6mzOhzmQiW/NNI5g8JS4JiHw2sDNTvt1dsFTuqFkUHyEOY3ESTsfHHBQV8Ip4bEA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-musl-x64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.93.2.tgz",
+ "integrity": "sha512-t3ejQ+1LEVuHy7JHBI2tWHhoMfhedUNDjGJR2FKaLgrtJntGnyD1RyX0xb3nuqL/UXiEAtmTmZY+Uh3SLUe1Hg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-riscv64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.93.2.tgz",
+ "integrity": "sha512-e7AndEwAbFtXaLy6on4BfNGTr3wtGZQmypUgYpSNVcYDO+CWxatKVY4cxbehMPhxG9g5ru+eaMfynvhZt7fLaA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-x64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.93.2.tgz",
+ "integrity": "sha512-U3EIUZQL11DU0xDDHXexd4PYPHQaSQa2hzc4EzmhHqrAj+TyfYO94htjWOd+DdTPtSwmLp+9cTWwPZBODzC96w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-unknown-all": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.93.2.tgz",
+ "integrity": "sha512-7VnaOmyewcXohiuoFagJ3SK5ddP9yXpU0rzz+pZQmS1/+5O6vzyFCUoEt3HDRaLctH4GT3nUGoK1jg0ae62IfQ==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "!android",
+ "!darwin",
+ "!linux",
+ "!win32"
+ ],
+ "dependencies": {
+ "sass": "1.93.2"
+ }
+ },
+ "node_modules/sass-embedded-win32-arm64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.93.2.tgz",
+ "integrity": "sha512-Y90DZDbQvtv4Bt0GTXKlcT9pn4pz8AObEjFF8eyul+/boXwyptPZ/A1EyziAeNaIEIfxyy87z78PUgCeGHsx3Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-win32-x64": {
+ "version": "1.93.2",
+ "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.93.2.tgz",
+ "integrity": "sha512-BbSucRP6PVRZGIwlEBkp+6VQl2GWdkWFMN+9EuOTPrLxCJZoq+yhzmbjspd3PeM8+7WJ7AdFu/uRYdO8tor1iQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/scslre": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz",
+ "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.8.0",
+ "refa": "^0.12.0",
+ "regexp-ast-analysis": "^0.7.0"
+ },
+ "engines": {
+ "node": "^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/scule": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz",
+ "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-indent": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.0.tgz",
+ "integrity": "sha512-OA95x+JPmL7kc7zCu+e+TeYxEiaIyndRx0OrBcK2QPPH09oAndr2ALvymxWA+Lx1PYYvFUm4O63pRkdJAaW96w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-literal": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz",
+ "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^9.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/superjson": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
+ "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
+ "license": "MIT",
+ "dependencies": {
+ "copy-anything": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sync-child-process": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/sync-child-process/-/sync-child-process-1.0.2.tgz",
+ "integrity": "sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "sync-message-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/sync-message-port": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/sync-message-port/-/sync-message-port-1.1.3.tgz",
+ "integrity": "sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/synckit": {
+ "version": "0.11.11",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
+ "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.2.9"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
+ "node_modules/tinyexec": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz",
+ "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/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==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "devOptional": true,
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.45.0.tgz",
+ "integrity": "sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.45.0",
+ "@typescript-eslint/parser": "8.45.0",
+ "@typescript-eslint/typescript-estree": "8.45.0",
+ "@typescript-eslint/utils": "8.45.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/ufo": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
+ "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unimport": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/unimport/-/unimport-4.2.0.tgz",
+ "integrity": "sha512-mYVtA0nmzrysnYnyb3ALMbByJ+Maosee2+WyE0puXl+Xm2bUwPorPaaeZt0ETfuroPOtG8jj1g/qeFZ6buFnag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.14.1",
+ "escape-string-regexp": "^5.0.0",
+ "estree-walker": "^3.0.3",
+ "local-pkg": "^1.1.1",
+ "magic-string": "^0.30.17",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.2",
+ "pkg-types": "^2.1.0",
+ "scule": "^1.3.0",
+ "strip-literal": "^3.0.0",
+ "tinyglobby": "^0.2.12",
+ "unplugin": "^2.2.2",
+ "unplugin-utils": "^0.2.4"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
+ "node_modules/unimport/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/unimport/node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/unplugin": {
+ "version": "2.3.10",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.10.tgz",
+ "integrity": "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.5",
+ "acorn": "^8.15.0",
+ "picomatch": "^4.0.3",
+ "webpack-virtual-modules": "^0.6.2"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
+ "node_modules/unplugin-auto-import": {
+ "version": "19.3.0",
+ "resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-19.3.0.tgz",
+ "integrity": "sha512-iIi0u4Gq2uGkAOGqlPJOAMI8vocvjh1clGTfSK4SOrJKrt+tirrixo/FjgBwXQNNdS7ofcr7OxzmOb/RjWxeEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "local-pkg": "^1.1.1",
+ "magic-string": "^0.30.17",
+ "picomatch": "^4.0.2",
+ "unimport": "^4.2.0",
+ "unplugin": "^2.3.4",
+ "unplugin-utils": "^0.2.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@nuxt/kit": "^3.2.2",
+ "@vueuse/core": "*"
+ },
+ "peerDependenciesMeta": {
+ "@nuxt/kit": {
+ "optional": true
+ },
+ "@vueuse/core": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/unplugin-fonts": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/unplugin-fonts/-/unplugin-fonts-1.4.0.tgz",
+ "integrity": "sha512-TIJqr5rSlK/+3oL5nnrrEJ+Ty2taQ/bTJY1C5abYnksl553Q3HoHVqS4pnRLDkwpZq8AYqywib3kEVvHH+CtRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-glob": "^3.3.3",
+ "unplugin": "2.3.5"
+ },
+ "peerDependencies": {
+ "@nuxt/kit": "^3.0.0 || ^4.0.0",
+ "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@nuxt/kit": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/unplugin-fonts/node_modules/unplugin": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.5.tgz",
+ "integrity": "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.14.1",
+ "picomatch": "^4.0.2",
+ "webpack-virtual-modules": "^0.6.2"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
+ "node_modules/unplugin-utils": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.5.tgz",
+ "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/unplugin-vue-components": {
+ "version": "29.1.0",
+ "resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-29.1.0.tgz",
+ "integrity": "sha512-z/9ACPXth199s9aCTCdKZAhe5QGOpvzJYP+Hkd0GN1/PpAmsu+W3UlRY3BJAewPqQxh5xi56+Og6mfiCV1Jzpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.6.0",
+ "debug": "^4.4.3",
+ "local-pkg": "^1.1.2",
+ "magic-string": "^0.30.19",
+ "mlly": "^1.8.0",
+ "tinyglobby": "^0.2.15",
+ "unplugin": "^2.3.10",
+ "unplugin-utils": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@babel/parser": "^7.15.8",
+ "@nuxt/kit": "^3.2.2 || ^4.0.0",
+ "vue": "2 || 3"
+ },
+ "peerDependenciesMeta": {
+ "@babel/parser": {
+ "optional": true
+ },
+ "@nuxt/kit": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/readdirp/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/unplugin-utils": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.0.tgz",
+ "integrity": "sha512-JLoggz+PvLVMJo+jZt97hdIIIZ2yTzGgft9e9q8iMrC4ewufl62ekeW7mixBghonn2gVb/ICjyvlmOCUBnJLQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/unplugin-vue-router": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/unplugin-vue-router/-/unplugin-vue-router-0.15.0.tgz",
+ "integrity": "sha512-PyGehCjd9Ny9h+Uer4McbBjjib3lHihcyUEILa7pHKl6+rh8N7sFyw4ZkV+N30Oq2zmIUG7iKs3qpL0r+gXAaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue-macros/common": "3.0.0-beta.16",
+ "@vue/language-core": "^3.0.1",
+ "ast-walker-scope": "^0.8.1",
+ "chokidar": "^4.0.3",
+ "json5": "^2.2.3",
+ "local-pkg": "^1.1.1",
+ "magic-string": "^0.30.17",
+ "mlly": "^1.7.4",
+ "muggle-string": "^0.4.1",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3",
+ "scule": "^1.3.0",
+ "tinyglobby": "^0.2.14",
+ "unplugin": "^2.3.5",
+ "unplugin-utils": "^0.2.4",
+ "yaml": "^2.8.0"
+ },
+ "peerDependencies": {
+ "@vue/compiler-sfc": "^3.5.17",
+ "vue-router": "^4.5.1"
+ },
+ "peerDependenciesMeta": {
+ "vue-router": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/upath": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz",
+ "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4",
+ "yarn": "*"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/varint": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
+ "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/vite": {
+ "version": "7.1.9",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.9.tgz",
+ "integrity": "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-vue-layouts-next": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-vue-layouts-next/-/vite-plugin-vue-layouts-next-1.0.0.tgz",
+ "integrity": "sha512-y3oNYcJs5lrv4F/E0EXU7OXi88CH1/b/DOk9nsFAeglxmk4Ps635DTy9R29Nl9Vj7LteBRKaxOkKVSHKOMqo7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.1",
+ "fast-glob": "^3.3.3"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
+ "vue": "^3.2.4",
+ "vue-router": "^4.0.11"
+ }
+ },
+ "node_modules/vite-plugin-vuetify": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-vuetify/-/vite-plugin-vuetify-2.1.2.tgz",
+ "integrity": "sha512-I/wd6QS+DO6lHmuGoi1UTyvvBTQ2KDzQZ9oowJQEJ6OcjWfJnscYXx2ptm6S7fJSASuZT8jGRBL3LV4oS3LpaA==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vuetify/loader-shared": "^2.1.1",
+ "debug": "^4.3.3",
+ "upath": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": ">=5",
+ "vue": "^3.0.0",
+ "vuetify": "^3.0.0"
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz",
+ "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.22",
+ "@vue/compiler-sfc": "3.5.22",
+ "@vue/runtime-dom": "3.5.22",
+ "@vue/server-renderer": "3.5.22",
+ "@vue/shared": "3.5.22"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-eslint-parser": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz",
+ "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "eslint-scope": "^8.2.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.6.0",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0"
+ }
+ },
+ "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-router/node_modules/@vue/devtools-api": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
+ "license": "MIT"
+ },
+ "node_modules/vuetify": {
+ "version": "3.10.4",
+ "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.10.4.tgz",
+ "integrity": "sha512-aatUQ0RM0i6VdkJaFyj3gydecuFmAgACNO3RwWznvjvIvRENQXxMRiv+vlGFoshbw2UG+zOPPMhO12OCPSa2UQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/johnleider"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.7",
+ "vite-plugin-vuetify": ">=2.1.0",
+ "vue": "^3.5.0",
+ "webpack-plugin-vuetify": ">=3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ },
+ "vite-plugin-vuetify": {
+ "optional": true
+ },
+ "webpack-plugin-vuetify": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-virtual-modules": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+ "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
+ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
+ "devOptional": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ }
+ },
+ "node_modules/yaml-eslint-parser": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.3.0.tgz",
+ "integrity": "sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.0.0",
+ "yaml": "^2.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ota-meshi"
+ }
+ },
+ "node_modules/yaml-eslint-parser/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/frontend-prototype/package.json b/frontend-prototype/package.json
new file mode 100644
index 0000000000..c688783291
--- /dev/null
+++ b/frontend-prototype/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "frontend-prototype",
+ "private": true,
+ "type": "module",
+ "version": "0.0.0",
+ "scripts": {
+ "dev": "vite --host 0.0.0.0",
+ "build": "vite build",
+ "preview": "vite preview --host 0.0.0.0 --port 3333",
+ "lint": "eslint . --fix"
+ },
+ "dependencies": {
+ "@fontsource/roboto": "5.2.7",
+ "@mdi/font": "7.4.47",
+ "inter-ui": "3.19.3",
+ "pinia": "^3.0.3",
+ "vue": "^3.5.21",
+ "vue-router": "^4.5.1",
+ "vuetify": "^3.10.1"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^6.0.1",
+ "eslint": "^9.35.0",
+ "eslint-config-vuetify": "^4.2.0",
+ "sass-embedded": "^1.92.1",
+ "unplugin-auto-import": "^19.3.0",
+ "unplugin-fonts": "^1.4.0",
+ "unplugin-vue-components": "^29.0.0",
+ "unplugin-vue-router": "^0.15.0",
+ "vite": "^7.1.5",
+ "vite-plugin-vue-layouts-next": "^1.0.0",
+ "vite-plugin-vuetify": "^2.1.2"
+ }
+}
diff --git a/frontend-prototype/public/favicon.ico b/frontend-prototype/public/favicon.ico
new file mode 100644
index 0000000000..8fb9f91b3a
Binary files /dev/null and b/frontend-prototype/public/favicon.ico differ
diff --git a/frontend-prototype/src/App.vue b/frontend-prototype/src/App.vue
new file mode 100644
index 0000000000..64618cdf22
--- /dev/null
+++ b/frontend-prototype/src/App.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/frontend-prototype/src/assets/logo.png b/frontend-prototype/src/assets/logo.png
new file mode 100644
index 0000000000..a5f23ae7bf
Binary files /dev/null and b/frontend-prototype/src/assets/logo.png differ
diff --git a/frontend-prototype/src/assets/logo.svg b/frontend-prototype/src/assets/logo.svg
new file mode 100644
index 0000000000..d57771c6df
--- /dev/null
+++ b/frontend-prototype/src/assets/logo.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/frontend-prototype/src/components/AppBarItem.vue b/frontend-prototype/src/components/AppBarItem.vue
new file mode 100644
index 0000000000..86bdf2fe21
--- /dev/null
+++ b/frontend-prototype/src/components/AppBarItem.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+ {{ text }}
+
+
+
+
diff --git a/frontend-prototype/src/components/AppFooter.vue b/frontend-prototype/src/components/AppFooter.vue
new file mode 100644
index 0000000000..7444827109
--- /dev/null
+++ b/frontend-prototype/src/components/AppFooter.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+ © 2016-{{ (new Date()).getFullYear() }}
Vuetify, LLC
+ —
+
+ MIT License
+
+
+
+
+
+
+
+
diff --git a/frontend-prototype/src/components/HelloWorld.vue b/frontend-prototype/src/components/HelloWorld.vue
new file mode 100644
index 0000000000..730485c042
--- /dev/null
+++ b/frontend-prototype/src/components/HelloWorld.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Get started
+
+
+
+
+
+ Change this page by updating {{ ` ` }} in components/HelloWorld.vue .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-prototype/src/components/Logo.vue b/frontend-prototype/src/components/Logo.vue
new file mode 100644
index 0000000000..80245ef86b
--- /dev/null
+++ b/frontend-prototype/src/components/Logo.vue
@@ -0,0 +1,31 @@
+
+
+
+
+ $vuetify.icons.ecamp eCamp
+
+
+
+
+
+
+
+
+
diff --git a/frontend-prototype/src/components/README.md b/frontend-prototype/src/components/README.md
new file mode 100644
index 0000000000..d1dc92f5e1
--- /dev/null
+++ b/frontend-prototype/src/components/README.md
@@ -0,0 +1,35 @@
+# Components
+
+Vue template files in this folder are automatically imported.
+
+## 🚀 Usage
+
+Importing is handled by [unplugin-vue-components](https://github.com/unplugin/unplugin-vue-components). This plugin automatically imports `.vue` files created in the `src/components` directory, and registers them as global components. This means that you can use any component in your application without having to manually import it.
+
+The following example assumes a component located at `src/components/MyComponent.vue`:
+
+```vue
+
+
+
+
+
+
+
+```
+
+When your template is rendered, the component's import will automatically be inlined, which renders to this:
+
+```vue
+
+
+
+
+
+
+
+```
diff --git a/frontend-prototype/src/components/UserMeta.vue b/frontend-prototype/src/components/UserMeta.vue
new file mode 100644
index 0000000000..e32e5117be
--- /dev/null
+++ b/frontend-prototype/src/components/UserMeta.vue
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ authUser.displayName }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ authUser.displayName }}
+
+
+
+
+
+ mdi-account
+ {{ $tc('components.navigation.userMeta.profile') }}
+
+
+ mdi-format-list-bulleted-triangle
+ {{ $tc('components.navigation.userMeta.myCamps') }}
+
+
+ mdi-email
+ {{ $tc('components.navigation.userMeta.invitations') }}
+
+
+
+
+
+ mdi-coffee
+ {{ $tc('components.navigation.userMeta.admin') }}
+
+
+ mdi-help-circle
+ {{ $tc('global.navigation.help') }}
+
+ mdi-open-in-new
+
+
+ mdi-script-text-outline
+ {{ $tc('global.navigation.news') }}
+
+ mdi-open-in-new
+
+
+
+
+ mdi-logout
+
+ {{ $tc('components.navigation.userMeta.logOut') }}
+
+
+
+
+
+
+
+
diff --git a/frontend-prototype/src/layouts/README.md b/frontend-prototype/src/layouts/README.md
new file mode 100644
index 0000000000..78f68b6028
--- /dev/null
+++ b/frontend-prototype/src/layouts/README.md
@@ -0,0 +1,5 @@
+# Layouts
+
+Layouts are reusable components that wrap around pages. They are used to provide a consistent look and feel across multiple pages.
+
+Full documentation for this feature can be found in the Official [vite-plugin-vue-layouts-next](https://github.com/loicduong/vite-plugin-vue-layouts-next) repository.
diff --git a/frontend-prototype/src/layouts/default.vue b/frontend-prototype/src/layouts/default.vue
new file mode 100644
index 0000000000..3037ff7fe0
--- /dev/null
+++ b/frontend-prototype/src/layouts/default.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-prototype/src/main.js b/frontend-prototype/src/main.js
new file mode 100644
index 0000000000..98cac25f29
--- /dev/null
+++ b/frontend-prototype/src/main.js
@@ -0,0 +1,23 @@
+/**
+ * main.js
+ *
+ * Bootstraps Vuetify and other plugins then mounts the App`
+ */
+
+// Plugins
+import { registerPlugins } from '@/plugins'
+
+// Components
+import App from './App.vue'
+
+// Composables
+import { createApp } from 'vue'
+
+// Styles
+import '@/styles/global.scss'
+
+const app = createApp(App)
+
+registerPlugins(app)
+
+app.mount('#app')
diff --git a/frontend-prototype/src/pages/README.md b/frontend-prototype/src/pages/README.md
new file mode 100644
index 0000000000..341536c2ff
--- /dev/null
+++ b/frontend-prototype/src/pages/README.md
@@ -0,0 +1,5 @@
+# Pages
+
+Vue components created in this folder will automatically be converted to navigatable routes.
+
+Full documentation for this feature can be found in the Official [unplugin-vue-router](https://github.com/posva/unplugin-vue-router) repository.
diff --git a/frontend-prototype/src/pages/index.vue b/frontend-prototype/src/pages/index.vue
new file mode 100644
index 0000000000..993f2e0d37
--- /dev/null
+++ b/frontend-prototype/src/pages/index.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Help
+ mdi-open-in-new
+
+
+
+
+
+
+
+
diff --git a/frontend-prototype/src/plugins/README.md b/frontend-prototype/src/plugins/README.md
new file mode 100644
index 0000000000..62201c7cfc
--- /dev/null
+++ b/frontend-prototype/src/plugins/README.md
@@ -0,0 +1,3 @@
+# Plugins
+
+Plugins are a way to extend the functionality of your Vue application. Use this folder for registering plugins that you want to use globally.
diff --git a/frontend-prototype/src/plugins/index.js b/frontend-prototype/src/plugins/index.js
new file mode 100644
index 0000000000..be6e2daa3d
--- /dev/null
+++ b/frontend-prototype/src/plugins/index.js
@@ -0,0 +1,17 @@
+/**
+ * plugins/index.js
+ *
+ * Automatically included in `./src/main.js`
+ */
+
+// Plugins
+import vuetify from './vuetify'
+import pinia from '@/stores'
+import router from '@/router'
+
+export function registerPlugins (app) {
+ app
+ .use(vuetify)
+ .use(router)
+ .use(pinia)
+}
diff --git a/frontend-prototype/src/plugins/vuetify.js b/frontend-prototype/src/plugins/vuetify.js
new file mode 100644
index 0000000000..30a4980832
--- /dev/null
+++ b/frontend-prototype/src/plugins/vuetify.js
@@ -0,0 +1,19 @@
+/**
+ * plugins/vuetify.js
+ *
+ * Framework documentation: https://vuetifyjs.com`
+ */
+
+// Styles
+import '@mdi/font/css/materialdesignicons.css'
+import 'vuetify/styles'
+
+// Composables
+import { createVuetify } from 'vuetify'
+
+// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
+export default createVuetify({
+ theme: {
+ defaultTheme: 'system',
+ },
+})
diff --git a/frontend-prototype/src/router/index.js b/frontend-prototype/src/router/index.js
new file mode 100644
index 0000000000..a6f6a863fe
--- /dev/null
+++ b/frontend-prototype/src/router/index.js
@@ -0,0 +1,37 @@
+/**
+ * router/index.ts
+ *
+ * Automatic routes for `./src/pages/*.vue`
+ */
+
+// Composables
+import { createRouter, createWebHistory } from 'vue-router'
+import { setupLayouts } from 'virtual:generated-layouts'
+import { routes } from 'vue-router/auto-routes'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: setupLayouts(routes),
+ base: '/prototype',
+})
+
+// Workaround for https://github.com/vitejs/vite/issues/11804
+router.onError((err, to) => {
+ if (err?.message?.includes?.('Failed to fetch dynamically imported module')) {
+ if (localStorage.getItem('vuetify:dynamic-reload')) {
+ console.error('Dynamic import error, reloading page did not fix it', err)
+ } else {
+ console.log('Reloading page to fix dynamic import error')
+ localStorage.setItem('vuetify:dynamic-reload', 'true')
+ location.assign(to.fullPath)
+ }
+ } else {
+ console.error(err)
+ }
+})
+
+router.isReady().then(() => {
+ localStorage.removeItem('vuetify:dynamic-reload')
+})
+
+export default router
diff --git a/frontend-prototype/src/stores/README.md b/frontend-prototype/src/stores/README.md
new file mode 100644
index 0000000000..54f8e03b69
--- /dev/null
+++ b/frontend-prototype/src/stores/README.md
@@ -0,0 +1,5 @@
+# Store
+
+Pinia stores are used to store reactive state and expose actions to mutate it.
+
+Full documentation for this feature can be found in the Official [Pinia](https://pinia.esm.dev/) repository.
diff --git a/frontend-prototype/src/stores/app.js b/frontend-prototype/src/stores/app.js
new file mode 100644
index 0000000000..74295436ec
--- /dev/null
+++ b/frontend-prototype/src/stores/app.js
@@ -0,0 +1,8 @@
+// Utilities
+import { defineStore } from 'pinia'
+
+export const useAppStore = defineStore('app', {
+ state: () => ({
+ //
+ }),
+})
diff --git a/frontend-prototype/src/stores/index.js b/frontend-prototype/src/stores/index.js
new file mode 100644
index 0000000000..153625250d
--- /dev/null
+++ b/frontend-prototype/src/stores/index.js
@@ -0,0 +1,4 @@
+// Utilities
+import { createPinia } from 'pinia'
+
+export default createPinia()
diff --git a/frontend-prototype/src/styles/README.md b/frontend-prototype/src/styles/README.md
new file mode 100644
index 0000000000..ea861794d6
--- /dev/null
+++ b/frontend-prototype/src/styles/README.md
@@ -0,0 +1,3 @@
+# Styles
+
+This directory is for configuring the styles of the application.
diff --git a/frontend-prototype/src/styles/global.scss b/frontend-prototype/src/styles/global.scss
new file mode 100644
index 0000000000..6e333f6a3a
--- /dev/null
+++ b/frontend-prototype/src/styles/global.scss
@@ -0,0 +1,11 @@
+@use 'inter-ui/default' as inter-ui with (
+ $inter-font-path: 'inter-ui/Inter (web hinted latin)'
+);
+@include inter-ui.weight-200;
+@include inter-ui.weight-400;
+@include inter-ui.weight-500;
+@include inter-ui.weight-600;
+
+body {
+ font-feature-settings: 'ss03', 'calt', 'rlig', 'kern', 'cv05', 'cv07', 'cv08';
+}
\ No newline at end of file
diff --git a/frontend-prototype/src/styles/settings.scss b/frontend-prototype/src/styles/settings.scss
new file mode 100644
index 0000000000..324e2252aa
--- /dev/null
+++ b/frontend-prototype/src/styles/settings.scss
@@ -0,0 +1,29 @@
+/**
+ * src/styles/settings.scss
+ *
+ * Configures SASS variables and Vuetify overwrites
+ */
+
+// https://vuetifyjs.com/features/sass-variables/`
+// @use 'vuetify/settings' with (
+// $color-pack: false
+// );
+
+@use 'vuetify/settings' with (
+ $heading-font-family: ('Inter', sans-serif, emoji),
+ $body-font-family: ('Inter', sans-serif, emoji),
+ $font-weights: (
+ 'light': 200,
+ 'regular': 400,
+ 'bold': 600,
+ ),
+
+ $button-text-letter-spacing: 0.25px,
+ $button-text-transform: none,
+ $bottom-navigation-min-width: 60px,
+ $list-item-icon-margin-end: 20px,
+ $menu-content-border-radius: 0 0 4px 4px,
+ $card-actions-padding: 16px,
+ $expansion-panel-title-padding: 16px,
+ $expansion-panel-text-padding: 0 16px 16px,
+);
\ No newline at end of file
diff --git a/frontend-prototype/typed-router.d.ts b/frontend-prototype/typed-router.d.ts
new file mode 100644
index 0000000000..7e0b732a46
--- /dev/null
+++ b/frontend-prototype/typed-router.d.ts
@@ -0,0 +1,51 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️
+// It's recommended to commit this file.
+// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
+
+declare module 'vue-router/auto-routes' {
+ import type {
+ RouteRecordInfo,
+ ParamValue,
+ ParamValueOneOrMore,
+ ParamValueZeroOrMore,
+ ParamValueZeroOrOne,
+ } from 'vue-router'
+
+ /**
+ * Route name map generated by unplugin-vue-router
+ */
+ export interface RouteNamedMap {
+ '/': RouteRecordInfo<'/', '/', Record, Record>,
+ }
+
+ /**
+ * Route file to route info map by unplugin-vue-router.
+ * Used by the volar plugin to automatically type useRoute()
+ *
+ * Each key is a file path relative to the project root with 2 properties:
+ * - routes: union of route names of the possible routes when in this page (passed to useRoute<...>())
+ * - views: names of nested views (can be passed to )
+ *
+ * @internal
+ */
+ export interface _RouteFileInfoMap {
+ 'src/pages/index.vue': {
+ routes: '/'
+ views: never
+ }
+ }
+
+ /**
+ * Get a union of possible route names in a certain route component file.
+ * Used by the volar plugin to automatically type useRoute()
+ *
+ * @internal
+ */
+ export type _RouteNamesForFilePath =
+ _RouteFileInfoMap extends Record
+ ? Info['routes']
+ : keyof RouteNamedMap
+}
diff --git a/frontend-prototype/vite.config.mjs b/frontend-prototype/vite.config.mjs
new file mode 100644
index 0000000000..cdc4d5cff4
--- /dev/null
+++ b/frontend-prototype/vite.config.mjs
@@ -0,0 +1,73 @@
+// Plugins
+import AutoImport from 'unplugin-auto-import/vite'
+import Components from 'unplugin-vue-components/vite'
+import Layouts from 'vite-plugin-vue-layouts-next'
+import Vue from '@vitejs/plugin-vue'
+import VueRouter from 'unplugin-vue-router/vite'
+import { VueRouterAutoImports } from 'unplugin-vue-router'
+import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
+
+// Utilities
+import { defineConfig } from 'vite'
+import { fileURLToPath, URL } from 'node:url'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ base: '/prototype',
+ plugins: [
+ VueRouter(),
+ Layouts(),
+ Vue({
+ template: { transformAssetUrls },
+ }),
+ // https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme
+ Vuetify({
+ autoImport: true,
+ styles: {
+ configFile: 'src/styles/settings.scss',
+ },
+ }),
+ Components(),
+ AutoImport({
+ imports: [
+ 'vue',
+ VueRouterAutoImports,
+ {
+ pinia: ['defineStore', 'storeToRefs'],
+ },
+ ],
+ eslintrc: {
+ enabled: true,
+ },
+ vueTemplate: true,
+ }),
+ ],
+ optimizeDeps: {
+ exclude: [
+ 'vuetify',
+ 'vue-router',
+ 'unplugin-vue-router/runtime',
+ 'unplugin-vue-router/data-loaders',
+ 'unplugin-vue-router/data-loaders/basic',
+ ],
+ },
+ define: { 'process.env': {} },
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('src', import.meta.url)),
+ },
+ extensions: [
+ '.js',
+ '.json',
+ '.jsx',
+ '.mjs',
+ '.ts',
+ '.tsx',
+ '.vue',
+ ],
+ },
+ server: {
+ port: 3333,
+ allowedHosts: ['frontend-prototype', 'localhost:3000'],
+ },
+})
diff --git a/frontend-vue3/.editorconfig b/frontend-vue3/.editorconfig
new file mode 100644
index 0000000000..7053c49a04
--- /dev/null
+++ b/frontend-vue3/.editorconfig
@@ -0,0 +1,5 @@
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/frontend-vue3/.gitignore b/frontend-vue3/.gitignore
new file mode 100644
index 0000000000..fae6461ae2
--- /dev/null
+++ b/frontend-vue3/.gitignore
@@ -0,0 +1,35 @@
+.DS_Store
+node_modules
+/components.d.ts
+/data
+/dist
+
+selenium-debug.log
+
+# local env files
+.env.local
+.env.*.local
+
+# Auto-generated files
+public/twemoji/
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw*
+
+# yalc
+.yalc
+yalc.lock
+
+# Sentry Auth Token
+.env.sentry-build-plugin
diff --git a/frontend-vue3/.prettierignore b/frontend-vue3/.prettierignore
new file mode 100644
index 0000000000..de2f837688
--- /dev/null
+++ b/frontend-vue3/.prettierignore
@@ -0,0 +1,6 @@
+src/common/locales/
+src/locales/
+/data
+/dist
+.vscode
+/public/twemoji
diff --git a/frontend-vue3/README.md b/frontend-vue3/README.md
new file mode 100644
index 0000000000..79caff12af
--- /dev/null
+++ b/frontend-vue3/README.md
@@ -0,0 +1,31 @@
+# frontend
+
+## Project setup
+
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+
+```
+npm run build
+```
+
+### Lints and fixes files
+
+```
+npm run lint
+```
+
+### Run your unit tests
+
+```
+npm run test:unit
+```
diff --git a/frontend-vue3/babel.config.js b/frontend-vue3/babel.config.js
new file mode 100644
index 0000000000..2b8a72a2f4
--- /dev/null
+++ b/frontend-vue3/babel.config.js
@@ -0,0 +1,7 @@
+// noinspection JSUnusedGlobalSymbols
+export const presets = ['@vue/app']
+export const env = {
+ test: {
+ plugins: ['require-context-hook'],
+ },
+}
diff --git a/frontend-vue3/docker-setup.sh b/frontend-vue3/docker-setup.sh
new file mode 100755
index 0000000000..91dd9c4dd9
--- /dev/null
+++ b/frontend-vue3/docker-setup.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+set -euo pipefail
+
+BASEDIR=$(dirname "$0")
+PDF_DIST=$BASEDIR"/src/pdf"
+
+if [ ! -f "$PDF_DIST/pdf.js" ] || [ ! -f "$PDF_DIST/prepareInMainThread.js" ]; then
+ # Copy dummy versions of the pdf build outputs, to make sure there is always something to import
+ cp "$PDF_DIST/pdf.js.dist" "$PDF_DIST/pdf.js"
+ cp "$PDF_DIST/prepareInMainThread.js.dist" "$PDF_DIST/prepareInMainThread.js"
+fi
+
+if [ "$CI" = 'true' ] ; then
+ npm ci --verbose
+ npm run build
+ npm run preview
+else
+ npm install
+ npm run dev
+fi
diff --git a/frontend-vue3/eslint-local-rules/index.js b/frontend-vue3/eslint-local-rules/index.js
new file mode 100644
index 0000000000..0431dd1383
--- /dev/null
+++ b/frontend-vue3/eslint-local-rules/index.js
@@ -0,0 +1,6 @@
+import utils from 'eslint-plugin-vue/lib/utils/index.js'
+// noinspection ES6UnusedImports
+import createMatchingTranslationKeys from '../../common/eslint-local-rules/matchingTranslationKeys.js'
+
+// noinspection JSUnusedGlobalSymbols
+export const matchingTranslationKeys = createMatchingTranslationKeys(utils)
diff --git a/frontend-vue3/eslint.config.mjs b/frontend-vue3/eslint.config.mjs
new file mode 100644
index 0000000000..4680e1ae15
--- /dev/null
+++ b/frontend-vue3/eslint.config.mjs
@@ -0,0 +1,98 @@
+import vueEslintConfigPrettier from '@vue/eslint-config-prettier'
+
+import { includeIgnoreFile } from '@eslint/compat'
+import localRules from 'eslint-plugin-local-rules'
+import globals from 'globals'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+import js from '@eslint/js'
+import { FlatCompat } from '@eslint/eslintrc'
+
+const __filename = fileURLToPath(import.meta.url)
+const __dirname = path.dirname(__filename)
+const compat = new FlatCompat({
+ baseDirectory: __dirname,
+ recommendedConfig: js.configs.recommended,
+ allConfig: js.configs.all,
+})
+const gitignorePath = path.resolve(__dirname, '.gitignore')
+export default [
+ ...compat.extends(
+ 'plugin:vue/vue3-recommended',
+ 'plugin:vue-scoped-css/vue3-recommended',
+ 'eslint:recommended'
+ ),
+ {
+ ignores: ['data/', 'dist/', 'public/twemoji/'],
+ },
+
+ includeIgnoreFile(gitignorePath),
+
+ vueEslintConfigPrettier,
+
+ {
+ plugins: {
+ 'local-rules': localRules,
+ },
+
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ },
+
+ parserOptions: {
+ ecmaVersion: '6',
+ parser: '@babel/eslint-parser',
+ },
+ },
+
+ rules: {
+ 'prefer-const': 'error',
+ 'prettier/prettier': 'error',
+
+ 'vue/component-tags-order': [
+ 'error',
+ {
+ order: ['template', 'script', 'style'],
+ },
+ ],
+
+ 'vue/multi-word-component-names': 'off',
+ 'vue/no-deprecated-destroyed-lifecycle': 'off',
+ 'vue/no-deprecated-dollar-listeners-api': 'off',
+ 'vue/no-deprecated-dollar-scopedslots-api': 'off',
+ 'vue/no-deprecated-filter': 'warn',
+ 'vue/no-deprecated-props-default-this': 'off',
+ 'vue/no-deprecated-slot-attribute': 'off',
+ 'vue/no-deprecated-slot-scope-attribute': 'off',
+ 'vue/no-deprecated-v-bind-sync': 'off',
+ 'vue/no-deprecated-v-on-native-modifier': 'warn',
+ 'vue/no-v-for-template-key-on-child': 'off',
+ 'vue/no-v-model-argument': 'warn',
+ 'vue/require-explicit-emits': 'off',
+
+ 'no-unused-vars': [
+ 'error',
+ {
+ argsIgnorePattern: '^_$',
+ },
+ ],
+
+ 'local-rules/matchingTranslationKeys': [
+ 'error',
+ {
+ ignoreKeysRegex:
+ '^(global|entity|contentNode\\.[a-z][a-zA-Z]+|print\\.(global|activity|cover|picasso|program|config|summary|toc|activityList))\\..+',
+ translationKeyPropRegex: '[a-zA-Z0-9]-i18n-key$',
+ },
+ ],
+
+ 'vue/no-mutating-props': [
+ 'error',
+ {
+ shallowOnly: true,
+ },
+ ],
+ },
+ },
+]
diff --git a/frontend-vue3/frontend/src/plugins/icons/BigScreen.vue b/frontend-vue3/frontend/src/plugins/icons/BigScreen.vue
new file mode 100644
index 0000000000..38b6fcb69d
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/BigScreen.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/CeviLogo.vue b/frontend-vue3/frontend/src/plugins/icons/CeviLogo.vue
new file mode 100644
index 0000000000..891d7aa053
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/CeviLogo.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/ColumnLayout.vue b/frontend-vue3/frontend/src/plugins/icons/ColumnLayout.vue
new file mode 100644
index 0000000000..13e4da4f70
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/ColumnLayout.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/GSLogo.vue b/frontend-vue3/frontend/src/plugins/icons/GSLogo.vue
new file mode 100644
index 0000000000..600d2a07f2
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/GSLogo.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/GoogleLogo.vue b/frontend-vue3/frontend/src/plugins/icons/GoogleLogo.vue
new file mode 100644
index 0000000000..f45efe6854
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/GoogleLogo.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/JSLogo.vue b/frontend-vue3/frontend/src/plugins/icons/JSLogo.vue
new file mode 100644
index 0000000000..661002f8af
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/JSLogo.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/JublaLogo.vue b/frontend-vue3/frontend/src/plugins/icons/JublaLogo.vue
new file mode 100644
index 0000000000..834c5a61f8
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/JublaLogo.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/PaperSize.vue b/frontend-vue3/frontend/src/plugins/icons/PaperSize.vue
new file mode 100644
index 0000000000..fd2f1a0506
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/PaperSize.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/PbsLogo.vue b/frontend-vue3/frontend/src/plugins/icons/PbsLogo.vue
new file mode 100644
index 0000000000..ba808c396b
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/PbsLogo.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/ResponsiveLayout.vue b/frontend-vue3/frontend/src/plugins/icons/ResponsiveLayout.vue
new file mode 100644
index 0000000000..fabf6ea911
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/ResponsiveLayout.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/TentDay.vue b/frontend-vue3/frontend/src/plugins/icons/TentDay.vue
new file mode 100644
index 0000000000..b673b46eab
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/TentDay.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/frontend/src/plugins/icons/eCampLogo.vue b/frontend-vue3/frontend/src/plugins/icons/eCampLogo.vue
new file mode 100644
index 0000000000..25d89d06f9
--- /dev/null
+++ b/frontend-vue3/frontend/src/plugins/icons/eCampLogo.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/index.html b/frontend-vue3/index.html
new file mode 100644
index 0000000000..34044dc6c4
--- /dev/null
+++ b/frontend-vue3/index.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ eCamp v3
+
+
+
+
+ Sorry, eCamp does not work without JavaScript. Please enable JavaScript to
+ continue.
+ Sorry, eCamp funktioniert nicht ohne JavaScript. Bitte aktiviere JavaScript um
+ fortzufahren.
+ Désolé, eCamp ne fonctionne pas sans JavaScript. Veuillez activer JavaScript pour
+ continuer.
+ Spiacente, eCamp non funziona senza JavaScript. Per favore, abilita JavaScript
+ per continuare.
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/jsconfig.json b/frontend-vue3/jsconfig.json
new file mode 100644
index 0000000000..abe04df578
--- /dev/null
+++ b/frontend-vue3/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/frontend-vue3/package-lock.json b/frontend-vue3/package-lock.json
new file mode 100644
index 0000000000..a635cf76d9
--- /dev/null
+++ b/frontend-vue3/package-lock.json
@@ -0,0 +1,12100 @@
+{
+ "name": "@ecamp3/frontend",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@ecamp3/frontend",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@intlify/core": "11.1.11",
+ "@mdi/font": "7.4.47",
+ "@react-pdf/font": "4.0.2",
+ "@react-pdf/layout": "4.4.0",
+ "@react-pdf/pdfkit": "4.0.3",
+ "@react-pdf/primitives": "4.1.1",
+ "@react-pdf/render": "4.3.0",
+ "@sentry/browser": "9.44.0",
+ "@sentry/vue": "9.44.0",
+ "@tiptap/extension-bold": "3.0.9",
+ "@tiptap/extension-bubble-menu": "3.0.9",
+ "@tiptap/extension-bullet-list": "3.0.9",
+ "@tiptap/extension-document": "3.0.9",
+ "@tiptap/extension-hard-break": "3.0.9",
+ "@tiptap/extension-heading": "3.0.9",
+ "@tiptap/extension-history": "3.0.9",
+ "@tiptap/extension-italic": "3.0.9",
+ "@tiptap/extension-list-item": "3.0.9",
+ "@tiptap/extension-ordered-list": "3.0.9",
+ "@tiptap/extension-paragraph": "3.0.9",
+ "@tiptap/extension-placeholder": "3.0.9",
+ "@tiptap/extension-strike": "3.0.9",
+ "@tiptap/extension-text": "3.0.9",
+ "@tiptap/extension-underline": "3.0.9",
+ "@tiptap/vue-3": "3.0.9",
+ "@unhead/vue": "2.0.14",
+ "@vee-validate/i18n": "4.15.1",
+ "@vee-validate/rules": "4.15.1",
+ "@vue/compat": "3.5.21",
+ "@zxcvbn-ts/core": "3.0.4",
+ "@zxcvbn-ts/language-common": "3.0.4",
+ "@zxcvbn-ts/language-de": "3.0.2",
+ "@zxcvbn-ts/language-en": "3.0.2",
+ "@zxcvbn-ts/language-fr": "3.0.2",
+ "@zxcvbn-ts/language-it": "3.0.2",
+ "assert": "2.1.0",
+ "axios": "1.11.0",
+ "colorjs.io": "0.5.2",
+ "comlink": "4.4.2",
+ "dayjs": "1.11.13",
+ "deepmerge": "4.3.1",
+ "emoji-regex": "10.4.0",
+ "file-saver": "2.0.5",
+ "hal-json-vuex": "3.0.0-alpha.10",
+ "inter-ui": "3.19.3",
+ "js-cookie": "3.0.5",
+ "linkify-it": "5.0.0",
+ "lodash-es": "4.17.21",
+ "runes": "0.4.3",
+ "slugify": "1.6.6",
+ "url-template": "3.1.1",
+ "util": "0.12.5",
+ "v-resize-observer": "2.1.0",
+ "vee-validate": "4.15.1",
+ "vue": "3.5.21",
+ "vue-axios": "3.5.2",
+ "vue-i18n": "11.1.11",
+ "vue-recaptcha-v3": "2.0.1",
+ "vue-router": "4.5.1",
+ "vue-toastification": "2.0.0-rc.5",
+ "vuedraggable": "2.24.3",
+ "vuetify": "3.10.4",
+ "vuex": "4.0.2",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
+ },
+ "devDependencies": {
+ "@babel/eslint-parser": "7.28.0",
+ "@eslint/compat": "1.3.1",
+ "@eslint/eslintrc": "3.3.1",
+ "@eslint/js": "9.32.0",
+ "@sentry/vite-plugin": "4.0.2",
+ "@testing-library/jest-dom": "6.6.4",
+ "@testing-library/user-event": "14.6.1",
+ "@testing-library/vue": "8.1.0",
+ "@vitejs/plugin-vue": "6.0.1",
+ "@vitest/coverage-v8": "3.2.4",
+ "@vue/babel-preset-app": "5.0.9",
+ "@vue/compiler-dom": "3.5.21",
+ "@vue/compiler-sfc": "3.5.21",
+ "@vue/eslint-config-prettier": "10.2.0",
+ "@vue/runtime-dom": "3.5.21",
+ "@vue/server-renderer": "3.5.21",
+ "@vue/shared": "3.5.21",
+ "@vue/test-utils": "2.4.6",
+ "autoprefixer": "10.4.21",
+ "babel-plugin-require-context-hook": "1.0.0",
+ "eslint": "9.32.0",
+ "eslint-config-prettier": "10.1.8",
+ "eslint-plugin-local-rules": "3.0.2",
+ "eslint-plugin-n": "17.21.3",
+ "eslint-plugin-prettier": "5.5.3",
+ "eslint-plugin-promise": "7.2.1",
+ "eslint-plugin-vue": "10.4.0",
+ "eslint-plugin-vue-scoped-css": "2.11.0",
+ "flush-promises": "1.0.2",
+ "globals": "16.3.0",
+ "jest-serializer-vue-tjw": "4.0.0",
+ "jsdom": "26.1.0",
+ "lint-staged": "16.1.4",
+ "prettier": "3.6.2",
+ "sass": "1.89.2",
+ "unplugin-vue-components": "28.8.0",
+ "vite": "6.3.5",
+ "vite-plugin-comlink": "5.3.0",
+ "vite-plugin-vuetify": "2.1.2",
+ "vite-svg-loader": "5.1.0",
+ "vitest": "3.2.4",
+ "vitest-canvas-mock": "0.3.3"
+ }
+ },
+ "node_modules/@adobe/css-tools": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz",
+ "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==",
+ "dev": true
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+ "dev": true,
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz",
+ "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz",
+ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.3",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-module-transforms": "^7.28.3",
+ "@babel/helpers": "^7.28.4",
+ "@babel/parser": "^7.28.4",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.4",
+ "@babel/types": "^7.28.4",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/eslint-parser": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.0.tgz",
+ "integrity": "sha512-N4ntErOlKvcbTt01rr5wj3y55xnIdx1ymrfIr8C2WnM1Y9glFgWaGDEULJIazOX3XM9NRzhfJ6zZnQ1sBNWU+w==",
+ "dev": true,
+ "dependencies": {
+ "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
+ "eslint-visitor-keys": "^2.1.0",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || >=14.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.11.0",
+ "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
+ "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.28.3",
+ "@babel/types": "^7.28.2",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.27.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
+ "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.27.2",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz",
+ "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-member-expression-to-functions": "^7.27.1",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/traverse": "^7.28.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz",
+ "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "regexpu-core": "^6.2.0",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz",
+ "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "debug": "^4.4.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.22.10"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz",
+ "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.28.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
+ "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
+ "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-wrap-function": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz",
+ "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.27.1",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
+ "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "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==",
+ "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==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz",
+ "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.3",
+ "@babel/types": "^7.28.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
+ "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
+ "dependencies": {
+ "@babel/types": "^7.28.4"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz",
+ "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz",
+ "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz",
+ "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz",
+ "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/plugin-transform-optional-chaining": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.13.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz",
+ "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.28.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-class-properties": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
+ "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-decorators": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz",
+ "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-syntax-decorators": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.21.0-placeholder-for-preset-env.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+ "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-decorators": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz",
+ "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-assertions": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz",
+ "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz",
+ "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz",
+ "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
+ "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-generator-functions": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz",
+ "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-remap-async-to-generator": "^7.27.1",
+ "@babel/traverse": "^7.28.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz",
+ "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-remap-async-to-generator": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz",
+ "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz",
+ "integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-properties": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz",
+ "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-static-block": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz",
+ "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.28.3",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz",
+ "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1",
+ "@babel/traverse": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz",
+ "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/template": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz",
+ "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.28.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz",
+ "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz",
+ "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz",
+ "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dynamic-import": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz",
+ "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-explicit-resource-management": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz",
+ "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-transform-destructuring": "^7.28.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz",
+ "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
+ "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
+ "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
+ "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-json-strings": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz",
+ "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
+ "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz",
+ "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz",
+ "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz",
+ "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz",
+ "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz",
+ "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz",
+ "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz",
+ "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz",
+ "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz",
+ "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-numeric-separator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz",
+ "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-rest-spread": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz",
+ "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-transform-destructuring": "^7.28.0",
+ "@babel/plugin-transform-parameters": "^7.27.7",
+ "@babel/traverse": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz",
+ "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-catch-binding": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz",
+ "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-chaining": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz",
+ "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz",
+ "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-methods": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz",
+ "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-property-in-object": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz",
+ "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz",
+ "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz",
+ "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz",
+ "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz",
+ "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-runtime": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.3.tgz",
+ "integrity": "sha512-Y6ab1kGqZ0u42Zv/4a7l0l72n9DKP/MKoKWaUSBylrhNZO2prYuqFOLbn5aW5SIFXwSH93yfjbgllL8lxuGKLg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "babel-plugin-polyfill-corejs2": "^0.4.14",
+ "babel-plugin-polyfill-corejs3": "^0.13.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.5",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
+ "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz",
+ "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
+ "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
+ "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz",
+ "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz",
+ "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-property-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz",
+ "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz",
+ "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz",
+ "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz",
+ "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.28.0",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3",
+ "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+ "@babel/plugin-syntax-import-assertions": "^7.27.1",
+ "@babel/plugin-syntax-import-attributes": "^7.27.1",
+ "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+ "@babel/plugin-transform-arrow-functions": "^7.27.1",
+ "@babel/plugin-transform-async-generator-functions": "^7.28.0",
+ "@babel/plugin-transform-async-to-generator": "^7.27.1",
+ "@babel/plugin-transform-block-scoped-functions": "^7.27.1",
+ "@babel/plugin-transform-block-scoping": "^7.28.0",
+ "@babel/plugin-transform-class-properties": "^7.27.1",
+ "@babel/plugin-transform-class-static-block": "^7.28.3",
+ "@babel/plugin-transform-classes": "^7.28.3",
+ "@babel/plugin-transform-computed-properties": "^7.27.1",
+ "@babel/plugin-transform-destructuring": "^7.28.0",
+ "@babel/plugin-transform-dotall-regex": "^7.27.1",
+ "@babel/plugin-transform-duplicate-keys": "^7.27.1",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1",
+ "@babel/plugin-transform-dynamic-import": "^7.27.1",
+ "@babel/plugin-transform-explicit-resource-management": "^7.28.0",
+ "@babel/plugin-transform-exponentiation-operator": "^7.27.1",
+ "@babel/plugin-transform-export-namespace-from": "^7.27.1",
+ "@babel/plugin-transform-for-of": "^7.27.1",
+ "@babel/plugin-transform-function-name": "^7.27.1",
+ "@babel/plugin-transform-json-strings": "^7.27.1",
+ "@babel/plugin-transform-literals": "^7.27.1",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.27.1",
+ "@babel/plugin-transform-member-expression-literals": "^7.27.1",
+ "@babel/plugin-transform-modules-amd": "^7.27.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.27.1",
+ "@babel/plugin-transform-modules-systemjs": "^7.27.1",
+ "@babel/plugin-transform-modules-umd": "^7.27.1",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1",
+ "@babel/plugin-transform-new-target": "^7.27.1",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
+ "@babel/plugin-transform-numeric-separator": "^7.27.1",
+ "@babel/plugin-transform-object-rest-spread": "^7.28.0",
+ "@babel/plugin-transform-object-super": "^7.27.1",
+ "@babel/plugin-transform-optional-catch-binding": "^7.27.1",
+ "@babel/plugin-transform-optional-chaining": "^7.27.1",
+ "@babel/plugin-transform-parameters": "^7.27.7",
+ "@babel/plugin-transform-private-methods": "^7.27.1",
+ "@babel/plugin-transform-private-property-in-object": "^7.27.1",
+ "@babel/plugin-transform-property-literals": "^7.27.1",
+ "@babel/plugin-transform-regenerator": "^7.28.3",
+ "@babel/plugin-transform-regexp-modifiers": "^7.27.1",
+ "@babel/plugin-transform-reserved-words": "^7.27.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.27.1",
+ "@babel/plugin-transform-spread": "^7.27.1",
+ "@babel/plugin-transform-sticky-regex": "^7.27.1",
+ "@babel/plugin-transform-template-literals": "^7.27.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.27.1",
+ "@babel/plugin-transform-unicode-escapes": "^7.27.1",
+ "@babel/plugin-transform-unicode-property-regex": "^7.27.1",
+ "@babel/plugin-transform-unicode-regex": "^7.27.1",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.27.1",
+ "@babel/preset-modules": "0.1.6-no-external-plugins",
+ "babel-plugin-polyfill-corejs2": "^0.4.14",
+ "babel-plugin-polyfill-corejs3": "^0.13.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.5",
+ "core-js-compat": "^3.43.0",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.6-no-external-plugins",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
+ "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz",
+ "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.3",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.4",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.4",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
+ "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
+ "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz",
+ "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "dependencies": {
+ "@csstools/color-helpers": "^5.1.0",
+ "@csstools/css-calc": "^2.1.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
+ "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz",
+ "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz",
+ "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz",
+ "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz",
+ "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz",
+ "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz",
+ "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz",
+ "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz",
+ "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz",
+ "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz",
+ "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz",
+ "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz",
+ "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz",
+ "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz",
+ "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz",
+ "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz",
+ "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz",
+ "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz",
+ "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz",
+ "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz",
+ "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz",
+ "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz",
+ "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz",
+ "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz",
+ "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz",
+ "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.8.0.tgz",
+ "integrity": "sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/compat": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.3.1.tgz",
+ "integrity": "sha512-k8MHony59I5EPic6EQTCNOuPoVBnoYXkP+20xvwFjN7t0qI3ImyvyBgg+hIVPwC8JaxVjjUZld+cLfBLFDLucg==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "peerDependencies": {
+ "eslint": "^8.40 || 9"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.32.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz",
+ "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/core": "^0.15.2",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
+ "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.10"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz",
+ "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.3",
+ "@floating-ui/utils": "^0.2.10"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
+ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@intlify/core": {
+ "version": "11.1.11",
+ "resolved": "https://registry.npmjs.org/@intlify/core/-/core-11.1.11.tgz",
+ "integrity": "sha512-cq3NnOQN9KSNJYcKV5YNj9IPEYi4GJbOUBy4gVbGKcxC83msSOcTvkpPq0pdMYZDqx6tPDIcr7xKT9qHjcJASQ==",
+ "dependencies": {
+ "@intlify/core-base": "11.1.11",
+ "@intlify/shared": "11.1.11"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@intlify/core-base": {
+ "version": "11.1.11",
+ "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.1.11.tgz",
+ "integrity": "sha512-1Z0N8jTfkcD2Luq9HNZt+GmjpFe4/4PpZF3AOzoO1u5PTtSuXZcfhwBatywbfE2ieB/B5QHIoOFmCXY2jqVKEQ==",
+ "dependencies": {
+ "@intlify/message-compiler": "11.1.11",
+ "@intlify/shared": "11.1.11"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@intlify/message-compiler": {
+ "version": "11.1.11",
+ "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.1.11.tgz",
+ "integrity": "sha512-7PC6neomoc/z7a8JRjPBbu0T2TzR2MQuY5kn2e049MP7+o32Ve7O8husylkA7K9fQRe4iNXZWTPnDJ6vZdtS1Q==",
+ "dependencies": {
+ "@intlify/shared": "11.1.11",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@intlify/shared": {
+ "version": "11.1.11",
+ "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.1.11.tgz",
+ "integrity": "sha512-RIBFTIqxZSsxUqlcyoR7iiC632bq7kkOwYvZlvcVObHfrF4NhuKc4FKvu8iPCrEO+e3XsY7/UVpfgzg+M7ETzA==",
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.30",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz",
+ "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@mdi/font": {
+ "version": "7.4.47",
+ "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz",
+ "integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw=="
+ },
+ "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": {
+ "version": "5.1.1-v1",
+ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
+ "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==",
+ "dev": true,
+ "dependencies": {
+ "eslint-scope": "5.1.1"
+ }
+ },
+ "node_modules/@one-ini/wasm": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
+ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
+ "dev": true
+ },
+ "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==",
+ "hasInstallScript": true,
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@pkgr/core": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
+ "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
+ "node_modules/@react-pdf/fns": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@react-pdf/fns/-/fns-3.1.2.tgz",
+ "integrity": "sha512-qTKGUf0iAMGg2+OsUcp9ffKnKi41RukM/zYIWMDJ4hRVYSr89Q7e3wSDW/Koqx3ea3Uy/z3h2y3wPX6Bdfxk6g=="
+ },
+ "node_modules/@react-pdf/font": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@react-pdf/font/-/font-4.0.2.tgz",
+ "integrity": "sha512-/dAWu7Y2RD1RxarDZ9SkYPHgBYOhmcDnet4W/qN/m8k+A2Hr3ja54GymSR7GGxWBtxjKtNauVKrTa9LS1n8WUw==",
+ "dependencies": {
+ "@react-pdf/pdfkit": "^4.0.3",
+ "@react-pdf/types": "^2.9.0",
+ "fontkit": "^2.0.2",
+ "is-url": "^1.2.4"
+ }
+ },
+ "node_modules/@react-pdf/image": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@react-pdf/image/-/image-3.0.3.tgz",
+ "integrity": "sha512-lvP5ryzYM3wpbO9bvqLZYwEr5XBDX9jcaRICvtnoRqdJOo7PRrMnmB4MMScyb+Xw10mGeIubZAAomNAG5ONQZQ==",
+ "dependencies": {
+ "@react-pdf/png-js": "^3.0.0",
+ "jay-peg": "^1.1.1"
+ }
+ },
+ "node_modules/@react-pdf/layout": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf/layout/-/layout-4.4.0.tgz",
+ "integrity": "sha512-Aq+Cc6JYausWLoks2FvHe3PwK9cTuvksB2uJ0AnkKJEUtQbvCq8eCRb1bjbbwIji9OzFRTTzZij7LzkpKHjIeA==",
+ "dependencies": {
+ "@react-pdf/fns": "3.1.2",
+ "@react-pdf/image": "^3.0.3",
+ "@react-pdf/primitives": "^4.1.1",
+ "@react-pdf/stylesheet": "^6.1.0",
+ "@react-pdf/textkit": "^6.0.0",
+ "@react-pdf/types": "^2.9.0",
+ "emoji-regex": "^10.3.0",
+ "queue": "^6.0.1",
+ "yoga-layout": "^3.2.1"
+ }
+ },
+ "node_modules/@react-pdf/pdfkit": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@react-pdf/pdfkit/-/pdfkit-4.0.3.tgz",
+ "integrity": "sha512-k+Lsuq8vTwWsCqTp+CCB4+2N+sOTFrzwGA7aw3H9ix/PDWR9QksbmNg0YkzGbLAPI6CeawmiLHcf4trZ5ecLPQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/png-js": "^3.0.0",
+ "browserify-zlib": "^0.2.0",
+ "crypto-js": "^4.2.0",
+ "fontkit": "^2.0.2",
+ "jay-peg": "^1.1.1",
+ "linebreak": "^1.1.0",
+ "vite-compatible-readable-stream": "^3.6.1"
+ }
+ },
+ "node_modules/@react-pdf/png-js": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf/png-js/-/png-js-3.0.0.tgz",
+ "integrity": "sha512-eSJnEItZ37WPt6Qv5pncQDxLJRK15eaRwPT+gZoujP548CodenOVp49GST8XJvKMFt9YqIBzGBV/j9AgrOQzVA==",
+ "dependencies": {
+ "browserify-zlib": "^0.2.0"
+ }
+ },
+ "node_modules/@react-pdf/primitives": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@react-pdf/primitives/-/primitives-4.1.1.tgz",
+ "integrity": "sha512-IuhxYls1luJb7NUWy6q5avb1XrNaVj9bTNI40U9qGRuS6n7Hje/8H8Qi99Z9UKFV74bBP3DOf3L1wV2qZVgVrQ=="
+ },
+ "node_modules/@react-pdf/render": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf/render/-/render-4.3.0.tgz",
+ "integrity": "sha512-MdWfWaqO6d7SZD75TZ2z5L35V+cHpyA43YNRlJNG0RJ7/MeVGDQv12y/BXOJgonZKkeEGdzM3EpAt9/g4E22WA==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@react-pdf/fns": "3.1.2",
+ "@react-pdf/primitives": "^4.1.1",
+ "@react-pdf/textkit": "^6.0.0",
+ "@react-pdf/types": "^2.9.0",
+ "abs-svg-path": "^0.1.1",
+ "color-string": "^1.9.1",
+ "normalize-svg-path": "^1.1.0",
+ "parse-svg-path": "^0.1.2",
+ "svg-arc-to-cubic-bezier": "^3.2.0"
+ }
+ },
+ "node_modules/@react-pdf/stylesheet": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf/stylesheet/-/stylesheet-6.1.0.tgz",
+ "integrity": "sha512-BGZ2sYNUp38VJUegjva/jsri3iiRGnVNjWI+G9dTwAvLNOmwFvSJzqaCsEnqQ/DW5mrTBk/577FhDY7pv6AidA==",
+ "dependencies": {
+ "@react-pdf/fns": "3.1.2",
+ "@react-pdf/types": "^2.9.0",
+ "color-string": "^1.9.1",
+ "hsl-to-hex": "^1.0.0",
+ "media-engine": "^1.0.3",
+ "postcss-value-parser": "^4.1.0"
+ }
+ },
+ "node_modules/@react-pdf/textkit": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf/textkit/-/textkit-6.0.0.tgz",
+ "integrity": "sha512-fDt19KWaJRK/n2AaFoVm31hgGmpygmTV7LsHGJNGZkgzXcFyLsx+XUl63DTDPH3iqxj3xUX128t104GtOz8tTw==",
+ "dependencies": {
+ "@react-pdf/fns": "3.1.2",
+ "bidi-js": "^1.0.2",
+ "hyphen": "^1.6.4",
+ "unicode-properties": "^1.4.1"
+ }
+ },
+ "node_modules/@react-pdf/types": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/@react-pdf/types/-/types-2.9.0.tgz",
+ "integrity": "sha512-ckj80vZLlvl9oYrQ4tovEaqKWP3O06Eb1D48/jQWbdwz1Yh7Y9v1cEmwlP8ET+a1Whp8xfdM0xduMexkuPANCQ==",
+ "dependencies": {
+ "@react-pdf/font": "^4.0.2",
+ "@react-pdf/primitives": "^4.1.1",
+ "@react-pdf/stylesheet": "^6.1.0"
+ }
+ },
+ "node_modules/@remirror/core-constants": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz",
+ "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==",
+ "peer": true
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.29",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.29.tgz",
+ "integrity": "sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==",
+ "dev": true
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.0.tgz",
+ "integrity": "sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.0.tgz",
+ "integrity": "sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.0.tgz",
+ "integrity": "sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.0.tgz",
+ "integrity": "sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.0.tgz",
+ "integrity": "sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.0.tgz",
+ "integrity": "sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.0.tgz",
+ "integrity": "sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.0.tgz",
+ "integrity": "sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.0.tgz",
+ "integrity": "sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.0.tgz",
+ "integrity": "sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.0.tgz",
+ "integrity": "sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.0.tgz",
+ "integrity": "sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.0.tgz",
+ "integrity": "sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.0.tgz",
+ "integrity": "sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.0.tgz",
+ "integrity": "sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.0.tgz",
+ "integrity": "sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.0.tgz",
+ "integrity": "sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.0.tgz",
+ "integrity": "sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.0.tgz",
+ "integrity": "sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.0.tgz",
+ "integrity": "sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.0.tgz",
+ "integrity": "sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@sentry-internal/browser-utils": {
+ "version": "9.44.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.44.0.tgz",
+ "integrity": "sha512-ySIXxq3xq2lhY/XPMLUtaUd6HghJUsz+S5GksuRCxv6exY6mRMjsbm7VhcAEPmY4IrhsXjnEzCONP+M7pzAc3A==",
+ "dependencies": {
+ "@sentry/core": "9.44.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/feedback": {
+ "version": "9.44.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.44.0.tgz",
+ "integrity": "sha512-ptA74gXPU7qV9eBuz2UUyFv+BroMrVMZD58eIG3IkRu93mAH0dhJiKmd1rhlWheXfhFhiw82WdNH9sTQj7++GA==",
+ "dependencies": {
+ "@sentry/core": "9.44.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/replay": {
+ "version": "9.44.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.44.0.tgz",
+ "integrity": "sha512-IVRbONKaoxcDItpcXV9wpNCL+T5iMnTLJv2glMULMnqU4nplhBynxjSyng1s/rpTU4PwwYYIgwkb4Z0GMIYPlg==",
+ "dependencies": {
+ "@sentry-internal/browser-utils": "9.44.0",
+ "@sentry/core": "9.44.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry-internal/replay-canvas": {
+ "version": "9.44.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.44.0.tgz",
+ "integrity": "sha512-JTRBlKsd46tz/bE6FE8bRsapteWwBt+4eviYZlE6Wn/QSirYOqEniibhJ8GIUIpUmHpkrvNAfIRaKJ4tXYaqGQ==",
+ "dependencies": {
+ "@sentry-internal/replay": "9.44.0",
+ "@sentry/core": "9.44.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/babel-plugin-component-annotate": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-4.0.2.tgz",
+ "integrity": "sha512-Nr/VamvpQs6w642EI5t+qaCUGnVEro0qqk+S8XO1gc8qSdpc8kkZJFnUk7ozAr+ljYWGfVgWXrxI9lLiriLsRA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@sentry/browser": {
+ "version": "9.44.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.44.0.tgz",
+ "integrity": "sha512-QhZds04ta8m1SGN8jpF22kFu2SyM2FcHM2tFBaFuYTK6b7ouBII6YpYLhXulZvF+xl/pxnYsXHgyeTJ5JseITg==",
+ "dependencies": {
+ "@sentry-internal/browser-utils": "9.44.0",
+ "@sentry-internal/feedback": "9.44.0",
+ "@sentry-internal/replay": "9.44.0",
+ "@sentry-internal/replay-canvas": "9.44.0",
+ "@sentry/core": "9.44.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/bundler-plugin-core": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-4.0.2.tgz",
+ "integrity": "sha512-LeARs8qHhEw19tk+KZd9DDV+Rh/UeapIH0+C09fTmff9p8Y82Cj89pEQ2a1rdUiF/oYIjQX45vnZscB7ra42yw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.18.5",
+ "@sentry/babel-plugin-component-annotate": "4.0.2",
+ "@sentry/cli": "^2.49.0",
+ "dotenv": "^16.3.1",
+ "find-up": "^5.0.0",
+ "glob": "^9.3.2",
+ "magic-string": "0.30.8",
+ "unplugin": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@sentry/cli": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.53.0.tgz",
+ "integrity": "sha512-n2ZNb+5Z6AZKQSI0SusQ7ZzFL637mfw3Xh4C3PEyVSn9LiF683fX0TTq8OeGmNZQS4maYfS95IFD+XpydU0dEA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "https-proxy-agent": "^5.0.0",
+ "node-fetch": "^2.6.7",
+ "progress": "^2.0.3",
+ "proxy-from-env": "^1.1.0",
+ "which": "^2.0.2"
+ },
+ "bin": {
+ "sentry-cli": "bin/sentry-cli"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@sentry/cli-darwin": "2.53.0",
+ "@sentry/cli-linux-arm": "2.53.0",
+ "@sentry/cli-linux-arm64": "2.53.0",
+ "@sentry/cli-linux-i686": "2.53.0",
+ "@sentry/cli-linux-x64": "2.53.0",
+ "@sentry/cli-win32-arm64": "2.53.0",
+ "@sentry/cli-win32-i686": "2.53.0",
+ "@sentry/cli-win32-x64": "2.53.0"
+ }
+ },
+ "node_modules/@sentry/cli-darwin": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.53.0.tgz",
+ "integrity": "sha512-NNPfpILMwKgpHiyJubHHuauMKltkrgLQ5tvMdxNpxY60jBNdo5VJtpESp4XmXlnidzV4j1z61V4ozU6ttDgt5Q==",
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-arm": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.53.0.tgz",
+ "integrity": "sha512-NdRzQ15Ht83qG0/Lyu11ciy/Hu/oXbbtJUgwzACc7bWvHQA8xEwTsehWexqn1529Kfc5EjuZ0Wmj3MHmp+jOWw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd",
+ "android"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-arm64": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.53.0.tgz",
+ "integrity": "sha512-xY/CZ1dVazsSCvTXzKpAgXaRqfljVfdrFaYZRUaRPf1ZJRGa3dcrivoOhSIeG/p5NdYtMvslMPY9Gm2MT0M83A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd",
+ "android"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-i686": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.53.0.tgz",
+ "integrity": "sha512-0REmBibGAB4jtqt9S6JEsFF4QybzcXHPcHtJjgMi5T0ueh952uG9wLzjSxQErCsxTKF+fL8oG0Oz5yKBuCwCCQ==",
+ "cpu": [
+ "x86",
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd",
+ "android"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-x64": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.53.0.tgz",
+ "integrity": "sha512-9UGJL+Vy5N/YL1EWPZ/dyXLkShlNaDNrzxx4G7mTS9ywjg+BIuemo6rnN7w43K1NOjObTVO6zY0FwumJ1pCyLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd",
+ "android"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-win32-arm64": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.53.0.tgz",
+ "integrity": "sha512-G1kjOjrjMBY20rQcJV2GA8KQE74ufmROCDb2GXYRfjvb1fKAsm4Oh8N5+Tqi7xEHdjQoLPkE4CNW0aH68JSUDQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-win32-i686": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.53.0.tgz",
+ "integrity": "sha512-qbGTZUzesuUaPtY9rPXdNfwLqOZKXrJRC1zUFn52hdo6B+Dmv0m/AHwRVFHZP53Tg1NCa8bDei2K/uzRN0dUZw==",
+ "cpu": [
+ "x86",
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-win32-x64": {
+ "version": "2.53.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.53.0.tgz",
+ "integrity": "sha512-1TXYxYHtwgUq5KAJt3erRzzUtPqg7BlH9T7MdSPHjJatkrr/kwZqnVe2H6Arr/5NH891vOlIeSPHBdgJUAD69g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/core": {
+ "version": "9.44.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.44.0.tgz",
+ "integrity": "sha512-U+KBNGgq/eXIj226CPtRk+n5dx0q1xGVvbLbyfAyeek9C/wxQ3f+mvqeVqF9cx8FfrWIOeDM1F8ISH5uRkjjQg==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/vite-plugin": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-4.0.2.tgz",
+ "integrity": "sha512-rStdvDGj0VcJBsl2NANE3OQF5m13VCJ+2Ovs5pb2LAqOW72/1GLmef9Mo3b9BwzCjWOQIcgtllwOfSV5Pse03w==",
+ "dev": true,
+ "dependencies": {
+ "@sentry/bundler-plugin-core": "4.0.2",
+ "unplugin": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@sentry/vue": {
+ "version": "9.44.0",
+ "resolved": "https://registry.npmjs.org/@sentry/vue/-/vue-9.44.0.tgz",
+ "integrity": "sha512-UwO8GrZhtwiI0oWQJq8ZdcjSiK0ZYMbq3z8po49eqd+Li7wCrwImWRUB5rllX96YuWMXFKi4B3vfmuya/AmSQg==",
+ "dependencies": {
+ "@sentry/browser": "9.44.0",
+ "@sentry/core": "9.44.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "pinia": "2.x || 3.x",
+ "vue": "2.x || 3.x"
+ },
+ "peerDependenciesMeta": {
+ "pinia": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.17",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
+ "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@testing-library/dom": {
+ "version": "10.4.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
+ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.3.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.5.0",
+ "picocolors": "1.1.1",
+ "pretty-format": "^27.0.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@testing-library/jest-dom": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.4.tgz",
+ "integrity": "sha512-xDXgLjVunjHqczScfkCJ9iyjdNOVHvvCdqHSSxwM9L0l/wHkTRum67SDc020uAlCoqktJplgO2AAQeLP1wgqDQ==",
+ "dev": true,
+ "dependencies": {
+ "@adobe/css-tools": "^4.4.0",
+ "aria-query": "^5.0.0",
+ "css.escape": "^1.5.1",
+ "dom-accessibility-api": "^0.6.3",
+ "lodash": "^4.17.21",
+ "picocolors": "^1.1.1",
+ "redent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
+ "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
+ "dev": true
+ },
+ "node_modules/@testing-library/user-event": {
+ "version": "14.6.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
+ "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": ">=7.21.4"
+ }
+ },
+ "node_modules/@testing-library/vue": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/vue/-/vue-8.1.0.tgz",
+ "integrity": "sha512-ls4RiHO1ta4mxqqajWRh8158uFObVrrtAPoxk7cIp4HrnQUj/ScKzqz53HxYpG3X6Zb7H2v+0eTGLSoy8HQ2nA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/runtime": "^7.23.2",
+ "@testing-library/dom": "^9.3.3",
+ "@vue/test-utils": "^2.4.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@vue/compiler-sfc": ">= 3",
+ "vue": ">= 3"
+ },
+ "peerDependenciesMeta": {
+ "@vue/compiler-sfc": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@testing-library/vue/node_modules/@testing-library/dom": {
+ "version": "9.3.4",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz",
+ "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.1.3",
+ "chalk": "^4.1.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.5.0",
+ "pretty-format": "^27.0.2"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@testing-library/vue/node_modules/aria-query": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
+ "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
+ "dev": true,
+ "dependencies": {
+ "deep-equal": "^2.0.5"
+ }
+ },
+ "node_modules/@tiptap/core": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.4.1.tgz",
+ "integrity": "sha512-31TFNnejJeOL/Ds9uB2Y7EnldXsTLeM3HQ7vExKU6So1o0gdFIBV67m/CESy84lmdb2O7ZXfQVOqedJgojip6A==",
+ "peer": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/pm": "^3.4.1"
+ }
+ },
+ "node_modules/@tiptap/extension-bold": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.0.9.tgz",
+ "integrity": "sha512-rVULIFt9ZO+fO5ty9zuC3HwY3knxUw7q9JBztpKPfQQCuIJ+iQnOfB8NtI3L8hxVSxhIR1pqr8B3S/8vlpXbVg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-bubble-menu": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.0.9.tgz",
+ "integrity": "sha512-fZQfdSbKJl3J+Yi+s8NrcLBgXHOaGVD4g+vn+orTPUlZdG9FWvEoon8DexOdK9OvYnW6QMM7kS8whOgpogVyUQ==",
+ "dependencies": {
+ "@floating-ui/dom": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9",
+ "@tiptap/pm": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-bullet-list": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.0.9.tgz",
+ "integrity": "sha512-Aob5TVfrtoEzfTm3wl7lognmWia6EEilOxLihSGISCvI4FTndJg+mwhumduQeYCLWkF9i/DR87m2/3EbjR3R4Q==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/extension-list": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-document": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.0.9.tgz",
+ "integrity": "sha512-DB/R5e6QvuGhY8EhCkfNjR2xQfz/TOWoxfQGhDuy5U+oK3WBwCcHq9t5+nbSCMHtKfi/i49aHKDvv7TQCpuP0w==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-floating-menu": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.4.1.tgz",
+ "integrity": "sha512-9qGINja20Kz4XI0uESoYiwgGo+ejvDrHiSoRmd3jkDMv6fGMXj1U+HYzqhXZTV30kuQZQN8twNmbmzBu+jltYQ==",
+ "optional": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@floating-ui/dom": "^1.0.0",
+ "@tiptap/core": "^3.4.1",
+ "@tiptap/pm": "^3.4.1"
+ }
+ },
+ "node_modules/@tiptap/extension-hard-break": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.0.9.tgz",
+ "integrity": "sha512-PWNYsUwVsMWt/R5/OWjfGb+7DQT0DvH+1owBimRq0pWZepg8qkz1jdPGgsRmUFyERRsXeEpgj3VaQfrgbyUfrA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-heading": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.0.9.tgz",
+ "integrity": "sha512-LRLCIt87fvDZ5CdkinzhkCwRz5ax6FlsjJzG32MJ3wXyvVslqeLXBvH28JFUZEyzgcd/SnYmYxnef5+yvAX61g==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-history": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-3.0.9.tgz",
+ "integrity": "sha512-wTSNy85Kla77y9zSUrNEGUVkqCWK9fU+Dsq8wH1A7Xrgi7vBPGkzhy8jpA8+CYtd6xI6c9IiuZrX+x44vjBlSw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/extensions": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-italic": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.0.9.tgz",
+ "integrity": "sha512-Gt4FbMtZerzKpit8+FvIjIQ3CBD559/FFC+kOT9y8JHlINeqWyh/bgHuaA/9/XtHphOQiA7NDwOiuPh4KIKpqA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-list": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.4.1.tgz",
+ "integrity": "sha512-HyPvpBoenF+e2EwIrg+/en7axIn9MEcgLzfsm0W0U0XMXY5oAyvvfFDv827Zop6NndDvbdEHLEGE8J9IEpJw3Q==",
+ "peer": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.4.1",
+ "@tiptap/pm": "^3.4.1"
+ }
+ },
+ "node_modules/@tiptap/extension-list-item": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.0.9.tgz",
+ "integrity": "sha512-K+ogk1BH/eYhsK9nSTXNdIXlxQcXzty6h1QFiZNr9XmaLk+q4NZFHR5FVz3EJ7QXyw+Gv/2FQn+T2Q/GpbMxZQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/extension-list": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-ordered-list": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.0.9.tgz",
+ "integrity": "sha512-ACubdGc/y/rKPEgHTO7hDSg547wRRA+Es7c/rQgjrkpI///LBJQfixyUvNg2UNNPttNsavF/CUwhshCeo9MeBA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/extension-list": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-paragraph": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.0.9.tgz",
+ "integrity": "sha512-K5zGg4zLxxqAG0BgtRpLvKclYSGoSSuU1Fza0M5MwUgrFA0S2q4JnLB1czQ77S4pfb3hpScIe50fwJzZmIUEQw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-placeholder": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-3.0.9.tgz",
+ "integrity": "sha512-OgDVijDrNFDJpe/1/yMx6VFEmGBt0vE6ZWw5kGkM4NVfOxhRvv6mSZXio269dc9oBSjmyTISKaI1JAYVCfyJIw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/extensions": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-strike": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.0.9.tgz",
+ "integrity": "sha512-2TBQ9P/FGe+/34ckfwP+eCdb4vbxDVZ5qD0piDIR9Ws5QI5IdtW90pNO4roxiPeRdVFrhTbFPEIuL0tg4NQRmg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-text": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.0.9.tgz",
+ "integrity": "sha512-yWdz4aW1nu5YGcinxfu3FXiwMnP/7jp+s7dFXhq9m/6zhDUD2+qyUwhJfIU4Tcz+BGdVHqoNgOA3QXLMA6jyFA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extension-underline": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.0.9.tgz",
+ "integrity": "sha512-xLR5NbnxlEJmvfb4Aj8wCbTmh/ycnPsSDeP8+TAsdAYxypSA6BP6G0t4d4NWreqAq+tq6QV6Eh0+YDN0G1VZxw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.0.9"
+ }
+ },
+ "node_modules/@tiptap/extensions": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.4.1.tgz",
+ "integrity": "sha512-OFqcI2NwFm0pzik7yyaF/05d/j4ED3UNRVcjqwU+LdHCm7NKOChEuuyMKcqx8G6DNe9419wyKbB9fy6ykLX1lA==",
+ "peer": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.4.1",
+ "@tiptap/pm": "^3.4.1"
+ }
+ },
+ "node_modules/@tiptap/pm": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.4.1.tgz",
+ "integrity": "sha512-fI5WjxY9NjHdNNlfYuvQ7WBjr5LLTOHg5LQ5/n/2RTbOYwTrhmKpAJiVVFFHB6BdmOF399MtKL1GyEflkln4KQ==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-changeset": "^2.3.0",
+ "prosemirror-collab": "^1.3.1",
+ "prosemirror-commands": "^1.6.2",
+ "prosemirror-dropcursor": "^1.8.1",
+ "prosemirror-gapcursor": "^1.3.2",
+ "prosemirror-history": "^1.4.1",
+ "prosemirror-inputrules": "^1.4.0",
+ "prosemirror-keymap": "^1.2.2",
+ "prosemirror-markdown": "^1.13.1",
+ "prosemirror-menu": "^1.2.4",
+ "prosemirror-model": "^1.24.1",
+ "prosemirror-schema-basic": "^1.2.3",
+ "prosemirror-schema-list": "^1.5.0",
+ "prosemirror-state": "^1.4.3",
+ "prosemirror-tables": "^1.6.4",
+ "prosemirror-trailing-node": "^3.0.0",
+ "prosemirror-transform": "^1.10.2",
+ "prosemirror-view": "^1.38.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ }
+ },
+ "node_modules/@tiptap/vue-3": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@tiptap/vue-3/-/vue-3-3.0.9.tgz",
+ "integrity": "sha512-IEhddTn2M0LbatFGkBPxfdbs+kL+xVC2GgYWWxvR/44ptXpKV4axtlH42nqh7sLj4DSBfP9jRlU6U0n6zdeMGg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "optionalDependencies": {
+ "@tiptap/extension-bubble-menu": "^3.0.9",
+ "@tiptap/extension-floating-menu": "^3.0.9"
+ },
+ "peerDependencies": {
+ "@floating-ui/dom": "^1.0.0",
+ "@tiptap/core": "^3.0.9",
+ "@tiptap/pm": "^3.0.9",
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/@trysound/sax": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
+ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/@types/aria-query": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
+ "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
+ "dev": true
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
+ "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
+ "dev": true,
+ "dependencies": {
+ "@types/deep-eql": "*"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true
+ },
+ "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==",
+ "devOptional": true
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "peer": true
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "peer": true,
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "peer": true
+ },
+ "node_modules/@unhead/vue": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-2.0.14.tgz",
+ "integrity": "sha512-Ym9f+Kd2Afqek2FtUHvYvK+j2uZ2vbZ6Rr9NCnNGGBMdmafAuiZpT117YGyh0ARcueL6Znia0U8ySqPsnHOZIg==",
+ "dependencies": {
+ "hookable": "^5.5.3",
+ "unhead": "2.0.14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/harlan-zw"
+ },
+ "peerDependencies": {
+ "vue": ">=3.5.18"
+ }
+ },
+ "node_modules/@vee-validate/i18n": {
+ "version": "4.15.1",
+ "resolved": "https://registry.npmjs.org/@vee-validate/i18n/-/i18n-4.15.1.tgz",
+ "integrity": "sha512-6ogEyxkoTr7IZk4EAUT0rD3pr34Nw/YEToez/c0DSlI1/cBeOpunSmGmoYPh32pmd3imxFPEawCB7IyFvRJSAw=="
+ },
+ "node_modules/@vee-validate/rules": {
+ "version": "4.15.1",
+ "resolved": "https://registry.npmjs.org/@vee-validate/rules/-/rules-4.15.1.tgz",
+ "integrity": "sha512-2TGXq2MYt21nT8ysuxyFY/LBVQDcMPKn1hY0w3uIDmG333vzBkOtXAylmvrS93AsJ7N5coHMJjcCGG4JxCO2hQ==",
+ "dependencies": {
+ "vee-validate": "4.15.1"
+ }
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.1.tgz",
+ "integrity": "sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==",
+ "dev": true,
+ "dependencies": {
+ "@rolldown/pluginutils": "1.0.0-beta.29"
+ },
+ "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/@vitest/coverage-v8": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz",
+ "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.3.0",
+ "@bcoe/v8-coverage": "^1.0.2",
+ "ast-v8-to-istanbul": "^0.3.3",
+ "debug": "^4.4.1",
+ "istanbul-lib-coverage": "^3.2.2",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-lib-source-maps": "^5.0.6",
+ "istanbul-reports": "^3.1.7",
+ "magic-string": "^0.30.17",
+ "magicast": "^0.3.5",
+ "std-env": "^3.9.0",
+ "test-exclude": "^7.0.1",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@vitest/browser": "3.2.4",
+ "vitest": "3.2.4"
+ },
+ "peerDependenciesMeta": {
+ "@vitest/browser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/coverage-v8/node_modules/magic-string": {
+ "version": "0.30.18",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
+ "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
+ "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
+ "dev": true,
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz",
+ "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==",
+ "dev": true,
+ "dependencies": {
+ "@vitest/spy": "3.2.4",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.17"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/mocker/node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/@vitest/mocker/node_modules/magic-string": {
+ "version": "0.30.18",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
+ "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
+ "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
+ "dev": true,
+ "dependencies": {
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz",
+ "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
+ "dev": true,
+ "dependencies": {
+ "@vitest/utils": "3.2.4",
+ "pathe": "^2.0.3",
+ "strip-literal": "^3.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz",
+ "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
+ "dev": true,
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot/node_modules/magic-string": {
+ "version": "0.30.18",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
+ "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
+ "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
+ "dev": true,
+ "dependencies": {
+ "tinyspy": "^4.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
+ "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
+ "dev": true,
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "loupe": "^3.1.4",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vue/babel-helper-vue-jsx-merge-props": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz",
+ "integrity": "sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==",
+ "dev": true
+ },
+ "node_modules/@vue/babel-helper-vue-transform-on": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz",
+ "integrity": "sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==",
+ "dev": true
+ },
+ "node_modules/@vue/babel-plugin-jsx": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz",
+ "integrity": "sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.0",
+ "@babel/types": "^7.28.2",
+ "@vue/babel-helper-vue-transform-on": "1.5.0",
+ "@vue/babel-plugin-resolve-type": "1.5.0",
+ "@vue/shared": "^3.5.18"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/babel-plugin-resolve-type": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz",
+ "integrity": "sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/parser": "^7.28.0",
+ "@vue/compiler-sfc": "^3.5.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/babel-plugin-transform-vue-jsx": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.4.0.tgz",
+ "integrity": "sha512-Fmastxw4MMx0vlgLS4XBX0XiBbUFzoMGeVXuMV08wyOfXdikAFqBTuYPR0tlk+XskL19EzHc39SgjrPGY23JnA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "@babel/plugin-syntax-jsx": "^7.2.0",
+ "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
+ "html-tags": "^2.0.0",
+ "lodash.kebabcase": "^4.1.1",
+ "svg-tags": "^1.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/babel-preset-app": {
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-5.0.9.tgz",
+ "integrity": "sha512-0rKOF4s/AhaRMJLybxOCgXfwtYhO3pwDSL/q/W8wRs1LzmHAc77FyTXWlun6VyKiSKwSdtH7CvOiWqq+DfofdA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.12.16",
+ "@babel/helper-compilation-targets": "^7.12.16",
+ "@babel/helper-module-imports": "^7.12.13",
+ "@babel/plugin-proposal-class-properties": "^7.12.13",
+ "@babel/plugin-proposal-decorators": "^7.12.13",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-jsx": "^7.12.13",
+ "@babel/plugin-transform-runtime": "^7.12.15",
+ "@babel/preset-env": "^7.12.16",
+ "@babel/runtime": "^7.12.13",
+ "@vue/babel-plugin-jsx": "^1.0.3",
+ "@vue/babel-preset-jsx": "^1.1.2",
+ "babel-plugin-dynamic-import-node": "^2.3.3",
+ "core-js": "^3.8.3",
+ "core-js-compat": "^3.8.3",
+ "semver": "^7.3.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "*",
+ "core-js": "^3",
+ "vue": "^2 || ^3.2.13"
+ },
+ "peerDependenciesMeta": {
+ "core-js": {
+ "optional": true
+ },
+ "vue": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/babel-preset-app/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@vue/babel-preset-jsx": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.4.0.tgz",
+ "integrity": "sha512-QmfRpssBOPZWL5xw7fOuHNifCQcNQC1PrOo/4fu6xlhlKJJKSA3HqX92Nvgyx8fqHZTUGMPHmFA+IDqwXlqkSA==",
+ "dev": true,
+ "dependencies": {
+ "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
+ "@vue/babel-plugin-transform-vue-jsx": "^1.4.0",
+ "@vue/babel-sugar-composition-api-inject-h": "^1.4.0",
+ "@vue/babel-sugar-composition-api-render-instance": "^1.4.0",
+ "@vue/babel-sugar-functional-vue": "^1.4.0",
+ "@vue/babel-sugar-inject-h": "^1.4.0",
+ "@vue/babel-sugar-v-model": "^1.4.0",
+ "@vue/babel-sugar-v-on": "^1.4.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0",
+ "vue": "*"
+ },
+ "peerDependenciesMeta": {
+ "vue": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/babel-sugar-composition-api-inject-h": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.4.0.tgz",
+ "integrity": "sha512-VQq6zEddJHctnG4w3TfmlVp5FzDavUSut/DwR0xVoe/mJKXyMcsIibL42wPntozITEoY90aBV0/1d2KjxHU52g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/babel-sugar-composition-api-render-instance": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.4.0.tgz",
+ "integrity": "sha512-6ZDAzcxvy7VcnCjNdHJ59mwK02ZFuP5CnucloidqlZwVQv5CQLijc3lGpR7MD3TWFi78J7+a8J56YxbCtHgT9Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/babel-sugar-functional-vue": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.4.0.tgz",
+ "integrity": "sha512-lTEB4WUFNzYt2In6JsoF9sAYVTo84wC4e+PoZWSgM6FUtqRJz7wMylaEhSRgG71YF+wfLD6cc9nqVeXN2rwBvw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/babel-sugar-inject-h": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.4.0.tgz",
+ "integrity": "sha512-muwWrPKli77uO2fFM7eA3G1lAGnERuSz2NgAxuOLzrsTlQl8W4G+wwbM4nB6iewlKbwKRae3nL03UaF5ffAPMA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/babel-sugar-v-model": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.4.0.tgz",
+ "integrity": "sha512-0t4HGgXb7WHYLBciZzN5s0Hzqan4Ue+p/3FdQdcaHAb7s5D9WZFGoSxEZHrR1TFVZlAPu1bejTKGeAzaaG3NCQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-jsx": "^7.2.0",
+ "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
+ "@vue/babel-plugin-transform-vue-jsx": "^1.4.0",
+ "camelcase": "^5.0.0",
+ "html-tags": "^2.0.0",
+ "svg-tags": "^1.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/babel-sugar-v-on": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.4.0.tgz",
+ "integrity": "sha512-m+zud4wKLzSKgQrWwhqRObWzmTuyzl6vOP7024lrpeJM4x2UhQtRDLgYjXAw9xBXjCwS0pP9kXjg91F9ZNo9JA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-jsx": "^7.2.0",
+ "@vue/babel-plugin-transform-vue-jsx": "^1.4.0",
+ "camelcase": "^5.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/compat": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compat/-/compat-3.5.21.tgz",
+ "integrity": "sha512-uakoBcdx+7qb1dv+rYJ4Bgex7fz7guWrr5Iv0gHCqdl7ijyNXyDJ0BqpZrvxDej82O+113i5LGZmIxfVMyPy/Q==",
+ "dependencies": {
+ "@babel/parser": "^7.28.3",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ },
+ "peerDependencies": {
+ "vue": "3.5.21"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.21.tgz",
+ "integrity": "sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw==",
+ "dependencies": {
+ "@babel/parser": "^7.28.3",
+ "@vue/shared": "3.5.21",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.21.tgz",
+ "integrity": "sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ==",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.21",
+ "@vue/shared": "3.5.21"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.21.tgz",
+ "integrity": "sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ==",
+ "dependencies": {
+ "@babel/parser": "^7.28.3",
+ "@vue/compiler-core": "3.5.21",
+ "@vue/compiler-dom": "3.5.21",
+ "@vue/compiler-ssr": "3.5.21",
+ "@vue/shared": "3.5.21",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.18",
+ "postcss": "^8.5.6",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-sfc/node_modules/magic-string": {
+ "version": "0.30.18",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
+ "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.21.tgz",
+ "integrity": "sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.21",
+ "@vue/shared": "3.5.21"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz",
+ "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.7"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz",
+ "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.7",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz",
+ "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/eslint-config-prettier": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-10.2.0.tgz",
+ "integrity": "sha512-GL3YBLwv/+b86yHcNNfPJxOTtVFJ4Mbc9UU3zR+KVoG7SwGTjPT+32fXamscNumElhcpXW3mT0DgzS9w32S7Bw==",
+ "dev": true,
+ "dependencies": {
+ "eslint-config-prettier": "^10.0.1",
+ "eslint-plugin-prettier": "^5.2.2"
+ },
+ "peerDependencies": {
+ "eslint": ">= 8.21.0",
+ "prettier": ">= 3.0.0"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.21.tgz",
+ "integrity": "sha512-3ah7sa+Cwr9iiYEERt9JfZKPw4A2UlbY8RbbnH2mGCE8NwHkhmlZt2VsH0oDA3P08X3jJd29ohBDtX+TbD9AsA==",
+ "dependencies": {
+ "@vue/shared": "3.5.21"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.21.tgz",
+ "integrity": "sha512-+DplQlRS4MXfIf9gfD1BOJpk5RSyGgGXD/R+cumhe8jdjUcq/qlxDawQlSI8hCKupBlvM+3eS1se5xW+SuNAwA==",
+ "dependencies": {
+ "@vue/reactivity": "3.5.21",
+ "@vue/shared": "3.5.21"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.21.tgz",
+ "integrity": "sha512-3M2DZsOFwM5qI15wrMmNF5RJe1+ARijt2HM3TbzBbPSuBHOQpoidE+Pa+XEaVN+czbHf81ETRoG1ltztP2em8w==",
+ "dependencies": {
+ "@vue/reactivity": "3.5.21",
+ "@vue/runtime-core": "3.5.21",
+ "@vue/shared": "3.5.21",
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.21.tgz",
+ "integrity": "sha512-qr8AqgD3DJPJcGvLcJKQo2tAc8OnXRcfxhOJCPF+fcfn5bBGz7VCcO7t+qETOPxpWK1mgysXvVT/j+xWaHeMWA==",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.21",
+ "@vue/shared": "3.5.21"
+ },
+ "peerDependencies": {
+ "vue": "3.5.21"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.21.tgz",
+ "integrity": "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw=="
+ },
+ "node_modules/@vue/test-utils": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.6.tgz",
+ "integrity": "sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==",
+ "dev": true,
+ "dependencies": {
+ "js-beautify": "^1.14.9",
+ "vue-component-type-helpers": "^2.0.0"
+ }
+ },
+ "node_modules/@vuetify/loader-shared": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@vuetify/loader-shared/-/loader-shared-2.1.1.tgz",
+ "integrity": "sha512-jSZTzTYaoiv8iwonFCVZQ0YYX/M+Uyl4ng+C4egMJT0Hcmh9gIxJL89qfZICDeo3g0IhqrvipW2FFKKRDMtVcA==",
+ "devOptional": true,
+ "dependencies": {
+ "upath": "^2.0.1"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0",
+ "vuetify": "^3.0.0"
+ }
+ },
+ "node_modules/@zxcvbn-ts/core": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@zxcvbn-ts/core/-/core-3.0.4.tgz",
+ "integrity": "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==",
+ "dependencies": {
+ "fastest-levenshtein": "1.0.16"
+ }
+ },
+ "node_modules/@zxcvbn-ts/language-common": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz",
+ "integrity": "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw=="
+ },
+ "node_modules/@zxcvbn-ts/language-de": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-de/-/language-de-3.0.2.tgz",
+ "integrity": "sha512-CPl2314qWtnJl4EkeEqFbL4unP6yEAHO976ER+df8CQcKsF4FxdZYEahkleWU66dhNI2VKnmJKNMzq8QtHQKcw=="
+ },
+ "node_modules/@zxcvbn-ts/language-en": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-en/-/language-en-3.0.2.tgz",
+ "integrity": "sha512-Zp+zL+I6Un2Bj0tRXNs6VUBq3Djt+hwTwUz4dkt2qgsQz47U0/XthZ4ULrT/RxjwJRl5LwiaKOOZeOtmixHnjg=="
+ },
+ "node_modules/@zxcvbn-ts/language-fr": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-fr/-/language-fr-3.0.2.tgz",
+ "integrity": "sha512-Tj9jS/Z8mNBAD21pn8Mp4O86CPrwImysO1fM3DG+fsfk8W79/MDzqpFDBHiqpu69Uo3LPPctMHEEteakFWt4Qg=="
+ },
+ "node_modules/@zxcvbn-ts/language-it": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-it/-/language-it-3.0.2.tgz",
+ "integrity": "sha512-VMC7JJZ855wPhklADB43kxRVWpbWIsVWjvrC8EACBoNqcFyk2DLD+WeoAtazM08ovM0wi/mN+wc0Sa5iFtOtvQ=="
+ },
+ "node_modules/abbrev": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/abs-svg-path": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz",
+ "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA=="
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz",
+ "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==",
+ "dev": true,
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "node_modules/aria-query": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
+ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
+ "dev": true,
+ "dependencies": {
+ "dequal": "^2.0.3"
+ }
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/assert": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz",
+ "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "is-nan": "^1.3.2",
+ "object-is": "^1.1.5",
+ "object.assign": "^4.1.4",
+ "util": "^0.12.5"
+ }
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/ast-v8-to-istanbul": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.5.tgz",
+ "integrity": "sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.30",
+ "estree-walker": "^3.0.3",
+ "js-tokens": "^9.0.1"
+ }
+ },
+ "node_modules/ast-v8-to-istanbul/node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
+ "node_modules/atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "devOptional": true,
+ "bin": {
+ "atob": "bin/atob.js"
+ },
+ "engines": {
+ "node": ">= 4.5.0"
+ }
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.21",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
+ "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "browserslist": "^4.24.4",
+ "caniuse-lite": "^1.0.30001702",
+ "fraction.js": "^4.3.7",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.1.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
+ "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.4",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "dependencies": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz",
+ "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.27.7",
+ "@babel/helper-define-polyfill-provider": "^0.6.5",
+ "semver": "^6.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz",
+ "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.5",
+ "core-js-compat": "^3.43.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz",
+ "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-require-context-hook": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-require-context-hook/-/babel-plugin-require-context-hook-1.0.0.tgz",
+ "integrity": "sha512-EMZD1563QUqLhzrqcThk759RhuNVX/ZJdrtGK6drwzgvnR+ARjWyXIHPbu+tUNaMGtPz/gQeAM2M6VUw2UiUeA==",
+ "dev": true
+ },
+ "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==",
+ "devOptional": true
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/bidi-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
+ "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
+ "dependencies": {
+ "require-from-string": "^2.0.2"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/birpc": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.5.0.tgz",
+ "integrity": "sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "devOptional": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "devOptional": true,
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/brotli": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
+ "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==",
+ "dependencies": {
+ "base64-js": "^1.1.2"
+ }
+ },
+ "node_modules/browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dependencies": {
+ "pako": "~1.0.5"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.25.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz",
+ "integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001737",
+ "electron-to-chromium": "^1.5.211",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001741",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz",
+ "integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/chai": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz",
+ "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==",
+ "dev": true,
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz",
+ "integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==",
+ "dev": true,
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "encoding-sniffer": "^0.2.1",
+ "htmlparser2": "^10.0.0",
+ "parse5": "^7.3.0",
+ "parse5-htmlparser2-tree-adapter": "^7.1.0",
+ "parse5-parser-stream": "^7.1.2",
+ "undici": "^7.12.0",
+ "whatwg-mimetype": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.18.1"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cheerio/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/htmlparser2": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
+ "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.1",
+ "entities": "^6.0.0"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "devOptional": true,
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
+ "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+ "dev": true,
+ "dependencies": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/color-string": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true
+ },
+ "node_modules/colorjs.io": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz",
+ "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw=="
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/comlink": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz",
+ "integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g=="
+ },
+ "node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "devOptional": true
+ },
+ "node_modules/confbox": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
+ "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==",
+ "dev": true
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "node_modules/copy-anything": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
+ "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
+ "dependencies": {
+ "is-what": "^4.1.8"
+ },
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/core-js": {
+ "version": "3.45.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.1.tgz",
+ "integrity": "sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.45.1",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz",
+ "integrity": "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.25.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/crelt": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
+ "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
+ "peer": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-js": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
+ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
+ },
+ "node_modules/css": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
+ "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
+ "devOptional": true,
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.6.0"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
+ "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+ "dev": true,
+ "dependencies": {
+ "mdn-data": "2.0.30",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css.escape": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+ "dev": true
+ },
+ "node_modules/css/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssfontparser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz",
+ "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==",
+ "dev": true
+ },
+ "node_modules/csso": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+ "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
+ "dev": true,
+ "dependencies": {
+ "css-tree": "~2.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/css-tree": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+ "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
+ "dev": true,
+ "dependencies": {
+ "mdn-data": "2.0.28",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/mdn-data": {
+ "version": "2.0.28",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
+ "dev": true
+ },
+ "node_modules/cssstyle": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
+ "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
+ "dev": true,
+ "dependencies": {
+ "@asamuzakjp/css-color": "^3.2.0",
+ "rrweb-cssom": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "node_modules/data-urls": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.13",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
+ "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
+ },
+ "node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "devOptional": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "dev": true
+ },
+ "node_modules/decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-equal": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
+ "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
+ "dev": true,
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "call-bind": "^1.0.5",
+ "es-get-iterator": "^1.1.3",
+ "get-intrinsic": "^1.2.2",
+ "is-arguments": "^1.1.1",
+ "is-array-buffer": "^3.0.2",
+ "is-date-object": "^1.0.5",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.2",
+ "isarray": "^2.0.5",
+ "object-is": "^1.1.5",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.4",
+ "regexp.prototype.flags": "^1.5.1",
+ "side-channel": "^1.0.4",
+ "which-boxed-primitive": "^1.0.2",
+ "which-collection": "^1.0.1",
+ "which-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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==",
+ "optional": true,
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/dfa": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz",
+ "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q=="
+ },
+ "node_modules/dom-accessibility-api": {
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
+ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
+ "dev": true
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "dev": true,
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true
+ },
+ "node_modules/editorconfig": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
+ "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
+ "dev": true,
+ "dependencies": {
+ "@one-ini/wasm": "0.1.1",
+ "commander": "^10.0.0",
+ "minimatch": "9.0.1",
+ "semver": "^7.5.3"
+ },
+ "bin": {
+ "editorconfig": "bin/editorconfig"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/editorconfig/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,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/editorconfig/node_modules/minimatch": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+ "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/editorconfig/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.214",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.214.tgz",
+ "integrity": "sha512-TpvUNdha+X3ybfU78NoQatKvQEm1oq3lf2QbnmCEdw+Bd9RuIAY+hJTvq1avzHM0f7EJfnH3vbCnbzKzisc/9Q==",
+ "dev": true
+ },
+ "node_modules/emoji-regex": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
+ "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="
+ },
+ "node_modules/encoding-sniffer": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
+ "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
+ "dev": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.3",
+ "whatwg-encoding": "^3.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.3",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
+ "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-get-iterator": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
+ "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.1.3",
+ "has-symbols": "^1.0.3",
+ "is-arguments": "^1.1.1",
+ "is-map": "^2.0.2",
+ "is-set": "^2.0.2",
+ "is-string": "^1.0.7",
+ "isarray": "^2.0.5",
+ "stop-iteration-iterator": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
+ "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==",
+ "devOptional": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.9",
+ "@esbuild/android-arm": "0.25.9",
+ "@esbuild/android-arm64": "0.25.9",
+ "@esbuild/android-x64": "0.25.9",
+ "@esbuild/darwin-arm64": "0.25.9",
+ "@esbuild/darwin-x64": "0.25.9",
+ "@esbuild/freebsd-arm64": "0.25.9",
+ "@esbuild/freebsd-x64": "0.25.9",
+ "@esbuild/linux-arm": "0.25.9",
+ "@esbuild/linux-arm64": "0.25.9",
+ "@esbuild/linux-ia32": "0.25.9",
+ "@esbuild/linux-loong64": "0.25.9",
+ "@esbuild/linux-mips64el": "0.25.9",
+ "@esbuild/linux-ppc64": "0.25.9",
+ "@esbuild/linux-riscv64": "0.25.9",
+ "@esbuild/linux-s390x": "0.25.9",
+ "@esbuild/linux-x64": "0.25.9",
+ "@esbuild/netbsd-arm64": "0.25.9",
+ "@esbuild/netbsd-x64": "0.25.9",
+ "@esbuild/openbsd-arm64": "0.25.9",
+ "@esbuild/openbsd-x64": "0.25.9",
+ "@esbuild/openharmony-arm64": "0.25.9",
+ "@esbuild/sunos-x64": "0.25.9",
+ "@esbuild/win32-arm64": "0.25.9",
+ "@esbuild/win32-ia32": "0.25.9",
+ "@esbuild/win32-x64": "0.25.9"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.32.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz",
+ "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.0",
+ "@eslint/core": "^0.15.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.32.0",
+ "@eslint/plugin-kit": "^0.3.4",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-compat-utils": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz",
+ "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/eslint-compat-utils/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.1.8",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
+ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
+ "dev": true,
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-config-prettier"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-es-x": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz",
+ "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/ota-meshi",
+ "https://opencollective.com/eslint"
+ ],
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.1.2",
+ "@eslint-community/regexpp": "^4.11.0",
+ "eslint-compat-utils": "^0.5.1"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=8"
+ }
+ },
+ "node_modules/eslint-plugin-local-rules": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-local-rules/-/eslint-plugin-local-rules-3.0.2.tgz",
+ "integrity": "sha512-IWME7GIYHXogTkFsToLdBCQVJ0U4kbSuVyDT+nKoR4UgtnVrrVeNWuAZkdEu1nxkvi9nsPccGehEEF6dgA28IQ==",
+ "dev": true
+ },
+ "node_modules/eslint-plugin-n": {
+ "version": "17.21.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.21.3.tgz",
+ "integrity": "sha512-MtxYjDZhMQgsWRm/4xYLL0i2EhusWT7itDxlJ80l1NND2AL2Vi5Mvneqv/ikG9+zpran0VsVRXTEHrpLmUZRNw==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.5.0",
+ "enhanced-resolve": "^5.17.1",
+ "eslint-plugin-es-x": "^7.8.0",
+ "get-tsconfig": "^4.8.1",
+ "globals": "^15.11.0",
+ "globrex": "^0.1.2",
+ "ignore": "^5.3.2",
+ "semver": "^7.6.3",
+ "ts-declaration-location": "^1.0.6"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": ">=8.23.0"
+ }
+ },
+ "node_modules/eslint-plugin-n/node_modules/globals": {
+ "version": "15.15.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
+ "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-plugin-n/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.3.tgz",
+ "integrity": "sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==",
+ "dev": true,
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0",
+ "synckit": "^0.11.7"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-plugin-prettier"
+ },
+ "peerDependencies": {
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
+ "prettier": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-promise": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz",
+ "integrity": "sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-vue": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.4.0.tgz",
+ "integrity": "sha512-K6tP0dW8FJVZLQxa2S7LcE1lLw3X8VvB3t887Q6CLrFVxHYBXGANbXvwNzYIu6Ughx1bSJ5BDT0YB3ybPT39lw==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "natural-compare": "^1.4.0",
+ "nth-check": "^2.1.1",
+ "postcss-selector-parser": "^6.0.15",
+ "semver": "^7.6.3",
+ "xml-name-validator": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^7.0.0 || ^8.0.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "vue-eslint-parser": "^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@typescript-eslint/parser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-vue-scoped-css": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue-scoped-css/-/eslint-plugin-vue-scoped-css-2.11.0.tgz",
+ "integrity": "sha512-rrJgLY8iroTIUMSyxhyhJzFcRxABbk3gFrOLkl41F9G1VBqNNpDShyf6PmDoBEWDk07/bJlnqYlvnQ3giUrRYQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "eslint-compat-utils": "^0.6.5",
+ "lodash": "^4.17.21",
+ "postcss": "^8.4.31",
+ "postcss-safe-parser": "^6.0.0",
+ "postcss-scss": "^4.0.3",
+ "postcss-selector-parser": "^7.0.0",
+ "postcss-styl": "^0.12.0"
+ },
+ "engines": {
+ "node": "^12.22 || ^14.17 || >=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ota-meshi"
+ },
+ "peerDependencies": {
+ "eslint": ">=5.0.0",
+ "vue-eslint-parser": ">=7.1.0"
+ }
+ },
+ "node_modules/eslint-plugin-vue-scoped-css/node_modules/eslint-compat-utils": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz",
+ "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-vue-scoped-css/node_modules/postcss-selector-parser": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-plugin-vue-scoped-css/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-plugin-vue/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esquery/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+ "dev": true
+ },
+ "node_modules/expect-type": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz",
+ "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/exsolve": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz",
+ "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==",
+ "dev": true
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
+ },
+ "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==",
+ "devOptional": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true
+ },
+ "node_modules/flush-promises": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/flush-promises/-/flush-promises-1.0.2.tgz",
+ "integrity": "sha512-G0sYfLQERwKz4+4iOZYQEZVpOt9zQrlItIxQAAYAWpfby3gbHrx0osCHz5RLl/XoXevXk0xoN4hDFky/VV9TrA==",
+ "dev": true
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fontkit": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.4.tgz",
+ "integrity": "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.12",
+ "brotli": "^1.3.2",
+ "clone": "^2.1.2",
+ "dfa": "^1.2.0",
+ "fast-deep-equal": "^3.1.3",
+ "restructure": "^3.0.0",
+ "tiny-inflate": "^1.0.3",
+ "unicode-properties": "^1.4.0",
+ "unicode-trie": "^2.0.0"
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "devOptional": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.1.tgz",
+ "integrity": "sha512-R1QfovbPsKmosqTnPoRFiJ7CF9MLRgb53ChvMZm+r4p76/+8yKDy17qLL2PKInORy2RkZZekuK0efYgmzTkXyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
+ "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
+ "dev": true,
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob": {
+ "version": "9.3.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
+ "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "minimatch": "^8.0.2",
+ "minipass": "^4.2.4",
+ "path-scurry": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz",
+ "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.3.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz",
+ "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globrex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
+ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
+ "dev": true
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ },
+ "node_modules/hal-json-normalizer": {
+ "version": "5.0.0-alpha.0",
+ "resolved": "https://registry.npmjs.org/hal-json-normalizer/-/hal-json-normalizer-5.0.0-alpha.0.tgz",
+ "integrity": "sha512-c/7LnUA63PZ/i+Jx6ueUNzTfr05cWzaiFIO2/aoQ8LCIpY37INfflHtYTlQiSi9FfAQDI/CTeExUrbU6U1uEnw==",
+ "dependencies": {
+ "lodash-es": "^4.17.15"
+ },
+ "engines": {
+ "node": ">= 18.17.0"
+ }
+ },
+ "node_modules/hal-json-vuex": {
+ "version": "3.0.0-alpha.10",
+ "resolved": "https://registry.npmjs.org/hal-json-vuex/-/hal-json-vuex-3.0.0-alpha.10.tgz",
+ "integrity": "sha512-2uKuvoMXKKFwtbNcs09LU7hOJEqWXNx0yTST0VKw9osYMIT0zQBdllIJUnK10oxtOSHYhmzFs7cF9LwEttSgyw==",
+ "dependencies": {
+ "hal-json-normalizer": "^5.0.0-alpha.0",
+ "url-template": "^3.1.1",
+ "vue-demi": "^0.14.10"
+ },
+ "engines": {
+ "node": ">=18.17.0"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^2.0.0 || >=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/hal-json-vuex/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
+ },
+ "node_modules/hsl-to-hex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hsl-to-hex/-/hsl-to-hex-1.0.0.tgz",
+ "integrity": "sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==",
+ "dependencies": {
+ "hsl-to-rgb-for-reals": "^1.1.0"
+ }
+ },
+ "node_modules/hsl-to-rgb-for-reals": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/hsl-to-rgb-for-reals/-/hsl-to-rgb-for-reals-1.1.1.tgz",
+ "integrity": "sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg=="
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-encoding": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "node_modules/html-tags": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz",
+ "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
+ "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.1.0",
+ "entities": "^4.5.0"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/http-proxy-agent/node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/hyphen": {
+ "version": "1.10.6",
+ "resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.10.6.tgz",
+ "integrity": "sha512-fXHXcGFTXOvZTSkPJuGOQf5Lv5T/R2itiiCVPg9LxAje5D00O0pP83yJShFq5V89Ly//Gt6acj7z8pbBr34stw=="
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "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==",
+ "devOptional": true
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "devOptional": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "node_modules/inter-ui": {
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/inter-ui/-/inter-ui-3.19.3.tgz",
+ "integrity": "sha512-5FG9fjuYOXocIfjzcCBhICL5cpvwEetseL3FU6tP3d6Bn7g8wODhB+I9RNGRTizCT7CUG4GOK54OPxqq3msQgg==",
+ "license": "OFL-1.1"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-arguments": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
+ "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "devOptional": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-nan": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz",
+ "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-url": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+ "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-what": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
+ "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jay-peg": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/jay-peg/-/jay-peg-1.1.1.tgz",
+ "integrity": "sha512-D62KEuBxz/ip2gQKOEhk/mx14o7eiFRaU+VNNSP4MOiIkwb/D6B3G1Mfas7C/Fit8EsSV2/IWjZElx/Gs6A4ww==",
+ "dependencies": {
+ "restructure": "^3.0.0"
+ }
+ },
+ "node_modules/jest-canvas-mock": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.5.2.tgz",
+ "integrity": "sha512-vgnpPupjOL6+L5oJXzxTxFrlGEIbHdZqFU+LFNdtLxZ3lRDCl17FlTMM7IatoRQkrcyOTMlDinjUguqmQ6bR2A==",
+ "dev": true,
+ "dependencies": {
+ "cssfontparser": "^1.2.1",
+ "moo-color": "^1.0.2"
+ }
+ },
+ "node_modules/jest-serializer-vue-tjw": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jest-serializer-vue-tjw/-/jest-serializer-vue-tjw-4.0.0.tgz",
+ "integrity": "sha512-VZv8shuNyPbXx96PkKVOAHGPlim86Tl8ie2ehdsjJT/dfQT0fsPl0UtBJdphK6DUAGBSIfltgPlQEYXDwW2EmQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "cheerio": "^1.0.0-rc.3",
+ "htmlparser2": "^9.0.0",
+ "js-beautify": "^1.14.8",
+ "lodash.clonedeep": "^4.5.0"
+ },
+ "engines": {
+ "node": ">=8.3.0",
+ "npm": ">=5.0.0"
+ }
+ },
+ "node_modules/js-beautify": {
+ "version": "1.15.4",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
+ "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==",
+ "dev": true,
+ "dependencies": {
+ "config-chain": "^1.1.13",
+ "editorconfig": "^1.0.4",
+ "glob": "^10.4.2",
+ "js-cookie": "^3.0.5",
+ "nopt": "^7.2.1"
+ },
+ "bin": {
+ "css-beautify": "js/bin/css-beautify.js",
+ "html-beautify": "js/bin/html-beautify.js",
+ "js-beautify": "js/bin/js-beautify.js"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/js-beautify/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,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/js-beautify/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-beautify/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,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-beautify/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/js-cookie": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "26.1.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz",
+ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
+ "dev": true,
+ "dependencies": {
+ "cssstyle": "^4.2.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.5.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.6",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.16",
+ "parse5": "^7.2.1",
+ "rrweb-cssom": "^0.8.0",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^5.1.1",
+ "w3c-xmlserializer": "^5.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.1.1",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "canvas": "^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jsdom/node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/jsdom/node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/jsdom/node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/linebreak": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz",
+ "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==",
+ "dependencies": {
+ "base64-js": "0.0.8",
+ "unicode-trie": "^2.0.0"
+ }
+ },
+ "node_modules/linebreak/node_modules/base64-js": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
+ "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "dependencies": {
+ "uc.micro": "^2.0.0"
+ }
+ },
+ "node_modules/lint-staged": {
+ "version": "16.1.4",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.4.tgz",
+ "integrity": "sha512-xy7rnzQrhTVGKMpv6+bmIA3C0yET31x8OhKBYfvGo0/byeZ6E0BjGARrir3Kg/RhhYHutpsi01+2J5IpfVoueA==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^5.4.1",
+ "commander": "^14.0.0",
+ "debug": "^4.4.1",
+ "lilconfig": "^3.1.3",
+ "listr2": "^9.0.1",
+ "micromatch": "^4.0.8",
+ "nano-spawn": "^1.0.2",
+ "pidtree": "^0.6.0",
+ "string-argv": "^0.3.2",
+ "yaml": "^2.8.0"
+ },
+ "bin": {
+ "lint-staged": "bin/lint-staged.js"
+ },
+ "engines": {
+ "node": ">=20.17"
+ },
+ "funding": {
+ "url": "https://opencollective.com/lint-staged"
+ }
+ },
+ "node_modules/lint-staged/node_modules/chalk": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz",
+ "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/lint-staged/node_modules/commander": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz",
+ "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==",
+ "dev": true,
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.3.tgz",
+ "integrity": "sha512-0aeh5HHHgmq1KRdMMDHfhMWQmIT/m7nRDTlxlFqni2Sp0had9baqsjJRvDGdlvgd6NmPE0nPloOipiQJGFtTHQ==",
+ "dev": true,
+ "dependencies": {
+ "cli-truncate": "^4.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
+ "log-update": "^6.1.0",
+ "rfdc": "^1.4.1",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/local-pkg": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
+ "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==",
+ "dev": true,
+ "dependencies": {
+ "mlly": "^1.7.4",
+ "pkg-types": "^2.3.0",
+ "quansync": "^0.2.11"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+ },
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+ "dev": true
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+ "dev": true
+ },
+ "node_modules/lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==",
+ "dev": true
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/lodash.sortedlastindex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortedlastindex/-/lodash.sortedlastindex-4.1.0.tgz",
+ "integrity": "sha512-s8xEQdsp2Tu5zUqVdFSe9C0kR8YlnAJYLqMdkh+pIRBRxF6/apWseLdHl3/+jv2I61dhPwtI/Ff+EqvCpc+N8w==",
+ "dev": true
+ },
+ "node_modules/log-update": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
+ "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^7.0.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^7.1.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+ "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+ "dev": true,
+ "dependencies": {
+ "get-east-asian-width": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz",
+ "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/loupe": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
+ "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/lz-string": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
+ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
+ "dev": true,
+ "bin": {
+ "lz-string": "bin/bin.js"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.15"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/magicast": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
+ "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.25.4",
+ "@babel/types": "^7.25.4",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/markdown-it": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
+ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
+ "peer": true,
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.0",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/mdn-data": {
+ "version": "2.0.30",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
+ "dev": true
+ },
+ "node_modules/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
+ "peer": true
+ },
+ "node_modules/media-engine": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/media-engine/-/media-engine-1.0.3.tgz",
+ "integrity": "sha512-aa5tG6sDoK+k70B9iEX1NeyfT8ObCKhNDs6lJVpwF6r8vhUfuKMslIcirq6HIUYuuUYLefcEQOn9bSBOvawtwg=="
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "devOptional": true,
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "devOptional": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
+ },
+ "node_modules/mlly": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
+ "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "pathe": "^2.0.3",
+ "pkg-types": "^1.3.1",
+ "ufo": "^1.6.1"
+ }
+ },
+ "node_modules/mlly/node_modules/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+ "dev": true
+ },
+ "node_modules/mlly/node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "dev": true,
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
+ }
+ },
+ "node_modules/moo-color": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz",
+ "integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "^1.1.4"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "devOptional": true
+ },
+ "node_modules/nano-spawn": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-1.0.3.tgz",
+ "integrity": "sha512-jtpsQDetTnvS2Ts1fiRdci5rx0VYws5jGyC+4IYOTnIQ/wwdf6JdomlHBwqC3bJYOvaKu0C2GSZ1A60anrYpaA==",
+ "dev": true,
+ "engines": {
+ "node": ">=20.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1"
+ }
+ },
+ "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"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/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==",
+ "optional": true
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-fetch/node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "dev": true
+ },
+ "node_modules/node-fetch/node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true
+ },
+ "node_modules/node-fetch/node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.20.tgz",
+ "integrity": "sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==",
+ "dev": true
+ },
+ "node_modules/nopt": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
+ "dev": true,
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-svg-path": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz",
+ "integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==",
+ "dependencies": {
+ "svg-arc-to-cubic-bezier": "^3.0.0"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.22",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz",
+ "integrity": "sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==",
+ "dev": true
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-is": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
+ "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "devOptional": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/orderedmap": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
+ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
+ "peer": true
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true
+ },
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-svg-path": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
+ "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
+ },
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "dev": true,
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+ "dev": true,
+ "dependencies": {
+ "domhandler": "^5.0.3",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-parser-stream": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+ "dev": true,
+ "dependencies": {
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true
+ },
+ "node_modules/path-scurry/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true
+ },
+ "node_modules/pathval": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pidtree": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
+ "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
+ "dev": true,
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/pkg-types": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
+ "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
+ "dev": true,
+ "dependencies": {
+ "confbox": "^0.2.2",
+ "exsolve": "^1.0.7",
+ "pathe": "^2.0.3"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-safe-parser": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
+ "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3.3"
+ }
+ },
+ "node_modules/postcss-scss": {
+ "version": "4.0.9",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz",
+ "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss-scss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.29"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-styl": {
+ "version": "0.12.3",
+ "resolved": "https://registry.npmjs.org/postcss-styl/-/postcss-styl-0.12.3.tgz",
+ "integrity": "sha512-8I7Cd8sxiEITIp32xBK4K/Aj1ukX6vuWnx8oY/oAH35NfQI4OZaY5nd68Yx8HeN5S49uhQ6DL0rNk0ZBu/TaLg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "fast-diff": "^1.2.0",
+ "lodash.sortedlastindex": "^4.1.0",
+ "postcss": "^7.0.27 || ^8.0.0",
+ "stylus": "^0.57.0"
+ },
+ "engines": {
+ "node": "^8.10.0 || ^10.13.0 || ^11.10.1 || >=12.13.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/stylus"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/prosemirror-changeset": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz",
+ "integrity": "sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-collab": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz",
+ "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-state": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-commands": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
+ "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.10.2"
+ }
+ },
+ "node_modules/prosemirror-dropcursor": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
+ "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0",
+ "prosemirror-view": "^1.1.0"
+ }
+ },
+ "node_modules/prosemirror-gapcursor": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz",
+ "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-keymap": "^1.0.0",
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-view": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-history": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz",
+ "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-state": "^1.2.2",
+ "prosemirror-transform": "^1.0.0",
+ "prosemirror-view": "^1.31.0",
+ "rope-sequence": "^1.3.0"
+ }
+ },
+ "node_modules/prosemirror-inputrules": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.0.tgz",
+ "integrity": "sha512-K0xJRCmt+uSw7xesnHmcn72yBGTbY45vm8gXI4LZXbx2Z0jwh5aF9xrGQgrVPu0WbyFVFF3E/o9VhJYz6SQWnA==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-keymap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
+ "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-state": "^1.0.0",
+ "w3c-keyname": "^2.2.0"
+ }
+ },
+ "node_modules/prosemirror-markdown": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.2.tgz",
+ "integrity": "sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==",
+ "peer": true,
+ "dependencies": {
+ "@types/markdown-it": "^14.0.0",
+ "markdown-it": "^14.0.0",
+ "prosemirror-model": "^1.25.0"
+ }
+ },
+ "node_modules/prosemirror-menu": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz",
+ "integrity": "sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==",
+ "peer": true,
+ "dependencies": {
+ "crelt": "^1.0.0",
+ "prosemirror-commands": "^1.0.0",
+ "prosemirror-history": "^1.0.0",
+ "prosemirror-state": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-model": {
+ "version": "1.25.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.3.tgz",
+ "integrity": "sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==",
+ "peer": true,
+ "dependencies": {
+ "orderedmap": "^2.0.0"
+ }
+ },
+ "node_modules/prosemirror-schema-basic": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz",
+ "integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-model": "^1.25.0"
+ }
+ },
+ "node_modules/prosemirror-schema-list": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
+ "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.7.3"
+ }
+ },
+ "node_modules/prosemirror-state": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz",
+ "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-transform": "^1.0.0",
+ "prosemirror-view": "^1.27.0"
+ }
+ },
+ "node_modules/prosemirror-tables": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.1.tgz",
+ "integrity": "sha512-DAgDoUYHCcc6tOGpLVPSU1k84kCUWTWnfWX3UDy2Delv4ryH0KqTD6RBI6k4yi9j9I8gl3j8MkPpRD/vWPZbug==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-keymap": "^1.2.2",
+ "prosemirror-model": "^1.25.0",
+ "prosemirror-state": "^1.4.3",
+ "prosemirror-transform": "^1.10.3",
+ "prosemirror-view": "^1.39.1"
+ }
+ },
+ "node_modules/prosemirror-trailing-node": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz",
+ "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==",
+ "peer": true,
+ "dependencies": {
+ "@remirror/core-constants": "3.0.0",
+ "escape-string-regexp": "^4.0.0"
+ },
+ "peerDependencies": {
+ "prosemirror-model": "^1.22.1",
+ "prosemirror-state": "^1.4.2",
+ "prosemirror-view": "^1.33.8"
+ }
+ },
+ "node_modules/prosemirror-transform": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz",
+ "integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-model": "^1.21.0"
+ }
+ },
+ "node_modules/prosemirror-view": {
+ "version": "1.41.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.0.tgz",
+ "integrity": "sha512-FatMIIl0vRHMcNc3sPy3cMw5MMyWuO1nWQxqvYpJvXAruucGvmQ2tyyjT2/Lbok77T9a/qZqBVCq4sj43V2ihw==",
+ "peer": true,
+ "dependencies": {
+ "prosemirror-model": "^1.20.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "dev": true
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/quansync": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
+ "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ]
+ },
+ "node_modules/queue": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
+ "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
+ "dependencies": {
+ "inherits": "~2.0.3"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "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==",
+ "devOptional": true,
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/recaptcha-v3": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/recaptcha-v3/-/recaptcha-v3-1.11.3.tgz",
+ "integrity": "sha512-sEE6J0RzUkS+sKEBpgCD/AqCU0ffrAVOADGjvAx9vcttN+VLK42SWMkj/J/I6vHu3Kew+xcfbBqDVb65N0QGDw=="
+ },
+ "node_modules/redent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+ "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+ "dev": true,
+ "dependencies": {
+ "indent-string": "^4.0.0",
+ "strip-indent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "dev": true
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+ "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
+ "dev": true,
+ "dependencies": {
+ "regenerate": "^1.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexpu-core": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+ "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
+ "dev": true,
+ "dependencies": {
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.2.0",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.12.0",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+ "dev": true
+ },
+ "node_modules/regjsparser": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
+ "dev": true,
+ "dependencies": {
+ "jsesc": "~3.0.2"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resize-observer-polyfill": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/restructure": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz",
+ "integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw=="
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="
+ },
+ "node_modules/rollup": {
+ "version": "4.50.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.0.tgz",
+ "integrity": "sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==",
+ "devOptional": true,
+ "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.50.0",
+ "@rollup/rollup-android-arm64": "4.50.0",
+ "@rollup/rollup-darwin-arm64": "4.50.0",
+ "@rollup/rollup-darwin-x64": "4.50.0",
+ "@rollup/rollup-freebsd-arm64": "4.50.0",
+ "@rollup/rollup-freebsd-x64": "4.50.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.50.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.50.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.50.0",
+ "@rollup/rollup-linux-arm64-musl": "4.50.0",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.50.0",
+ "@rollup/rollup-linux-ppc64-gnu": "4.50.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.50.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.50.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.50.0",
+ "@rollup/rollup-linux-x64-gnu": "4.50.0",
+ "@rollup/rollup-linux-x64-musl": "4.50.0",
+ "@rollup/rollup-openharmony-arm64": "4.50.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.50.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.50.0",
+ "@rollup/rollup-win32-x64-msvc": "4.50.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rope-sequence": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
+ "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
+ "peer": true
+ },
+ "node_modules/rrweb-cssom": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+ "dev": true
+ },
+ "node_modules/runes": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/runes/-/runes-0.4.3.tgz",
+ "integrity": "sha512-K6p9y4ZyL9wPzA+PMDloNQPfoDGTiFYDvdlXznyGKgD10BJpcAosvATKrExRKOrNLgD8E7Um7WGW0lxsnOuNLg==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "devOptional": true
+ },
+ "node_modules/sass": {
+ "version": "1.89.2",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz",
+ "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==",
+ "devOptional": true,
+ "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/sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "devOptional": true
+ },
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+ "dev": true,
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/slugify": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
+ "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/sortablejs": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
+ "integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
+ },
+ "node_modules/source-map": {
+ "version": "0.7.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
+ "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
+ "devOptional": true,
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "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==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-resolve": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
+ "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
+ "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
+ "devOptional": true,
+ "dependencies": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0"
+ }
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true
+ },
+ "node_modules/std-env": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
+ "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
+ "dev": true
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi/node_modules/ansi-regex": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz",
+ "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/strip-indent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+ "dev": true,
+ "dependencies": {
+ "min-indent": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-literal": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz",
+ "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==",
+ "dev": true,
+ "dependencies": {
+ "js-tokens": "^9.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/strip-literal/node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true
+ },
+ "node_modules/stylus": {
+ "version": "0.57.0",
+ "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.57.0.tgz",
+ "integrity": "sha512-yOI6G8WYfr0q8v8rRvE91wbxFU+rJPo760Va4MF6K0I6BZjO4r+xSynkvyPBP9tV1CIEUeRsiidjIs2rzb1CnQ==",
+ "devOptional": true,
+ "dependencies": {
+ "css": "^3.0.0",
+ "debug": "^4.3.2",
+ "glob": "^7.1.6",
+ "safer-buffer": "^2.1.2",
+ "sax": "~1.2.4",
+ "source-map": "^0.7.3"
+ },
+ "bin": {
+ "stylus": "bin/stylus"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/stylus/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "devOptional": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/superjson": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
+ "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
+ "dependencies": {
+ "copy-anything": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/svg-arc-to-cubic-bezier": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz",
+ "integrity": "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g=="
+ },
+ "node_modules/svg-tags": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+ "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
+ "dev": true
+ },
+ "node_modules/svgo": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz",
+ "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==",
+ "dev": true,
+ "dependencies": {
+ "@trysound/sax": "0.2.0",
+ "commander": "^7.2.0",
+ "css-select": "^5.1.0",
+ "css-tree": "^2.3.1",
+ "css-what": "^6.1.0",
+ "csso": "^5.0.5",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "svgo": "bin/svgo"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/svgo"
+ }
+ },
+ "node_modules/svgo/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true
+ },
+ "node_modules/synckit": {
+ "version": "0.11.11",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
+ "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==",
+ "dev": true,
+ "dependencies": {
+ "@pkgr/core": "^0.2.9"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz",
+ "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
+ "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==",
+ "dev": true,
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/test-exclude/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,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/test-exclude/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,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/test-exclude/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/tiny-inflate": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+ "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
+ },
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true
+ },
+ "node_modules/tinyexec": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+ "dev": true
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
+ "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
+ "devOptional": true,
+ "dependencies": {
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/tinypool": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz",
+ "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==",
+ "dev": true,
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tinyspy": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz",
+ "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "dev": true,
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "dev": true
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "devOptional": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "dev": true,
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/ts-declaration-location": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz",
+ "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "ko-fi",
+ "url": "https://ko-fi.com/rebeccastevens"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/ts-declaration-location"
+ }
+ ],
+ "dependencies": {
+ "picomatch": "^4.0.2"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.0.0"
+ }
+ },
+ "node_modules/ts-declaration-location/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz",
+ "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
+ "devOptional": true,
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
+ },
+ "node_modules/ufo": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
+ "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
+ "dev": true
+ },
+ "node_modules/undici": {
+ "version": "7.15.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.15.0.tgz",
+ "integrity": "sha512-7oZJCPvvMvTd0OlqWsIxTuItTpJBpU1tcbVl24FMn3xt3+VSunwUasmfPJRE57oNO1KsZ4PgA1xTdAX4hq8NyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=20.18.1"
+ }
+ },
+ "node_modules/unhead": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/unhead/-/unhead-2.0.14.tgz",
+ "integrity": "sha512-dRP6OCqtShhMVZQe1F4wdt/WsYl2MskxKK+cvfSo0lQnrPJ4oAUQEkxRg7pPP+vJENabhlir31HwAyHUv7wfMg==",
+ "dependencies": {
+ "hookable": "^5.5.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/harlan-zw"
+ }
+ },
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+ "dev": true,
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^2.0.0",
+ "unicode-property-aliases-ecmascript": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-value-ecmascript": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-properties": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz",
+ "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==",
+ "dependencies": {
+ "base64-js": "^1.3.0",
+ "unicode-trie": "^2.0.0"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-trie": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
+ "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==",
+ "dependencies": {
+ "pako": "^0.2.5",
+ "tiny-inflate": "^1.0.0"
+ }
+ },
+ "node_modules/unicode-trie/node_modules/pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="
+ },
+ "node_modules/unplugin": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz",
+ "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^8.8.1",
+ "chokidar": "^3.5.3",
+ "webpack-sources": "^3.2.3",
+ "webpack-virtual-modules": "^0.5.0"
+ }
+ },
+ "node_modules/unplugin-utils": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.5.tgz",
+ "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==",
+ "dev": true,
+ "dependencies": {
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/unplugin-utils/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/unplugin-vue-components": {
+ "version": "28.8.0",
+ "resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-28.8.0.tgz",
+ "integrity": "sha512-2Q6ZongpoQzuXDK0ZsVzMoshH0MWZQ1pzVL538G7oIDKRTVzHjppBDS8aB99SADGHN3lpGU7frraCG6yWNoL5Q==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": "^3.6.0",
+ "debug": "^4.4.1",
+ "local-pkg": "^1.1.1",
+ "magic-string": "^0.30.17",
+ "mlly": "^1.7.4",
+ "tinyglobby": "^0.2.14",
+ "unplugin": "^2.3.5",
+ "unplugin-utils": "^0.2.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@babel/parser": "^7.15.8",
+ "@nuxt/kit": "^3.2.2 || ^4.0.0",
+ "vue": "2 || 3"
+ },
+ "peerDependenciesMeta": {
+ "@babel/parser": {
+ "optional": true
+ },
+ "@nuxt/kit": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/magic-string": {
+ "version": "0.30.18",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
+ "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/unplugin": {
+ "version": "2.3.10",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.10.tgz",
+ "integrity": "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.5",
+ "acorn": "^8.15.0",
+ "picomatch": "^4.0.3",
+ "webpack-virtual-modules": "^0.6.2"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/unplugin/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/unplugin-vue-components/node_modules/webpack-virtual-modules": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
+ "dev": true
+ },
+ "node_modules/unplugin/node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/unplugin/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/unplugin/node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/upath": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz",
+ "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=4",
+ "yarn": "*"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "name": "uri-js-replace",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz",
+ "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==",
+ "dev": true
+ },
+ "node_modules/url-template": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/url-template/-/url-template-3.1.1.tgz",
+ "integrity": "sha512-4oszoaEKE/mQOtAmdMWqIRHmkxWkUZMnXFnjQ5i01CuRSK3uluxcH1MRVVVWmhlnzT1SCDfKxxficm2G37qzCA==",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/util": {
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+ "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "which-typed-array": "^1.1.2"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "node_modules/v-resize-observer": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/v-resize-observer/-/v-resize-observer-2.1.0.tgz",
+ "integrity": "sha512-QyTdSFAAtsP1/2ISR2hsz8PeEyxhaACqJXIzs5INlHXtu/pkMqyva8tHPWA54YejUyhxmU1bPriDBnW2cqbBcA==",
+ "dependencies": {
+ "resize-observer-polyfill": "^1.5.1",
+ "vue-demi": "latest"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.7.0",
+ "vue": "^2.5.0 || >=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/v-resize-observer/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vee-validate": {
+ "version": "4.15.1",
+ "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.15.1.tgz",
+ "integrity": "sha512-DkFsiTwEKau8VIxyZBGdO6tOudD+QoUBPuHj3e6QFqmbfCRj1ArmYWue9lEp6jLSWBIw4XPlDLjFIZNLdRAMSg==",
+ "dependencies": {
+ "@vue/devtools-api": "^7.5.2",
+ "type-fest": "^4.8.3"
+ },
+ "peerDependencies": {
+ "vue": "^3.4.26"
+ }
+ },
+ "node_modules/vite": {
+ "version": "6.3.5",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
+ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
+ "devOptional": true,
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-compatible-readable-stream": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/vite-compatible-readable-stream/-/vite-compatible-readable-stream-3.6.1.tgz",
+ "integrity": "sha512-t20zYkrSf868+j/p31cRIGN28Phrjm3nRSLR2fyc2tiWi4cZGVdv68yNlwnIINTkMTmPoMiSlc0OadaO7DXZaQ==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/vite-node": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz",
+ "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==",
+ "dev": true,
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.4.1",
+ "es-module-lexer": "^1.7.0",
+ "pathe": "^2.0.3",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vite-plugin-comlink": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-comlink/-/vite-plugin-comlink-5.3.0.tgz",
+ "integrity": "sha512-grCxBC8JaCYIHPIvrM5c8Hq+XjFs3nhwSDc0SLpgY3D2LtE5j0wIZTF8zMWMzwMcrFPXWSejZI6MF6yvP/Iq9g==",
+ "dev": true,
+ "dependencies": {
+ "json5": "2.2.3",
+ "magic-string": "0.30.17",
+ "source-map": "^0.7.4"
+ },
+ "peerDependencies": {
+ "comlink": "^4.3.1",
+ "vite": ">=2.9.6"
+ }
+ },
+ "node_modules/vite-plugin-comlink/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==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/vite-plugin-vuetify": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/vite-plugin-vuetify/-/vite-plugin-vuetify-2.1.2.tgz",
+ "integrity": "sha512-I/wd6QS+DO6lHmuGoi1UTyvvBTQ2KDzQZ9oowJQEJ6OcjWfJnscYXx2ptm6S7fJSASuZT8jGRBL3LV4oS3LpaA==",
+ "devOptional": true,
+ "dependencies": {
+ "@vuetify/loader-shared": "^2.1.1",
+ "debug": "^4.3.3",
+ "upath": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": ">=5",
+ "vue": "^3.0.0",
+ "vuetify": "^3.0.0"
+ }
+ },
+ "node_modules/vite-svg-loader": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/vite-svg-loader/-/vite-svg-loader-5.1.0.tgz",
+ "integrity": "sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "svgo": "^3.0.2"
+ },
+ "peerDependencies": {
+ "vue": ">=3.2.13"
+ }
+ },
+ "node_modules/vite/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
+ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
+ "dev": true,
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/expect": "3.2.4",
+ "@vitest/mocker": "3.2.4",
+ "@vitest/pretty-format": "^3.2.4",
+ "@vitest/runner": "3.2.4",
+ "@vitest/snapshot": "3.2.4",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "debug": "^4.4.1",
+ "expect-type": "^1.2.1",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.2",
+ "std-env": "^3.9.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.2",
+ "tinyglobby": "^0.2.14",
+ "tinypool": "^1.1.1",
+ "tinyrainbow": "^2.0.0",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
+ "vite-node": "3.2.4",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@types/debug": "^4.1.12",
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "@vitest/browser": "3.2.4",
+ "@vitest/ui": "3.2.4",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@types/debug": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitest-canvas-mock": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/vitest-canvas-mock/-/vitest-canvas-mock-0.3.3.tgz",
+ "integrity": "sha512-3P968tYBpqYyzzOaVtqnmYjqbe13576/fkjbDEJSfQAkHtC5/UjuRHOhFEN/ZV5HVZIkaROBUWgazDKJ+Ibw+Q==",
+ "dev": true,
+ "dependencies": {
+ "jest-canvas-mock": "~2.5.2"
+ },
+ "peerDependencies": {
+ "vitest": "*"
+ }
+ },
+ "node_modules/vitest/node_modules/magic-string": {
+ "version": "0.30.18",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
+ "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/vitest/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.21.tgz",
+ "integrity": "sha512-xxf9rum9KtOdwdRkiApWL+9hZEMWE90FHh8yS1+KJAiWYh+iGWV1FquPjoO9VUHQ+VIhsCXNNyZ5Sf4++RVZBA==",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.21",
+ "@vue/compiler-sfc": "3.5.21",
+ "@vue/runtime-dom": "3.5.21",
+ "@vue/server-renderer": "3.5.21",
+ "@vue/shared": "3.5.21"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-axios": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/vue-axios/-/vue-axios-3.5.2.tgz",
+ "integrity": "sha512-GP+dct7UlAWkl1qoP3ppw0z6jcSua5/IrMpjB5O8bh089iIiJ+hdxPYH2NPEpajlYgkW5EVMP95ttXWdas1O0g==",
+ "peerDependencies": {
+ "axios": "*",
+ "vue": "^3.0.0 || ^2.0.0"
+ }
+ },
+ "node_modules/vue-component-type-helpers": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.2.12.tgz",
+ "integrity": "sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==",
+ "dev": true
+ },
+ "node_modules/vue-eslint-parser": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz",
+ "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "debug": "^4.4.0",
+ "eslint-scope": "^8.2.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.6.0",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0"
+ }
+ },
+ "node_modules/vue-eslint-parser/node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/vue-eslint-parser/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/vue-eslint-parser/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/vue-i18n": {
+ "version": "11.1.11",
+ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.1.11.tgz",
+ "integrity": "sha512-LvyteQoXeQiuILbzqv13LbyBna/TEv2Ha+4ZWK2AwGHUzZ8+IBaZS0TJkCgn5izSPLcgZwXy9yyTrewCb2u/MA==",
+ "dependencies": {
+ "@intlify/core-base": "11.1.11",
+ "@intlify/shared": "11.1.11",
+ "@vue/devtools-api": "^6.5.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/vue-i18n/node_modules/@vue/devtools-api": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
+ },
+ "node_modules/vue-recaptcha-v3": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/vue-recaptcha-v3/-/vue-recaptcha-v3-2.0.1.tgz",
+ "integrity": "sha512-isEDtOfHU4wWRrZZuxciAELtQmPOeEEdicPNa0f1AOyLPy3sCcBEcpFt+FOcO3RQv5unJ3Yn5NlsWtXv9rXqjg==",
+ "dependencies": {
+ "recaptcha-v3": "^1.8.0"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.11"
+ }
+ },
+ "node_modules/vue-router": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",
+ "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==",
+ "dependencies": {
+ "@vue/devtools-api": "^6.6.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "vue": "^3.2.0"
+ }
+ },
+ "node_modules/vue-router/node_modules/@vue/devtools-api": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
+ },
+ "node_modules/vue-toastification": {
+ "version": "2.0.0-rc.5",
+ "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz",
+ "integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==",
+ "peerDependencies": {
+ "vue": "^3.0.2"
+ }
+ },
+ "node_modules/vuedraggable": {
+ "version": "2.24.3",
+ "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
+ "integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
+ "dependencies": {
+ "sortablejs": "1.10.2"
+ }
+ },
+ "node_modules/vuetify": {
+ "version": "3.10.4",
+ "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.10.4.tgz",
+ "integrity": "sha512-aatUQ0RM0i6VdkJaFyj3gydecuFmAgACNO3RwWznvjvIvRENQXxMRiv+vlGFoshbw2UG+zOPPMhO12OCPSa2UQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/johnleider"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.7",
+ "vite-plugin-vuetify": ">=2.1.0",
+ "vue": "^3.5.0",
+ "webpack-plugin-vuetify": ">=3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ },
+ "vite-plugin-vuetify": {
+ "optional": true
+ },
+ "webpack-plugin-vuetify": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vuex": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
+ "integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==",
+ "dependencies": {
+ "@vue/devtools-api": "^6.0.0-beta.11"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.2"
+ }
+ },
+ "node_modules/vuex/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=="
+ },
+ "node_modules/w3c-keyname": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
+ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
+ "peer": true
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
+ "dev": true,
+ "dependencies": {
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/w3c-xmlserializer/node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
+ "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack-virtual-modules": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz",
+ "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==",
+ "dev": true
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "dev": true,
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "dev": true,
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
+ "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "devOptional": true
+ },
+ "node_modules/ws": {
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xlsx": {
+ "version": "0.20.2",
+ "resolved": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz",
+ "integrity": "sha512-+nKZ39+nvK7Qq6i0PvWWRA4j/EkfWOtkP/YhMtupm+lJIiHxUrgTr1CcKv1nBk1rHtkRRQ3O2+Ih/q/sA+FXZA==",
+ "license": "Apache-2.0",
+ "bin": {
+ "xlsx": "bin/xlsx.njs"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+ "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
+ "node_modules/yaml": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
+ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
+ "devOptional": true,
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/yoga-layout": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz",
+ "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="
+ }
+ }
+}
diff --git a/frontend-vue3/package.json b/frontend-vue3/package.json
new file mode 100644
index 0000000000..d499e40819
--- /dev/null
+++ b/frontend-vue3/package.json
@@ -0,0 +1,158 @@
+{
+ "name": "@ecamp3/frontend",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "serve": "vite --host 0.0.0.0",
+ "preview": "vite preview --host 0.0.0.0 --port 3000",
+ "build": "vite build",
+ "lint": "npm run lint:eslint && npm run lint:prettier",
+ "lint:eslint": "eslint --fix .",
+ "lint:prettier": "prettier --write --ignore-path .prettierignore **/*.{css,scss,json,md}",
+ "lint:check": "npm run lint:check:eslint && npm run lint:check:prettier",
+ "lint:check:eslint": "eslint .",
+ "lint:check:prettier": "prettier --check --ignore-path .prettierignore **/*.{css,scss,json,md}",
+ "start": "vite --host 0.0.0.0",
+ "dev": "vite --host 0.0.0.0",
+ "test:unit": "vitest run --coverage",
+ "test:unit:debug": "node --inspect-brk=0.0.0.0:9229 ./node_modules/.bin/vitest --no-cache --runInBand",
+ "test:unit:watch": "vitest --watch",
+ "postinstall": "./scripts/install-twemoji.sh"
+ },
+ "dependencies": {
+ "@intlify/core": "11.1.11",
+ "@mdi/font": "7.4.47",
+ "@react-pdf/font": "4.0.2",
+ "@react-pdf/layout": "4.4.0",
+ "@react-pdf/pdfkit": "4.0.3",
+ "@react-pdf/primitives": "4.1.1",
+ "@react-pdf/render": "4.3.0",
+ "@sentry/browser": "9.44.0",
+ "@sentry/vue": "9.44.0",
+ "@tiptap/extension-bold": "3.0.9",
+ "@tiptap/extension-bubble-menu": "3.0.9",
+ "@tiptap/extension-bullet-list": "3.0.9",
+ "@tiptap/extension-document": "3.0.9",
+ "@tiptap/extension-hard-break": "3.0.9",
+ "@tiptap/extension-heading": "3.0.9",
+ "@tiptap/extension-history": "3.0.9",
+ "@tiptap/extension-italic": "3.0.9",
+ "@tiptap/extension-list-item": "3.0.9",
+ "@tiptap/extension-ordered-list": "3.0.9",
+ "@tiptap/extension-paragraph": "3.0.9",
+ "@tiptap/extension-placeholder": "3.0.9",
+ "@tiptap/extension-strike": "3.0.9",
+ "@tiptap/extension-text": "3.0.9",
+ "@tiptap/extension-underline": "3.0.9",
+ "@tiptap/vue-3": "3.0.9",
+ "@vee-validate/i18n": "4.15.1",
+ "@vee-validate/rules": "4.15.1",
+ "@unhead/vue": "2.0.14",
+ "@zxcvbn-ts/core": "3.0.4",
+ "@zxcvbn-ts/language-common": "3.0.4",
+ "@zxcvbn-ts/language-de": "3.0.2",
+ "@zxcvbn-ts/language-en": "3.0.2",
+ "@zxcvbn-ts/language-fr": "3.0.2",
+ "@zxcvbn-ts/language-it": "3.0.2",
+ "assert": "2.1.0",
+ "axios": "1.11.0",
+ "colorjs.io": "0.5.2",
+ "comlink": "4.4.2",
+ "dayjs": "1.11.13",
+ "deepmerge": "4.3.1",
+ "emoji-regex": "10.4.0",
+ "file-saver": "2.0.5",
+ "hal-json-vuex": "3.0.0-alpha.10",
+ "inter-ui": "3.19.3",
+ "js-cookie": "3.0.5",
+ "linkify-it": "5.0.0",
+ "lodash-es": "4.17.21",
+ "runes": "0.4.3",
+ "slugify": "1.6.6",
+ "url-template": "3.1.1",
+ "util": "0.12.5",
+ "v-resize-observer": "2.1.0",
+ "vee-validate": "4.15.1",
+ "vue": "3.5.21",
+ "@vue/compat": "3.5.21",
+ "vue-axios": "3.5.2",
+ "vue-i18n": "11.1.11",
+ "vue-recaptcha-v3": "2.0.1",
+ "vue-router": "4.5.1",
+ "vue-toastification": "2.0.0-rc.5",
+ "vuedraggable": "2.24.3",
+ "vuetify": "3.10.4",
+ "vuex": "4.0.2",
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
+ },
+ "devDependencies": {
+ "@babel/eslint-parser": "7.28.0",
+ "@eslint/compat": "1.3.1",
+ "@eslint/eslintrc": "3.3.1",
+ "@eslint/js": "9.32.0",
+ "@sentry/vite-plugin": "4.0.2",
+ "@testing-library/jest-dom": "6.6.4",
+ "@testing-library/user-event": "14.6.1",
+ "@testing-library/vue": "8.1.0",
+ "@vitejs/plugin-vue": "6.0.1",
+ "@vitest/coverage-v8": "3.2.4",
+ "@vue/babel-preset-app": "5.0.9",
+ "@vue/compiler-dom": "3.5.21",
+ "@vue/compiler-sfc": "3.5.21",
+ "@vue/runtime-dom": "3.5.21",
+ "@vue/server-renderer": "3.5.21",
+ "@vue/shared": "3.5.21",
+ "@vue/eslint-config-prettier": "10.2.0",
+ "@vue/test-utils": "2.4.6",
+ "autoprefixer": "10.4.21",
+ "babel-plugin-require-context-hook": "1.0.0",
+ "eslint": "9.32.0",
+ "eslint-config-prettier": "10.1.8",
+ "eslint-plugin-local-rules": "3.0.2",
+ "eslint-plugin-n": "17.21.3",
+ "eslint-plugin-prettier": "5.5.3",
+ "eslint-plugin-promise": "7.2.1",
+ "eslint-plugin-vue": "10.4.0",
+ "eslint-plugin-vue-scoped-css": "2.11.0",
+ "flush-promises": "1.0.2",
+ "globals": "16.3.0",
+ "jest-serializer-vue-tjw": "4.0.0",
+ "jsdom": "26.1.0",
+ "lint-staged": "16.1.4",
+ "prettier": "3.6.2",
+ "sass": "1.89.2",
+ "unplugin-vue-components": "28.8.0",
+ "vite": "6.3.5",
+ "vite-plugin-comlink": "5.3.0",
+ "vite-svg-loader": "5.1.0",
+ "vitest": "3.2.4",
+ "vitest-canvas-mock": "0.3.3",
+ "vite-plugin-vuetify": "2.1.2"
+ },
+ "overrides": {
+ "uri-js": "npm:uri-js-replace"
+ },
+ "postcss": {
+ "plugins": {
+ "autoprefixer": {}
+ }
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions",
+ "not ie <= 8"
+ ],
+ "gitHooks": {
+ "pre-commit": "lint-staged"
+ },
+ "lint-staged": {
+ "*.js": [
+ "eslint . --ext .vue,.js --fix --ignore-path .gitignore",
+ "git add"
+ ],
+ "*.vue": [
+ "eslint . --ext .vue,.js --fix --ignore-path .gitignore",
+ "git add"
+ ]
+ }
+}
diff --git a/frontend-vue3/public/browserassets/apple-touch-icon.png b/frontend-vue3/public/browserassets/apple-touch-icon.png
new file mode 100644
index 0000000000..76e05f775e
Binary files /dev/null and b/frontend-vue3/public/browserassets/apple-touch-icon.png differ
diff --git a/frontend-vue3/public/browserassets/favicon-16x16.png b/frontend-vue3/public/browserassets/favicon-16x16.png
new file mode 100644
index 0000000000..c45a8a1966
Binary files /dev/null and b/frontend-vue3/public/browserassets/favicon-16x16.png differ
diff --git a/frontend-vue3/public/browserassets/favicon-32x32.png b/frontend-vue3/public/browserassets/favicon-32x32.png
new file mode 100644
index 0000000000..3cce341a4b
Binary files /dev/null and b/frontend-vue3/public/browserassets/favicon-32x32.png differ
diff --git a/frontend-vue3/public/browserassets/logo@192px.png b/frontend-vue3/public/browserassets/logo@192px.png
new file mode 100644
index 0000000000..d275c989c4
Binary files /dev/null and b/frontend-vue3/public/browserassets/logo@192px.png differ
diff --git a/frontend-vue3/public/browserassets/logo@512px.png b/frontend-vue3/public/browserassets/logo@512px.png
new file mode 100644
index 0000000000..f8778ee95f
Binary files /dev/null and b/frontend-vue3/public/browserassets/logo@512px.png differ
diff --git a/frontend-vue3/public/browserassets/mstile-150x150.png b/frontend-vue3/public/browserassets/mstile-150x150.png
new file mode 100644
index 0000000000..322c49bc50
Binary files /dev/null and b/frontend-vue3/public/browserassets/mstile-150x150.png differ
diff --git a/frontend-vue3/public/browserassets/safari-pinned-tab.svg b/frontend-vue3/public/browserassets/safari-pinned-tab.svg
new file mode 100644
index 0000000000..0248b1e6bc
--- /dev/null
+++ b/frontend-vue3/public/browserassets/safari-pinned-tab.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/frontend-vue3/public/browserconfig.xml b/frontend-vue3/public/browserconfig.xml
new file mode 100644
index 0000000000..1cd51a1fa2
--- /dev/null
+++ b/frontend-vue3/public/browserconfig.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+ #263238
+
+
+
diff --git a/frontend-vue3/public/environment.js b/frontend-vue3/public/environment.js
new file mode 100644
index 0000000000..47b91ee3e6
--- /dev/null
+++ b/frontend-vue3/public/environment.js
@@ -0,0 +1,5 @@
+/**
+ * This is a placeholder.
+ * In production, this file is filled with the values for window.environment.
+ * In development, window.environment is filled in src/dev-environment.js
+ */
diff --git a/frontend-vue3/public/favicon.ico b/frontend-vue3/public/favicon.ico
new file mode 100644
index 0000000000..6c628462f9
Binary files /dev/null and b/frontend-vue3/public/favicon.ico differ
diff --git a/frontend-vue3/public/favicon.svg b/frontend-vue3/public/favicon.svg
new file mode 100644
index 0000000000..40da9b592e
--- /dev/null
+++ b/frontend-vue3/public/favicon.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/public/logo.svg b/frontend-vue3/public/logo.svg
new file mode 100644
index 0000000000..d9d26fca25
--- /dev/null
+++ b/frontend-vue3/public/logo.svg
@@ -0,0 +1,55 @@
+
+ Logo eCamp v3
+
+
+
+ image/svg+xml
+
+ Logo eCamp v3
+ 2020-04-02
+ Manuel Meister
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/public/manifest.webmanifest b/frontend-vue3/public/manifest.webmanifest
new file mode 100644
index 0000000000..1b9895dc65
--- /dev/null
+++ b/frontend-vue3/public/manifest.webmanifest
@@ -0,0 +1,30 @@
+{
+ "short_name": "eCamp",
+ "name": "eCamp v3",
+ "icons": [
+ {
+ "src": "/favicon.svg",
+ "type": "image/svg",
+ "sizes": "16x16"
+ },
+ {
+ "src": "/logo.svg",
+ "type": "image/svg",
+ "sizes": "64x64"
+ },
+ {
+ "src": "/browserassets/logo@192px.png",
+ "type": "image/png",
+ "sizes": "192x192"
+ },
+ {
+ "src": "/browserassets/logo@512px.png",
+ "type": "image/png",
+ "sizes": "512x512"
+ }
+ ],
+ "start_url": "/",
+ "background_color": "#546e7a",
+ "display": "minimal-ui",
+ "theme_color": "#546e7a"
+}
diff --git a/frontend-vue3/scripts/install-twemoji.sh b/frontend-vue3/scripts/install-twemoji.sh
new file mode 100755
index 0000000000..9a1cb6172e
--- /dev/null
+++ b/frontend-vue3/scripts/install-twemoji.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env sh
+
+# We need twemoji for emoji support in client-side printing. Since there is no maintained npm package
+# which includes the actual emoji images, we use this script to install the images. By default,
+# twemoji are usually accessed from CDNs, but for traceability reasons, we self-host them.
+
+set -euo
+
+if [ ! -d "public/twemoji" ]
+then
+ echo 'downloading twemoji images from GitHub...'
+ # Clone as little as possible. No past revisions and only the image files we are interested in.
+ git clone --depth 1 --no-checkout --filter=blob:none --sparse https://github.com/twitter/twemoji.git public/twemoji
+ cd public/twemoji
+ git sparse-checkout set assets/72x72
+ git checkout master
+else
+ echo 'twemoji are already present, updating them to the latest version...'
+ cd public/twemoji
+ git pull || echo 'Could not update twemoji. Skipping for now...'
+fi
+
+echo 'twemoji images should be up to date now.'
diff --git a/frontend-vue3/src/App.vue b/frontend-vue3/src/App.vue
new file mode 100644
index 0000000000..52055fc78e
--- /dev/null
+++ b/frontend-vue3/src/App.vue
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('global.info.offline.title') }}
+ {{ $t('global.info.offline.description') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/080720_lotos_7896.jpg b/frontend-vue3/src/assets/080720_lotos_7896.jpg
new file mode 100644
index 0000000000..ba331f6694
Binary files /dev/null and b/frontend-vue3/src/assets/080720_lotos_7896.jpg differ
diff --git a/frontend-vue3/src/assets/080720_lotos_7896_small.jpg b/frontend-vue3/src/assets/080720_lotos_7896_small.jpg
new file mode 100644
index 0000000000..7e9c9c4847
Binary files /dev/null and b/frontend-vue3/src/assets/080720_lotos_7896_small.jpg differ
diff --git a/frontend-vue3/src/assets/140801151550_LOM.jpg b/frontend-vue3/src/assets/140801151550_LOM.jpg
new file mode 100644
index 0000000000..be93ebdeda
Binary files /dev/null and b/frontend-vue3/src/assets/140801151550_LOM.jpg differ
diff --git a/frontend-vue3/src/assets/140801151550_LOM_small.jpg b/frontend-vue3/src/assets/140801151550_LOM_small.jpg
new file mode 100644
index 0000000000..640aa99370
Binary files /dev/null and b/frontend-vue3/src/assets/140801151550_LOM_small.jpg differ
diff --git a/frontend-vue3/src/assets/CeviLogo.svg b/frontend-vue3/src/assets/CeviLogo.svg
new file mode 100644
index 0000000000..a085896ad3
--- /dev/null
+++ b/frontend-vue3/src/assets/CeviLogo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend-vue3/src/assets/FourZeroFour.svg b/frontend-vue3/src/assets/FourZeroFour.svg
new file mode 100644
index 0000000000..e4cd16606e
--- /dev/null
+++ b/frontend-vue3/src/assets/FourZeroFour.svg
@@ -0,0 +1,65 @@
+
+ Error 404
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend-vue3/src/assets/GoogleLogo.svg b/frontend-vue3/src/assets/GoogleLogo.svg
new file mode 100644
index 0000000000..3bbcc195cb
--- /dev/null
+++ b/frontend-vue3/src/assets/GoogleLogo.svg
@@ -0,0 +1 @@
+
diff --git a/frontend-vue3/src/assets/JublaLogo.svg b/frontend-vue3/src/assets/JublaLogo.svg
new file mode 100644
index 0000000000..a13774d235
--- /dev/null
+++ b/frontend-vue3/src/assets/JublaLogo.svg
@@ -0,0 +1 @@
+
diff --git a/frontend-vue3/src/assets/PbsLogo.svg b/frontend-vue3/src/assets/PbsLogo.svg
new file mode 100644
index 0000000000..e4086e4f2e
--- /dev/null
+++ b/frontend-vue3/src/assets/PbsLogo.svg
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/frontend-vue3/src/assets/eCampLogo.svg b/frontend-vue3/src/assets/eCampLogo.svg
new file mode 100644
index 0000000000..defa95d10e
--- /dev/null
+++ b/frontend-vue3/src/assets/eCampLogo.svg
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Bold.ttf b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Bold.ttf
new file mode 100644
index 0000000000..9aa4b0b542
Binary files /dev/null and b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Bold.ttf differ
diff --git a/frontend-vue3/src/assets/fonts/Inter/InterDisplay-BoldItalic.ttf b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-BoldItalic.ttf
new file mode 100644
index 0000000000..20ce27cbb4
Binary files /dev/null and b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-BoldItalic.ttf differ
diff --git a/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Italic.ttf b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Italic.ttf
new file mode 100644
index 0000000000..97da0c0bc1
Binary files /dev/null and b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Italic.ttf differ
diff --git a/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Medium.ttf b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Medium.ttf
new file mode 100644
index 0000000000..64748bd99e
Binary files /dev/null and b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Medium.ttf differ
diff --git a/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Regular.ttf b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Regular.ttf
new file mode 100644
index 0000000000..f4ac57f376
Binary files /dev/null and b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-Regular.ttf differ
diff --git a/frontend-vue3/src/assets/fonts/Inter/InterDisplay-SemiBold.ttf b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-SemiBold.ttf
new file mode 100644
index 0000000000..8abb2a7054
Binary files /dev/null and b/frontend-vue3/src/assets/fonts/Inter/InterDisplay-SemiBold.ttf differ
diff --git a/frontend-vue3/src/assets/fonts/Inter/LICENSE.txt b/frontend-vue3/src/assets/fonts/Inter/LICENSE.txt
new file mode 100644
index 0000000000..9b2ca37b3f
--- /dev/null
+++ b/frontend-vue3/src/assets/fonts/Inter/LICENSE.txt
@@ -0,0 +1,92 @@
+Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION AND CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/frontend-vue3/src/assets/icons/BigScreen.svg b/frontend-vue3/src/assets/icons/BigScreen.svg
new file mode 100644
index 0000000000..88e320bd94
--- /dev/null
+++ b/frontend-vue3/src/assets/icons/BigScreen.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/frontend-vue3/src/assets/icons/Coffee.vue b/frontend-vue3/src/assets/icons/Coffee.vue
new file mode 100644
index 0000000000..ef7ae7f7ef
--- /dev/null
+++ b/frontend-vue3/src/assets/icons/Coffee.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/icons/ColumnLayout.svg b/frontend-vue3/src/assets/icons/ColumnLayout.svg
new file mode 100644
index 0000000000..c640451de1
--- /dev/null
+++ b/frontend-vue3/src/assets/icons/ColumnLayout.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/frontend-vue3/src/assets/icons/PaperSize.svg b/frontend-vue3/src/assets/icons/PaperSize.svg
new file mode 100644
index 0000000000..5b2ec65313
--- /dev/null
+++ b/frontend-vue3/src/assets/icons/PaperSize.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/frontend-vue3/src/assets/icons/ResponsiveLayout.svg b/frontend-vue3/src/assets/icons/ResponsiveLayout.svg
new file mode 100644
index 0000000000..f65d28cce0
--- /dev/null
+++ b/frontend-vue3/src/assets/icons/ResponsiveLayout.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/frontend-vue3/src/assets/invitation/edge-left.svg b/frontend-vue3/src/assets/invitation/edge-left.svg
new file mode 100644
index 0000000000..5d61de797e
--- /dev/null
+++ b/frontend-vue3/src/assets/invitation/edge-left.svg
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/invitation/edge-right.svg b/frontend-vue3/src/assets/invitation/edge-right.svg
new file mode 100644
index 0000000000..083701dc30
--- /dev/null
+++ b/frontend-vue3/src/assets/invitation/edge-right.svg
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/invitation/tree-left.svg b/frontend-vue3/src/assets/invitation/tree-left.svg
new file mode 100644
index 0000000000..a0a6c8ccfd
--- /dev/null
+++ b/frontend-vue3/src/assets/invitation/tree-left.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/invitation/tree-right.svg b/frontend-vue3/src/assets/invitation/tree-right.svg
new file mode 100644
index 0000000000..443c359e56
--- /dev/null
+++ b/frontend-vue3/src/assets/invitation/tree-right.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/logo.png b/frontend-vue3/src/assets/logo.png
new file mode 100644
index 0000000000..f3d2503fc2
Binary files /dev/null and b/frontend-vue3/src/assets/logo.png differ
diff --git a/frontend-vue3/src/assets/tents/ShootingStar.vue b/frontend-vue3/src/assets/tents/ShootingStar.vue
new file mode 100644
index 0000000000..84acc6e684
--- /dev/null
+++ b/frontend-vue3/src/assets/tents/ShootingStar.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/tents/TentDay.svg b/frontend-vue3/src/assets/tents/TentDay.svg
new file mode 100644
index 0000000000..865ed192d9
--- /dev/null
+++ b/frontend-vue3/src/assets/tents/TentDay.svg
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/tents/TentNight.vue b/frontend-vue3/src/assets/tents/TentNight.vue
new file mode 100644
index 0000000000..2bdf6a2fe6
--- /dev/null
+++ b/frontend-vue3/src/assets/tents/TentNight.vue
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/assets/tents/stars.svg b/frontend-vue3/src/assets/tents/stars.svg
new file mode 100644
index 0000000000..d794cdcaa9
--- /dev/null
+++ b/frontend-vue3/src/assets/tents/stars.svg
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/common/assets/logos/GSLogo.svg b/frontend-vue3/src/common/assets/logos/GSLogo.svg
new file mode 100644
index 0000000000..4903b5e411
--- /dev/null
+++ b/frontend-vue3/src/common/assets/logos/GSLogo.svg
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/frontend-vue3/src/common/assets/logos/JSLogo.svg b/frontend-vue3/src/common/assets/logos/JSLogo.svg
new file mode 100644
index 0000000000..f0734b30cf
--- /dev/null
+++ b/frontend-vue3/src/common/assets/logos/JSLogo.svg
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/frontend-vue3/src/common/eslint-local-rules/__tests__/matchingTranslationKeys.spec.js b/frontend-vue3/src/common/eslint-local-rules/__tests__/matchingTranslationKeys.spec.js
new file mode 100644
index 0000000000..726d30ad18
--- /dev/null
+++ b/frontend-vue3/src/common/eslint-local-rules/__tests__/matchingTranslationKeys.spec.js
@@ -0,0 +1,358 @@
+import rule from '../matchingTranslationKeys.js'
+import { RuleTester } from 'eslint'
+import path from 'path'
+import fs from 'fs'
+import utils from 'eslint-plugin-vue/lib/utils/index.js'
+import { describe, it } from 'vitest'
+import localRules from 'eslint-plugin-local-rules'
+import globals from 'globals'
+import eslintParser from 'vue-eslint-parser'
+
+RuleTester.describe = describe
+RuleTester.it = it
+
+const ruleTester = new RuleTester({
+ plugins: {
+ 'local-rules': localRules,
+ },
+
+ languageOptions: {
+ parser: eslintParser,
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ },
+
+ parserOptions: {
+ parser: '@babel/eslint-parser',
+ },
+ },
+})
+const ruleInstance = rule(path, utils, fs)
+
+const options = [
+ {
+ ignoreKeysRegex: '^(global|entity|contentNode\\.[a-z][a-zA-Z]+)\\..+',
+ translationKeyPropRegex: '[a-zA-Z0-9]-i18n-key$',
+ },
+]
+
+ruleTester.run('local-rules/matching-translation-keys', ruleInstance, {
+ valid: [
+ {
+ name: 'allows correct key in js',
+ code: '$t("components.hello.world")',
+ options: options,
+ filename: '/src/components/hello.js',
+ },
+ {
+ name: 'allows correct key in vue component js',
+ code: '',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ },
+ {
+ name: 'allows correct key in vue component setup script',
+ code: '',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ },
+ {
+ name: 'allows correct key in scoped use in vue component js',
+ code: '',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ },
+ {
+ name: 'allows correct key in vue component template mustache syntax',
+ code: '{{ $t("components.helloWorld.foo") }} ',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ },
+ {
+ name: 'allows correct key in vue component template v-bind',
+ code: '
',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ },
+ {
+ name: 'allows correct key in vue component template i18n prop, based on translationKeyPropRegex',
+ code: '
',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ },
+ {
+ name: 'allows correct key in vue component template v-bind i18n prop, based on translationKeyPropRegex',
+ code: '
',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ },
+ {
+ name: 'ignores valueless prop in vue component template i18n prop, based on translationKeyPropRegex',
+ code: '
',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ },
+ {
+ name: 'allows global key, based on ignoreKeysRegex',
+ code: '$t("global.something")',
+ options: options,
+ filename: '/src/components/hello.js',
+ },
+ {
+ name: 'allows correct key with complex directory names',
+ code: '$t("components.camelCase.kebabCase.pascalCase.withPeriod.hello.world")',
+ options: options,
+ filename: '/src/components/camelCase/kebab-case/PascalCase/with.period/hello.js',
+ },
+ {
+ name: 'allows correct key with single quotes',
+ code: "$t('components.hello.world')",
+ options: options,
+ filename: '/src/components/hello.js',
+ },
+ {
+ name: 'allows correct key with single quotes',
+ code: '$t(\'components.hello.world\', 0, { test: "foo" })',
+ options: options,
+ filename: '/src/components/hello.js',
+ },
+ {
+ name: 'allows correct key with backticks',
+ code: '$t(`components.hello.world`)',
+ options: options,
+ filename: '/src/components/hello.js',
+ },
+ {
+ name: 'allows correct key with arguments',
+ code: '$t("components.hello.world", 0, { test: "foo" })',
+ options: options,
+ filename: '/src/components/hello.js',
+ },
+ {
+ name: 'allows correct key when used without dollar sign',
+ code: 't(\'components.hello.world\', 0, { test: "foo" })',
+ options: options,
+ filename: '/src/components/hello.js',
+ },
+ {
+ name: 'ignores call without arguments',
+ code: '$t()',
+ options: options,
+ filename: '/src/components/hello.js',
+ },
+ {
+ name: 'ignores unrelated file type',
+ code: "$t('hello.world')",
+ options: options,
+ filename: '/src/components/hello.json',
+ },
+ {
+ name: 'ignores test file',
+ code: "$t('hello.world')",
+ options: options,
+ filename: '/src/components/hello.spec.js',
+ },
+ {
+ name: 'ignores test helper file',
+ code: "$t('hello.world')",
+ options: options,
+ filename: '/src/components/__tests__/hello.js',
+ },
+ {
+ name: 'ignores e2e test file',
+ code: "$t('hello.world')",
+ options: options,
+ filename: '/src/e2e/hello.js',
+ },
+ {
+ name: 'accepts source file paths which do not start with /src',
+ code: '$t("components.hello.world")',
+ options: options,
+ filename: '/components/hello.js',
+ },
+ ],
+
+ invalid: [
+ {
+ name: 'lints incorrect key in js',
+ code: '$t("hello.world")',
+ options: options,
+ filename: '/src/components/hello.js',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.hello.`, based on file path `components/hello`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key in vue component js',
+ code: '',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.helloWorld.`, based on file path `components/HelloWorld`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key in vue component setup script',
+ code: '',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.helloWorld.`, based on file path `components/HelloWorld`.',
+ },
+ ],
+ },
+ {
+ name: 'lints correct key in scoped use in vue component js',
+ code: '',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.helloWorld.`, based on file path `components/HelloWorld`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key in vue component template mustache syntax',
+ code: '{{ $t("hello.world") }} ',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.helloWorld.`, based on file path `components/HelloWorld`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key in vue component template v-bind',
+ code: '
',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.helloWorld.`, based on file path `components/HelloWorld`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key in component template i18n prop, based on translationKeyPropRegex',
+ code: '
',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.helloWorld.`, based on file path `components/HelloWorld`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key in vue component template v-bind i18n prop, based on translationKeyPropRegex',
+ code: '
',
+ options: options,
+ filename: '/src/components/HelloWorld.vue',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.helloWorld.`, based on file path `components/HelloWorld`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect global key, based on ignoreKeysRegex',
+ code: '$t("something.containing.global.hello.world")',
+ options: options,
+ filename: '/src/components/hello.js',
+ errors: [
+ {
+ message:
+ 'Translation key `something.containing.global.hello.world` should start with `components.hello.`, based on file path `components/hello`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key with single quotes',
+ code: "$t('hello.world')",
+ options: options,
+ filename: '/src/components/hello.js',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.hello.`, based on file path `components/hello`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key with backticks',
+ code: '$t(`hello.world`)',
+ options: options,
+ filename: '/src/components/hello.js',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.hello.`, based on file path `components/hello`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key with arguments',
+ code: '$t(\'hello.world\', 0, { test: "foo" })',
+ options: options,
+ filename: '/src/components/hello.js',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.hello.`, based on file path `components/hello`.',
+ },
+ ],
+ },
+ {
+ name: 'lints incorrect key when used without dollar sign',
+ code: 't(\'hello.world\', 0, { test: "foo" })',
+ options: options,
+ filename: '/src/components/hello.js',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.hello.`, based on file path `components/hello`.',
+ },
+ ],
+ },
+ {
+ name: 'lints empty key in js',
+ code: '$t("")',
+ options: options,
+ filename: '/src/components/hello.js',
+ errors: [
+ {
+ message:
+ 'Translation key `` should start with `components.hello.`, based on file path `components/hello`.',
+ },
+ ],
+ },
+ {
+ name: 'lints in file with path which does not start with src/',
+ code: '$t("hello.world")',
+ options: options,
+ filename: '/components/hello.js',
+ errors: [
+ {
+ message:
+ 'Translation key `hello.world` should start with `components.hello.`, based on file path `components/hello`.',
+ },
+ ],
+ },
+ ],
+})
diff --git a/frontend-vue3/src/common/eslint-local-rules/__tests__/packageDirectory.spec.js b/frontend-vue3/src/common/eslint-local-rules/__tests__/packageDirectory.spec.js
new file mode 100644
index 0000000000..49248cb800
--- /dev/null
+++ b/frontend-vue3/src/common/eslint-local-rules/__tests__/packageDirectory.spec.js
@@ -0,0 +1,13 @@
+import { describe, expect, it } from 'vitest'
+import { packageDirectory } from '../packageDirectory.js'
+import path from 'path'
+import fs from 'fs'
+
+describe('packageDirectory', () => {
+ it('resolves the location of the closest package.json', () => {
+ const packageJsonFile = path.resolve(__dirname, '../../package.json')
+ fs.writeFileSync(packageJsonFile, '{}')
+ expect(packageDirectory(__dirname)).toEqual(path.resolve(__dirname, '../..'))
+ fs.unlinkSync(packageJsonFile)
+ })
+})
diff --git a/frontend-vue3/src/common/eslint-local-rules/matchingTranslationKeys.js b/frontend-vue3/src/common/eslint-local-rules/matchingTranslationKeys.js
new file mode 100644
index 0000000000..ec3dc95289
--- /dev/null
+++ b/frontend-vue3/src/common/eslint-local-rules/matchingTranslationKeys.js
@@ -0,0 +1,233 @@
+import { packageDirectory } from "./packageDirectory.js"
+import path from "path"
+
+export default function createMatchingTranslationKeys(utils) {
+
+ /**
+ * Convert a file path to our convention for translation key structures
+ */
+ function pathToTranslationKeyStructure(str) {
+ return (
+ str
+ // convert words to camel case
+ .replace(/[-_.](\w)/gu, (_, c) => (c ? c.toUpperCase() : ''))
+ // convert slashes to dots with lower case letter after them
+ .replace(/\/(\w)/gu, (_, c) => '.' + (c ? c.toLowerCase() : ''))
+ )
+ }
+
+ /**
+ * Escape a string for use in a regular expression
+ */
+ function escapeForRegExp(str) {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
+ }
+
+ /**
+ * Read the value of a string literal
+ */
+ function getStringLiteral(node) {
+ if (node && utils.isStringLiteral(node)) {
+ const value = utils.getStringLiteralValue(node)
+ if (value != null) {
+ return { name: value, value, loc: node.loc }
+ }
+ }
+
+ // cannot check
+ return null
+ }
+
+ /**
+ * Get the first method argument, including source location, from the given CallExpression
+ */
+ function getFirstMethodArgument(node) {
+ return getStringLiteral(node.arguments[0])
+ }
+
+ /**
+ * Get the called method name from the given CallExpression
+ */
+ function getCalledMethodName(node) {
+ const callee = utils.skipChainExpression(node.callee)
+ if (callee.type === 'Identifier') {
+ return callee.name
+ }
+ if (callee.type === 'MemberExpression') {
+ return utils.getStaticPropertyName(callee)
+ }
+ return null
+ }
+
+ /**
+ * Gets the key of the given attribute node.
+ * E.g. given a node which represents the attribute id="my-header",
+ * this function would return "id"
+ */
+ function getKeyName(attr) {
+ if (attr.directive) {
+ if (attr.key.name.name !== 'bind') {
+ // We are only interested in plain attrs and in v-bind attrs (which start with a colon)
+ return null
+ }
+ return attr.key.argument?.name
+ }
+ return attr.key.name
+ }
+
+ /**
+ * Gets the value of the given attribute node.
+ * E.g. given a node which represents the attribute id="my-header",
+ * this function would return "my-header"
+ */
+ function getPropValue(attr) {
+ const valueNode = attr.value
+ let value = null
+ if (!valueNode) {
+ return value
+ }
+ if (valueNode.type === 'VExpressionContainer') {
+ // The attribute is probably using v-bind (or prefix : colon), so it has a dynamic value.
+ // Try to read it as a string literal, and give up otherwise.
+ value = getStringLiteral(valueNode.expression)
+ } else if (valueNode.type === 'VLiteral') {
+ value = valueNode
+ }
+ return value
+ }
+
+ function shouldProcessFile(filename) {
+ if (!(filename.endsWith('.vue') || filename.endsWith('.js'))) {
+ // We only process .vue components and .js files
+ return false
+ }
+ if (
+ filename.endsWith('.spec.js') ||
+ filename.match(/\/__tests__\//) ||
+ filename.match(/\/e2e\//)
+ ) {
+ // ignore test files
+ return false
+ }
+ return true
+ }
+
+ return {
+ meta: {
+ hasSuggestions: false, // We cannot easily auto-fix the translation JSON, so we can't make an automatic fix suggestion
+ type: 'suggestion',
+ docs: {
+ description:
+ "require translation keys in Vue components to match the component's file name",
+ },
+ schema: [
+ {
+ type: 'object',
+ properties: {
+ ignoreKeysRegex: {
+ type: 'string',
+ },
+ translationKeyPropRegex: {
+ type: 'string',
+ },
+ },
+ additionalProperties: false,
+ },
+ ],
+ },
+ create(context) {
+ const filename = context.getFilename()
+ if (!shouldProcessFile(filename)) {
+ // Return no visitor logic if the file is not of interest to us
+ return {}
+ }
+
+ const extension = path.extname(filename)
+ const filesystemPrefix = packageDirectory(filename)
+ const filepath = context
+ .getFilename()
+ .replace(new RegExp(`^${escapeForRegExp(filesystemPrefix)}/`), '')
+ // Optionally, remove src/ from the file path. We have this in frontend, but not in print
+ .replace(/^src\//, '')
+ .replace(new RegExp(`${escapeForRegExp(extension)}$`), '')
+
+ const ignoreKeysRegex = context.options?.[0]?.ignoreKeysRegex
+ const _ignoreKeysRegex = new RegExp(ignoreKeysRegex)
+
+ function verifyTranslationKey(methodArgument, filepath) {
+ const translationKey = methodArgument.value || ''
+ if (ignoreKeysRegex && translationKey.match(_ignoreKeysRegex)) {
+ // Some global keys are allowed everywhere
+ return
+ }
+
+ const expectedPrefix = pathToTranslationKeyStructure(filepath)
+
+ if (!translationKey.match(new RegExp(`^${escapeForRegExp(expectedPrefix)}\\.`))) {
+ context.report({
+ node: methodArgument,
+ message:
+ 'Translation key `{{translationKey}}` should start with `{{expectedPrefix}}.`, based on file path `{{filepath}}`.',
+ data: { expectedPrefix, translationKey, filepath },
+ })
+ }
+ }
+
+ const nodeVisitor = {
+ CallExpression(node) {
+ const calledMethodName = getCalledMethodName(node)
+ if (!['$tc', 'tc'].includes(calledMethodName)) {
+ // Not a translation call
+ return
+ }
+
+ const methodArgument = getFirstMethodArgument(node)
+ if (!methodArgument) {
+ // Cannot find the value for the first argument, so we cannot check
+ return
+ }
+
+ verifyTranslationKey(methodArgument, filepath)
+ },
+ }
+
+ const translationKeyPropRegex = context.options?.[0]?.translationKeyPropRegex
+ const _translationKeyPropRegex = new RegExp(translationKeyPropRegex)
+
+ /**
+ * Some props of some of our components accept a translation key, which they pass into
+ * the $tc function internally. We can check these translation keys as well.
+ */
+ const attributeVisitor = {
+ 'VElement > VStartTag > VAttribute': function (attr) {
+ const keyName = getKeyName(attr)
+ if (!keyName || !keyName.match(_translationKeyPropRegex)) {
+ // We are only interested in a very specific selection of props
+ return
+ }
+
+ const value = getPropValue(attr)
+ if (value === null) {
+ // Could not extract value, or value was null. Either way, there is nothing to verify
+ return
+ }
+
+ verifyTranslationKey(value, filepath)
+ },
+ }
+
+ return utils.defineTemplateBodyVisitor(
+ context,
+ // template visitor
+ {
+ ...nodeVisitor,
+ ...(translationKeyPropRegex ? attributeVisitor : {}),
+ },
+ // script visitor
+ utils.isScriptSetup(context)
+ ? utils.defineScriptSetupVisitor(context, nodeVisitor)
+ : nodeVisitor
+ )
+ },
+ }
+}
diff --git a/frontend-vue3/src/common/eslint-local-rules/packageDirectory.js b/frontend-vue3/src/common/eslint-local-rules/packageDirectory.js
new file mode 100644
index 0000000000..01bdca5468
--- /dev/null
+++ b/frontend-vue3/src/common/eslint-local-rules/packageDirectory.js
@@ -0,0 +1,21 @@
+import path from "path";
+import fs from "fs";
+
+export function packageDirectory(filename) {
+ const { root } = path.parse(filename)
+
+ let directory = filename
+ while (directory !== root) {
+ directory = path.dirname(directory)
+
+ try {
+ if (fs.statSync(path.resolve(directory, 'package.json')).isFile()) {
+ return directory
+ }
+ } catch {
+ // Ignore, try going up to the next directory
+ }
+ }
+
+ return ''
+}
diff --git a/frontend-vue3/src/common/helpers/__tests__/activityResponsibles.spec.js b/frontend-vue3/src/common/helpers/__tests__/activityResponsibles.spec.js
new file mode 100644
index 0000000000..0010dde01f
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/activityResponsibles.spec.js
@@ -0,0 +1,47 @@
+import { describe, expect, it } from "vitest";
+import { activityResponsiblesCommaSeparated } from '../activityResponsibles.js'
+
+describe('activityResponsibles', () => {
+ it('resolves camp collaboration with and without user', () => {
+ expect(
+ activityResponsiblesCommaSeparated(
+ {
+ activityResponsibles: () => ({
+ items: [
+ {
+ campCollaboration: () => ({
+ inviteEmail: 'test@example.com',
+ }),
+ },
+ {
+ campCollaboration: () => ({
+ user: () => ({
+ displayName: 'dummyUser',
+ }),
+ }),
+ },
+ ],
+ }),
+ },
+ null
+ )
+ ).toEqual('test@example.com, dummyUser')
+ })
+
+ it('return empty string if no resonsibles', () => {
+ expect(
+ activityResponsiblesCommaSeparated(
+ {
+ activityResponsibles: () => ({
+ items: [],
+ }),
+ },
+ null
+ )
+ ).toEqual('')
+ })
+
+ it('return empty string for null object', () => {
+ expect(activityResponsiblesCommaSeparated(null, null)).toEqual('')
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/campCollaborationDisplayName.spec.js b/frontend-vue3/src/common/helpers/__tests__/campCollaborationDisplayName.spec.js
new file mode 100644
index 0000000000..fc762ff8ea
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/campCollaborationDisplayName.spec.js
@@ -0,0 +1,35 @@
+import { describe, expect, it } from "vitest";
+import campCollaborationDisplayName from '../campCollaborationDisplayName.js'
+
+describe('campCollaborationDisplayName', () => {
+ it.each([
+ [{}, ''],
+ [null, ''],
+ [undefined, ''],
+ [{ inviteEmail: 'ecamp@ecamp3.ch', user: null }, 'ecamp@ecamp3.ch'],
+ [{ inviteEmail: null, user: () => ({ displayName: 'Bi-Pi' }) }, 'Bi-Pi'],
+ [{ inviteEmail: null, _meta: {} }, ''],
+ [{ inviteEmail: null, _meta: { loading: true } }, ''],
+ [{ inviteEmail: null, user: () => ({ _meta: { loading: true } }) }, ''],
+ [
+ { inviteEmail: null, status: 'inactive', user: () => ({ displayName: 'Bi-Pi' }) },
+ 'Bi-Pi (inaktiv)',
+ ],
+ [
+ { inviteEmail: 'ecamp@ecamp3.ch', status: 'inactive', user: null },
+ 'ecamp@ecamp3.ch (inaktiv)',
+ ],
+ ])('maps %p to %p', (input, expected) => {
+ expect(campCollaborationDisplayName(input, () => 'inaktiv')).toEqual(expected)
+ })
+
+ it('does not add inactive indicator', () => {
+ expect(
+ campCollaborationDisplayName(
+ { inviteEmail: null, status: 'inactive', user: () => ({ displayName: 'Bi-Pi' }) },
+ null,
+ false
+ )
+ ).toEqual('Bi-Pi')
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/campCollaborationInitials.spec.js b/frontend-vue3/src/common/helpers/__tests__/campCollaborationInitials.spec.js
new file mode 100644
index 0000000000..66cecb956e
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/campCollaborationInitials.spec.js
@@ -0,0 +1,30 @@
+import { describe, expect, it } from "vitest";
+import campCollaborationInitials from '../campCollaborationInitials.js'
+
+describe('campCollaborationInitials', () => {
+ it.each([
+ [{}, ''],
+ [null, ''],
+ [undefined, ''],
+ [{ inviteEmail: 'ecamp@ecamp3.ch', user: null }, 'EC'],
+ [{ inviteEmail: null, user: () => ({ displayName: 'Bi-Pi' }) }, 'BP'],
+ [{ inviteEmail: null, _meta: {} }, ''],
+ [{ inviteEmail: null, _meta: { loading: true } }, ''],
+ [{ inviteEmail: null, user: () => ({ _meta: { loading: true } }) }, ''],
+ [
+ { inviteEmail: null, status: 'inactive', user: () => ({ displayName: 'Bam' }) },
+ 'BA',
+ ],
+ [{ inviteEmail: 'ecamp@ecamp3.ch', status: 'inactive', user: null }, 'EC'],
+ [{ abbreviation: 'B', inviteEmail: null, user: null }, 'B'],
+ [{ abbreviation: 'AA', user: () => ({ displayName: 'Bi-Pi' }) }, 'AA'],
+ [
+ { abbreviation: 'AA', user: () => ({ abbreviation: 'CC', displayName: 'Bi-Pi' }) },
+ 'AA',
+ ],
+ [{ user: () => ({ abbreviation: 'QQ' }) }, 'QQ'],
+ [{ user: () => ({ abbreviation: 'QQ', displayName: 'Bi-Pi' }) }, 'QQ'],
+ ])('maps %o to "%s"', (input, expected) => {
+ expect(campCollaborationInitials(input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/campCollaborationLegalName.spec.js b/frontend-vue3/src/common/helpers/__tests__/campCollaborationLegalName.spec.js
new file mode 100644
index 0000000000..93cd7dda77
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/campCollaborationLegalName.spec.js
@@ -0,0 +1,36 @@
+import { describe, expect, it } from "vitest";
+import campCollaborationLegalName from '../campCollaborationLegalName.js'
+
+describe('campCollaborationLegalName', () => {
+ it.each([
+ [{}, ''],
+ [null, ''],
+ [undefined, ''],
+ [{ inviteEmail: 'ecamp@ecamp3.ch', user: null }, ''],
+ [
+ {
+ inviteEmail: null,
+ user: () => ({ profile: () => ({ legalName: 'Bi-Pi', _meta: {} }) }),
+ },
+ 'Bi-Pi',
+ ],
+ [{ inviteEmail: null, _meta: {} }, ''],
+ [{ inviteEmail: null, _meta: { loading: true } }, ''],
+ [
+ {
+ inviteEmail: null,
+ user: () => ({ _meta: { loading: true }, profile: () => ({ _meta: {} }) }),
+ },
+ '',
+ ],
+ [
+ {
+ inviteEmail: null,
+ user: () => ({ profile: () => ({ _meta: { loading: true, _meta: {} } }) }),
+ },
+ '',
+ ],
+ ])('maps %p to %p', (input, expected) => {
+ expect(campCollaborationLegalName(input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/campShortTitle.spec.js b/frontend-vue3/src/common/helpers/__tests__/campShortTitle.spec.js
new file mode 100644
index 0000000000..ed452cf03f
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/campShortTitle.spec.js
@@ -0,0 +1,54 @@
+import { describe, expect, it } from 'vitest'
+import { campShortTitle } from '../campShortTitle.js'
+
+describe('campShortTitle', () => {
+ it.each([
+ [{ shortTitle: null, title: 'Sommerlager Pfadistufe 2024' }, 'SoLa24 Pfadis'],
+ [{ shortTitle: null, title: 'HeLa Wolfsstufe 2024' }, 'HeLa24 Wölfli'],
+ [{ shortTitle: null, title: 'Bezirkspfingstlager Rover 2025' }, 'BezPfiLa25 Rover'],
+ [{ shortTitle: null, title: 'PfiLa Pfadistufe 2024' }, 'PfiLa24 Pfadis'],
+ [{ shortTitle: null, title: 'Pfingstlager 2024' }, 'PfiLa 2024'],
+ [{ shortTitle: null, title: 'Pio SoLa 2024' }, 'Pio SoLa 2024'],
+ [{ shortTitle: null, title: 'Herbstlager 2024' }, 'HeLa 2024'],
+ [{ shortTitle: null, title: 'Auffahrtslager 2025 Pfadi Olymp' }, 'AufLa25PfadiOlym'],
+ [{ shortTitle: null, title: 'Sola 2024 Jubla BuechBerg' }, 'SoLa24JublaBuech'],
+ [{ shortTitle: null, title: 'Pfingstlager PTA Bern 2024' }, 'PfiLa24 PTA Bern'],
+ [{ shortTitle: null, title: 'PfiLa 24 -Wolfsstufe Falkenstein' }, 'PfiLa24-WölfliFa'],
+ [{ shortTitle: null, title: 'MoBe Klassenlager 2018 Scuol' }, 'MoBeKlaLa18Scuol'],
+ [{ shortTitle: null, title: 'Cevilager Thun 2024' }, 'Cevilager24 Thun'],
+ [{ shortTitle: null, title: 'Sommerlager Blauring 2024' }, 'SoLa24 Blauring'],
+ [{ shortTitle: null, title: 'Sola24 Pfadistufe und Wölfli' }, 'SoLa24Pfadis&Wöl'],
+ [{ shortTitle: null, title: 'Dracheburg Pfila 2024' }, 'DracheburgPfiLa2'],
+ [{ shortTitle: null, title: 'Pio Bezirkspfila 2024' }, 'Pio BezPfiLa24'],
+ [{ shortTitle: null, title: 'Piostufensola 12.12.2026' }, 'PioSoLa26 12.12.'],
+
+ [{ shortTitle: null, title: "Camp d'été à Thun 2024" }, 'été à Thun 2024'],
+ [{ shortTitle: null, title: "Campo di Pentecoste 2024" }, 'Pentecoste 2024'],
+ [{ shortTitle: null, title: "Camp d'hiver PiCos 2025" }, "hiver PiCos 2025"],
+ [{ shortTitle: null, title: "Camp d'automne Eclais 2025" }, "Aut Eclais 2025"],
+ [{ shortTitle: null, title: "Camp de pâques 2025 louveteaux" }, "Pâq25louveteaux"],
+ [{ shortTitle: null, title: "Campo di primavera 2025 esploratori" }, "Prim 2025 esplos"],
+ [{ shortTitle: null, title: "Campo autunnale 2028" }, "autunnale 2028"],
+ [{ shortTitle: null, title: "Campo dell'Ascensione 2025 Esploratori" }, "Asc 2025 Esplos"],
+
+ [{ shortTitle: 'Pfila 2024', title: 'Pfingstlager 2024' }, 'Pfila 2024'],
+ [{ shortTitle: 'Pfila 2024', title: null }, 'Pfila 2024'],
+ [{ shortTitle: null, title: null }, ''],
+ [{ shortTitle: undefined, title: null }, ''],
+ [{ shortTitle: '0', title: 'Sola24' }, '0'],
+ [{ shortTitle: '', title: 'Sola24' }, 'SoLa24'],
+
+ //error cases
+ [{ shortTitle: 0, title: 'Sola24' }, '0'],
+ [{ shortTitle: false, title: 'Sola24' }, 'false'],
+ [{ shortTitle: true, title: 'Sola24' }, 'true'],
+ [{ shortTitle: {}, title: 'Sola24' }, '[object Object]'],
+ [{ shortTitle: Symbol('foo'), title: 'Sola24' }, 'SoLa24'],
+ [{ shortTitle: [], title: 'Sola24' }, ''],
+ [{ shortTitle: /test/, title: 'Sola24' }, '/test/'],
+ [null, ''],
+ [undefined, ''],
+ ])('maps "%s" to "%s"', (input, expected) => {
+ expect(campShortTitle(input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/colors.spec.js b/frontend-vue3/src/common/helpers/__tests__/colors.spec.js
new file mode 100644
index 0000000000..9eadb357f0
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/colors.spec.js
@@ -0,0 +1,62 @@
+import { describe, expect, it } from "vitest";
+import { campCollaborationColor, idToColor, userColor } from '../colors.js'
+
+describe('idToColor', () => {
+ it.each([
+ [[undefined, false], '#4d4d4d'],
+ [[null, false], '#4d4d4d'],
+ [['', false], '#4d4d4d'],
+ [['0000000', false], '#900'],
+ [['0000000', true], '#4d4d4d'],
+ [['fffffff', false], '#992600'],
+ [['Wrong input', false], '#900'],
+ ])('maps %p to %p', (input, expected) => {
+ expect(idToColor(...input)).toEqual(expected)
+ })
+
+ it('uses false as default for inactive', () => {
+ expect(idToColor('fffffff')).toEqual('#992600')
+ })
+})
+
+describe('userColor', () => {
+ it.each([
+ [{ id: 'fffffff' }, '#992600'],
+ [{ name: 'test' }, '#4d4d4d'],
+ [{ _meta: {} }, '#4d4d4d'],
+ [{ _meta: { loading: true } }, '#4d4d4d'],
+ [{ color: '#abcdef' }, '#abcdef'],
+ [{ color: '#abcdef', _meta: { loading: true } }, '#4d4d4d'],
+ ])('maps %p to %p', (input, expected) => {
+ expect(userColor(input)).toEqual(expected)
+ })
+})
+
+describe('campCollaborationColor', () => {
+ it.each([
+ [{}, '#4d4d4d'],
+ [null, '#4d4d4d'],
+ [undefined, '#4d4d4d'],
+ [{ id: 'fffffff', user: null }, '#992600'],
+ [{ id: 'fffffff', user: () => ({ id: '0000000' }) }, '#900'],
+ [{ id: 'fffffff', _meta: {} }, '#992600'],
+ [{ _meta: { loading: true } }, '#4d4d4d'],
+ [{ id: 'fffffff', user: () => ({ _meta: { loading: true } }) }, '#4d4d4d'],
+ [{ color: '#ECA110' }, '#ECA110'],
+ [{ color: '#ECA110', _meta: { loading: true } }, '#4d4d4d'],
+ [
+ { id: 'fffffff', user: () => ({ color: '#ECA110', _meta: { loading: true } }) },
+ '#4d4d4d',
+ ],
+ [
+ {
+ id: 'fffffff',
+ _meta: { loading: true },
+ user: () => ({ color: '#ECA110', _meta: { loading: true } }),
+ },
+ '#4d4d4d',
+ ],
+ ])('maps %o to "%s"', (input, expected) => {
+ expect(campCollaborationColor(input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/dateHelperUTCFormatted.spec.js b/frontend-vue3/src/common/helpers/__tests__/dateHelperUTCFormatted.spec.js
new file mode 100644
index 0000000000..7d645be2b3
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/dateHelperUTCFormatted.spec.js
@@ -0,0 +1,97 @@
+import { describe, expect, it } from "vitest";
+import {
+ dateRange,
+ rangeLongEnd,
+ rangeShort,
+ timeDurationShort,
+} from '../dateHelperUTCFormatted.js'
+
+const tcMock = (string, _, obj = {}) => {
+ return Object.entries(obj).reduce((previous, [key, value]) => {
+ return previous.replace(`{${key}}`, value)
+ }, tcMockString(string))
+}
+
+const tcMockString = (string) => {
+ switch (string) {
+ case 'global.datetime.dateLong':
+ return 'dd L'
+ case 'global.datetime.dateShort':
+ return 'dd D.M.'
+ case 'global.datetime.dateTimeLong':
+ return 'dd L HH:mm'
+ case 'global.datetime.hourLong':
+ return 'HH:mm'
+ case 'global.datetime.hourShort':
+ return 'H:mm'
+ case 'global.datetime.duration.minutesOnly':
+ return '{minutes}min'
+ case 'global.datetime.duration.hoursOnly':
+ return '{hours}h'
+ case 'global.datetime.duration.daysOnly':
+ return '{days}d'
+ case 'global.datetime.duration.daysAndHours':
+ return '{days}d {hours}h'
+ case 'global.datetime.duration.daysAndHoursAndMinutes':
+ return '{days}d {hours}h {minutes}min'
+ case 'global.datetime.duration.daysAndMinutes':
+ return '{days}d {minutes}min'
+ case 'global.datetime.duration.hoursAndMinutes':
+ return '{hours}h {minutes}min'
+ }
+}
+
+describe('timeDurationShort', function () {
+ it.each([
+ ['only day(s)', '1d', '2020-06-07T10:00:00.000Z', '2020-06-08T10:00:00.000Z'],
+ ['only hour(s)', '1h', '2020-06-07T10:00:00.000Z', '2020-06-07T11:00:00.000Z'],
+ ['only minute(s)', '30min', '2020-06-07T10:00:00.000Z', '2020-06-07T10:30:00.000Z'],
+ ['all', '2d 1h 30min', '2020-06-07T10:00:00.000Z', '2020-06-09T11:30:00.000Z'],
+ ['days&minutes', '2d 45min', '2020-06-07T10:00:00.000Z', '2020-06-09T10:45:00.000Z'],
+ ['hour&minutes', '1h 30min', '2020-06-07T10:00:00.000Z', '2020-06-07T11:30:00.000Z'],
+ ['leap year', '2d', '2020-02-28T10:00:00.000Z', '2020-03-01T10:00:00.000Z'],
+ ['year', '730d 1h 30min', '2020-06-07T10:00:00.000Z', '2022-06-07T11:30:00.000Z'],
+ ['0', '0min', '2020-06-07T10:00:00.000Z', '2020-06-07T10:00:00.000Z'],
+ ])('should print %s: %s', (_, duration, start, end) => {
+ expect(timeDurationShort(start, end, tcMock)).toEqual(duration)
+ })
+})
+
+describe('rangeShort', () => {
+ it('omits end date if it is the same as start date: Tu 1.1. 20:00 - 22:00', () => {
+ expect(
+ rangeShort('2019-01-01T20:00:00.000Z', '2019-01-01T22:00:00.000Z', tcMock)
+ ).toEqual('Tu 1.1. 20:00 - 22:00')
+ })
+ it('prints end date if it another date: Tu 1.1. 14:00 - We 2.1. 10:00', () => {
+ expect(
+ rangeShort('2019-01-01T14:00:00.000Z', '2019-01-02T10:00:00.000Z', tcMock)
+ ).toEqual('Tu 1.1. 14:00 - We 2.1. 10:00')
+ })
+})
+
+describe('rangeLongEnd', () => {
+ it('omits end date if it is the same as start date: 20:00 - 22:00', () => {
+ expect(
+ rangeLongEnd('2019-01-01T20:00:00.000Z', '2019-01-01T22:00:00.000Z', tcMock)
+ ).toEqual('20:00 - 22:00')
+ })
+ it('prints end date if it another date: 14:00 - We 2.1. 10:00', () => {
+ expect(
+ rangeLongEnd('2019-01-01T14:00:00.000Z', '2019-01-02T10:00:00.000Z', tcMock)
+ ).toEqual('14:00 - We 2.1. 10:00')
+ })
+})
+
+describe('dateRange', () => {
+ it('omits end date if it is the same as start date: Tu 01/01/2019', () => {
+ expect(
+ dateRange('2019-01-01T20:00:00.000Z', '2019-01-01T22:00:00.000Z', tcMock)
+ ).toEqual('Tu 01/01/2019')
+ })
+ it('prints end date if it another date: Tu 1.1. - We 01/02/2019', () => {
+ expect(
+ dateRange('2019-01-01T14:00:00.000Z', '2019-01-02T10:00:00.000Z', tcMock)
+ ).toEqual('Tu 1.1. - We 01/02/2019')
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/dayResponsibles.spec.js b/frontend-vue3/src/common/helpers/__tests__/dayResponsibles.spec.js
new file mode 100644
index 0000000000..e3623c8698
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/dayResponsibles.spec.js
@@ -0,0 +1,83 @@
+import { describe, expect, it } from "vitest";
+import {
+ dayResponsiblesCommaSeparated,
+ filterDayResponsiblesByDay,
+} from '../dayResponsibles'
+
+const dayWith2Responsibles = {
+ _meta: {
+ self: '/day/1',
+ },
+ period: () => ({
+ dayResponsibles: () => ({
+ items: [
+ {
+ campCollaboration: () => ({
+ inviteEmail: 'test@example.com',
+ }),
+ day: () => ({
+ _meta: { self: '/day/1' },
+ }),
+ },
+ {
+ campCollaboration: () => ({
+ user: () => ({
+ displayName: 'dummyUser',
+ }),
+ }),
+ day: () => ({
+ _meta: { self: '/day/1' },
+ }),
+ },
+ {
+ campCollaboration: () => ({
+ user: () => ({
+ displayName: 'responsibleUserOnAnotherDay',
+ }),
+ }),
+ day: () => ({
+ _meta: { self: '/day/2' },
+ }),
+ },
+ ],
+ }),
+ }),
+}
+
+const dayWithoutResponsibles = {
+ period: () => ({
+ dayResponsibles: () => ({
+ items: [],
+ }),
+ }),
+}
+
+describe('dayResponsiblesCommaSeparated', () => {
+ it('resolves camp collaboration with and without user', () => {
+ expect(dayResponsiblesCommaSeparated(dayWith2Responsibles, null)).toEqual(
+ 'test@example.com, dummyUser'
+ )
+ })
+
+ it('return empty string if no responsibles', () => {
+ expect(dayResponsiblesCommaSeparated(dayWithoutResponsibles, null)).toEqual('')
+ })
+
+ it('return empty string for null object', () => {
+ expect(dayResponsiblesCommaSeparated(null, null)).toEqual('')
+ })
+})
+
+describe('filterDayResponsiblesByDay', () => {
+ it('resolves camp collaboration with and without user', () => {
+ expect(filterDayResponsiblesByDay(dayWith2Responsibles).length).toEqual(2)
+ })
+
+ it('return empty string if no responsibles', () => {
+ expect(filterDayResponsiblesByDay(dayWithoutResponsibles)).toEqual([])
+ })
+
+ it('return empty string for null object', () => {
+ expect(filterDayResponsiblesByDay(null)).toEqual([])
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/filterMatchScheduleEntry.spec.js b/frontend-vue3/src/common/helpers/__tests__/filterMatchScheduleEntry.spec.js
new file mode 100644
index 0000000000..783a677edd
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/filterMatchScheduleEntry.spec.js
@@ -0,0 +1,142 @@
+import { describe, expect, it } from "vitest";
+import { filterMatchScheduleEntry } from '../filterMatchScheduleEntry.js'
+
+const scheduleEntry = {
+ period: () => ({ _meta: { self: '/periods/1a2b3c4d' } }),
+ day: () => ({ _meta: { self: '/days/1a2b3c4d' } }),
+ activity: () => ({
+ category: () => ({ _meta: { self: '/categories/1a2b3c4d' } }),
+ activityResponsibles: () => ({
+ items: [
+ { campCollaboration: () => ({ _meta: { self: '/camp_collaborations/1a2b3c4d' } }) },
+ { campCollaboration: () => ({ _meta: { self: '/camp_collaborations/ffffffff' } }) },
+ ]
+ }),
+ progressLabel: () => ({ _meta: { self: '/progress_labels/1a2b3c4d' } })
+ }),
+}
+
+describe('filterMatchScheduleEntry', () => {
+ it.each([
+ [null, true],
+ [undefined, true],
+ ['wrong input', true],
+ [{}, true],
+ [{ period: undefined }, true],
+ [{ period: null }, true],
+ [{ period: '/periods/1a2b3c4d' }, true],
+ [{ period: '/periods/00000000' }, false],
+ [{ period: ['/periods/1a2b3c4d'] }, false], // an array of periods is currently not supported
+ [{ day: undefined }, true],
+ [{ day: null }, true],
+ [{ day: '/days/1a2b3c4d' }, true],
+ [{ day: '/days/00000000' }, false],
+ [{ day: ['/days/1a2b3c4d'] }, true],
+ [{ day: ['/days/00000000'] }, false],
+ [{ day: ['/days/1a2b3c4d', '/days/00000000'] }, true],
+ [{ day: ['/days/00000000', '/days/1a2b3c4d'] }, true],
+ [{ category: undefined }, true],
+ [{ category: null }, true],
+ [{ category: '/categories/1a2b3c4d' }, true],
+ [{ category: '/categories/00000000' }, false],
+ [{ category: ['/categories/1a2b3c4d'] }, true],
+ [{ category: ['/categories/00000000'] }, false],
+ [{ category: ['/categories/1a2b3c4d', '/categories/00000000'] }, true],
+ [{ category: ['/categories/00000000', '/categories/1a2b3c4d'] }, true],
+ [{ responsible: undefined }, true],
+ [{ responsible: null }, true],
+ [{ responsible: ['/camp_collaborations/1a2b3c4d'] }, true],
+ [{ responsible: ['/camp_collaborations/00000000'] }, false],
+ [{ responsible: ['/camp_collaborations/1a2b3c4d', '/camp_collaborations/00000000'] }, false],
+ [{ responsible: ['/camp_collaborations/00000000', '/camp_collaborations/1a2b3c4d'] }, false],
+ [{ responsible: ['/camp_collaborations/1a2b3c4d', '/camp_collaborations/ffffffff'] }, true],
+ [{ responsible: ['/camp_collaborations/ffffffff', '/camp_collaborations/1a2b3c4d'] }, true],
+ [{ progressLabel: undefined }, true],
+ [{ progressLabel: null }, true],
+ [{ progressLabel: '/progress_labels/1a2b3c4d' }, true],
+ [{ progressLabel: '/progress_labels/00000000' }, false],
+ [{ progressLabel: ['/progress_labels/1a2b3c4d'] }, true],
+ [{ progressLabel: ['/progress_labels/00000000'] }, false],
+ [{ progressLabel: ['/progress_labels/1a2b3c4d', '/progress_labels/00000000'] }, true],
+ [{ progressLabel: ['/progress_labels/00000000', '/progress_labels/1a2b3c4d'] }, true],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: ['/days/1a2b3c4d'],
+ category: ['/categories/1a2b3c4d'],
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, true],
+ [{
+ period: null,
+ day: ['/days/1a2b3c4d'],
+ category: ['/categories/1a2b3c4d'],
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, true],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: null,
+ category: ['/categories/1a2b3c4d'],
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, true],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: ['/days/1a2b3c4d'],
+ category: null,
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, true],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: ['/days/1a2b3c4d'],
+ category: ['/categories/1a2b3c4d'],
+ responsible: null,
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, true],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: ['/days/1a2b3c4d'],
+ category: ['/categories/1a2b3c4d'],
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: null,
+ }, true],
+ [{
+ period: '/periods/00000000',
+ day: ['/days/1a2b3c4d'],
+ category: ['/categories/1a2b3c4d'],
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, false],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: ['/days/00000000'],
+ category: ['/categories/1a2b3c4d'],
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, false],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: ['/days/1a2b3c4d'],
+ category: ['/categories/00000000'],
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, false],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: ['/days/1a2b3c4d'],
+ category: ['/categories/1a2b3c4d'],
+ responsible: ['/camp_collaborations/00000000'],
+ progressLabel: ['/progress_labels/1a2b3c4d'],
+ }, false],
+ [{
+ period: '/periods/1a2b3c4d',
+ day: ['/days/1a2b3c4d'],
+ category: ['/categories/1a2b3c4d'],
+ responsible: ['/camp_collaborations/1a2b3c4d'],
+ progressLabel: ['/progress_labels/00000000'],
+ }, false],
+ ])('maps %o to %s', (filter, expected) => {
+ expect(filterMatchScheduleEntry(scheduleEntry, filter)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/initials.spec.js b/frontend-vue3/src/common/helpers/__tests__/initials.spec.js
new file mode 100644
index 0000000000..895b46db75
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/initials.spec.js
@@ -0,0 +1,29 @@
+import { describe, expect, it } from "vitest";
+import initials from '../initials.js'
+
+describe('initials', () => {
+ it.each([
+ [undefined, ''],
+ [null, ''],
+ ['', ''],
+ [' ', ''],
+ [' ', ''],
+ ['.,_', ''],
+ [':)', ':)'],
+ ['a', 'A'],
+ ['ab', 'AB'],
+ ['Ab', 'AB'],
+ ['aB', 'AB'],
+ ['Regulus Arcturus Black', 'RA'],
+ ['luke skywalker', 'LS'],
+ ['Luke', 'LU'],
+ ['eCamp', 'EC'],
+ ['Bi-Pi', 'BP'],
+ ['bi-pi@scouts.com', 'BP'],
+ ['ecamp@scouts.com', 'EC'],
+ ['Happy 😊', 'H😊'],
+ ['Ömer Çedille', 'ÖÇ'],
+ ])('maps %p to %p', (input, expected) => {
+ expect(initials(input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/interpolation.spec.js b/frontend-vue3/src/common/helpers/__tests__/interpolation.spec.js
new file mode 100644
index 0000000000..c0ee4cb51b
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/interpolation.spec.js
@@ -0,0 +1,66 @@
+import { describe, expect, it } from "vitest";
+import { lerp, clamp, invlerp, range } from '../interpolation.js'
+
+describe('lerp', () => {
+ it.each([
+ [[0, 50, 0.5], 25],
+ [[1, 3, 0.5], 2],
+ [[0, 5, 0.2], 1],
+ [[2, 7, 1], 7],
+ [[8, 4, 0.5], 6],
+ [[5, 4, 1], 4],
+ [[3, 7, 2], 11],
+ [[2, 3, 3], 5],
+ [[-8, -4, 0.5], -6],
+ [[-2, -4, 0.25], -2.5],
+ [[0, 10, 0.1], 1],
+ [[10, 50, 1], 50],
+ ])('maps %p to %p', (input, expected) => {
+ expect(lerp(...input)).toEqual(expected)
+ })
+})
+
+describe('clamp', () => {
+ it.each([
+ [[0.5, 0, 50], 0.5],
+ [[3, 0, 5], 3],
+ [[2, -5, 10], 2],
+ [[8, 1, 3], 3],
+ [[5, -1, 2], 2],
+ [[3, 5, 10], 5],
+ [[1, 2, 3], 2],
+ [[11, 0, 10], 10],
+ [[1, 10, 50], 10],
+ ])('maps %p to %p', (input, expected) => {
+ expect(clamp(...input)).toEqual(expected)
+ })
+})
+
+describe('invlerp', () => {
+ it.each([
+ [[0, 2, 1], 0.5],
+ [[-10, 0, -5], 0.5],
+ [[-10, 10, 8], 0.9],
+ [[3, 7, 5], 0.5],
+ [[-1, 1, 10], 1],
+ [[99, 101, 42], 0],
+ [[-100, 100, -100], 0],
+ ])('maps %p to %p', (input, expected) => {
+ expect(invlerp(...input)).toEqual(expected)
+ })
+})
+
+describe('range', () => {
+ it.each([
+ [[0, 1, 10, 20, 0.5], 15],
+ [[10, 0, 20, 40, 7.5], 25],
+ [[-10, 10, 8, 96, 5], 74],
+ [[16, 32, 8, 14, 24], 11],
+ [[-100, 100, 0, 100, 0], 50],
+ [[-100, 100, 0, 100, 50], 75],
+ [[42, 42, 0, 100, 42], NaN],
+ [[1337, 50, 0, 100, 42], 100],
+ ])('maps %p to %p', (input, expected) => {
+ expect(range(...input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/materialListsSorted.spec.js b/frontend-vue3/src/common/helpers/__tests__/materialListsSorted.spec.js
new file mode 100644
index 0000000000..ca4327cb45
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/materialListsSorted.spec.js
@@ -0,0 +1,22 @@
+import { describe, expect, it } from "vitest";
+import materialListsSorted from '../materialListsSorted.js'
+
+describe('materialListsSorted', () => {
+ const list1 = { campCollaboration: '1a2b3c4d', name: 'B2-name' }
+ const list2 = { campCollaboration: '1a2b3c4d', name: 'b1-name' }
+ const list3 = { campCollaboration: '1a2b3c4d', name: 'a3-name' }
+ const list4 = { campCollaboration: null, name: 'B2-name' }
+ const list5 = { campCollaboration: null, name: 'b1-name' }
+ const list6 = { campCollaboration: null, name: 'a3-name' }
+
+ it('sorts Non-User bevor User-Lists, then alphabetically', () => {
+ expect(materialListsSorted([list1, list2, list3, list4, list5, list6])).toEqual([
+ list6,
+ list5,
+ list4,
+ list3,
+ list2,
+ list1,
+ ])
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/picasso.spec.js b/frontend-vue3/src/common/helpers/__tests__/picasso.spec.js
new file mode 100644
index 0000000000..ed3c1883cd
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/picasso.spec.js
@@ -0,0 +1,259 @@
+import { describe, expect, it } from "vitest";
+import { splitDaysIntoPages, calculateBedtime } from '../picasso.js'
+import dayjs from '@/common/helpers/dayjs.js'
+
+describe('splitPicassoIntoPages', () => {
+ function daysBetween(start, end) {
+ // Generates an array [start, start + 1, start + 2, ..., end - 1, end]
+ return [...Array(end - start + 1).keys()].map((day) => day + start)
+ }
+
+ it.each([
+ [[[], 1], []],
+ [[[], 8], []],
+ [[[], 0], []],
+ [
+ [daysBetween(1, 3), 2],
+ [daysBetween(1, 2), daysBetween(3, 3)],
+ ],
+ [
+ [daysBetween(1, 15), 8],
+ [daysBetween(1, 8), daysBetween(9, 15)],
+ ],
+ [
+ [daysBetween(1, 14), 4],
+ [daysBetween(1, 4), daysBetween(5, 8), daysBetween(9, 11), daysBetween(12, 14)],
+ ],
+ ])('maps %p to %p', (input, expected) => {
+ expect(splitDaysIntoPages(...input)).toEqual(expected)
+ })
+})
+
+describe('calculateBedtime', () => {
+ it.each([
+ [
+ 'no schedule entries',
+ [
+ [],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-03T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 0, bedtime: 24 },
+ ],
+ [
+ 'single schedule entry',
+ [
+ [{ start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T10:00:00+00:00' }],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-03T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 10 },
+ ],
+ [
+ 'single schedule entry, not ending on full hours',
+ [
+ [{ start: '2022-01-02T08:15:00+00:00', end: '2022-01-02T09:35:00+00:00' }],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-03T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 10 },
+ ],
+ [
+ 'two schedule entries, forcing the gap to end before the first schedule entry even though there is a larger gap during the day',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T10:00:00+00:00' },
+ { start: '2022-01-02T20:00:00+00:00', end: '2022-01-02T23:00:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-03T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 23 },
+ ],
+ [
+ 'schedule entry across midnight',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T17:00:00+00:00' },
+ { start: '2022-01-02T20:00:00+00:00', end: '2022-01-02T23:00:00+00:00' },
+ { start: '2022-01-02T23:00:00+00:00', end: '2022-01-03T02:00:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 26 },
+ ],
+ [
+ 'schedule entry through the night, end is not cut off',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T17:00:00+00:00' },
+ { start: '2022-01-02T20:00:00+00:00', end: '2022-01-02T23:00:00+00:00' },
+ { start: '2022-01-02T23:00:00+00:00', end: '2022-01-03T06:00:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 5, bedtime: 24 },
+ ],
+ [
+ '24hour schedule entry does not block whole day',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T17:00:00+00:00' },
+ { start: '2022-01-02T20:00:00+00:00', end: '2022-01-02T23:00:00+00:00' },
+ { start: '2022-01-02T23:00:00+00:00', end: '2022-01-03T02:00:00+00:00' },
+ { start: '2022-01-03T12:00:00+00:00', end: '2022-01-04T12:00:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-05T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 26 },
+ ],
+ [
+ 'schedule entry starting at bedtime on a full hour moves the bedtime later, to avoid hiding the schedule entry completely',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-02T22:00:00+00:00', end: '2022-01-03T08:30:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 23 },
+ ],
+ [
+ 'schedule entry starting around bedtime on a half hour does not move the bedtime, because it is already visible enough',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-02T21:30:00+00:00', end: '2022-01-03T08:30:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 22 },
+ ],
+ [
+ 'schedule entry starting around bedtime on a quarter hour moves the bedtime later, to make sure it is visible for at least half an hour',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-02T21:45:00+00:00', end: '2022-01-03T08:30:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 23 },
+ ],
+ [
+ 'very short schedule entry starting around bedtime does not move the bedtime later, because it would not gain more visibility',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-02T21:45:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-02T20:00:00+00:00', end: '2022-01-03T08:30:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 22 },
+ ],
+ [
+ 'schedule entry ending at getUpTime on a full hour moves the getUpTime earlier, to avoid hiding the schedule entry completely',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-02T21:30:00+00:00', end: '2022-01-03T08:00:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 7, bedtime: 22 },
+ ],
+ [
+ 'schedule entry ending around getUpTime on a half hour does not move the getUpTime, because it is already visible enough',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-02T21:30:00+00:00', end: '2022-01-03T08:30:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 22 },
+ ],
+ [
+ 'schedule entry ending around getUpTime on a quarter hour moves the getUpTime earlier, to make sure it is visible for at least half an hour',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-02T21:30:00+00:00', end: '2022-01-03T08:15:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 7, bedtime: 22 },
+ ],
+ [
+ 'very short schedule entry ending around getUpTime does not move the getUpTime earlier, because it would not gain more visibility',
+ [
+ [
+ { start: '2022-01-02T08:00:00+00:00', end: '2022-01-02T22:00:00+00:00' },
+ { start: '2022-01-03T08:00:00+00:00', end: '2022-01-03T08:15:00+00:00' },
+ { start: '2022-01-02T21:30:00+00:00', end: '2022-01-03T09:00:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 8, bedtime: 22 },
+ ],
+ [
+ 'empty first day, schedule entries only towards end of last day, latestGetUpTime falls back to a sensible value',
+ [
+ [
+ { start: '2022-01-03T18:00:00+00:00', end: '2022-01-03T19:00:00+00:00' },
+ { start: '2022-01-03T20:00:00+00:00', end: '2022-01-03T21:00:00+00:00' },
+ { start: '2022-01-03T22:00:00+00:00', end: '2022-01-03T23:00:00+00:00' },
+ ],
+ dayjs,
+ dayjs.utc('2022-01-02T00:00:00+00:00'),
+ dayjs.utc('2022-01-04T00:00:00+00:00'),
+ 1,
+ ],
+ { getUpTime: 18, bedtime: 23 },
+ ],
+ ])('%p', (title, input, expected) => {
+ expect(calculateBedtime(...input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/scheduleEntryLayout.spec.js b/frontend-vue3/src/common/helpers/__tests__/scheduleEntryLayout.spec.js
new file mode 100644
index 0000000000..298b1e576c
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/scheduleEntryLayout.spec.js
@@ -0,0 +1,47 @@
+import { expect, it } from 'vitest'
+import { arrange } from '../scheduleEntryLayout.js'
+
+it('should handle empty list', () => {
+ expect(arrange([])).toEqual([])
+})
+it('should arrange schedule entries in columns', () => {
+ const p0 = {
+ id: '0',
+ start: '2019-02-13 07:30',
+ end: '2019-02-13 08:30',
+ }
+ const p1 = {
+ id: '1',
+ start: '2019-02-13 08:00',
+ end: '2019-02-13 09:00',
+ }
+ const p2 = {
+ id: '2',
+ start: '2019-02-13 09:00',
+ end: '2019-02-13 10:00',
+ }
+ const p3 = {
+ id: '3',
+ start: '2019-02-10 00:00',
+ end: '2019-02-13 07:00',
+ }
+ const p4 = {
+ id: '4',
+ start: '2019-02-13 07:00',
+ end: '2019-02-13 10:00',
+ }
+ const p5 = {
+ id: '5',
+ start: '2019-02-13 08:00',
+ end: '2019-02-13 12:00',
+ }
+
+ expect(arrange([p0, p1, p2, p3, p4, p5])).toMatchObject([
+ { id: '3', left: 0, width: 100 },
+ { id: '4', left: 0, width: 25 },
+ { id: '0', left: 25, width: 25 },
+ { id: '5', left: 50, width: 25 },
+ { id: '1', left: 75, width: 25 },
+ { id: '2', left: 25, width: 25 },
+ ])
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/userDisplayName.spec.js b/frontend-vue3/src/common/helpers/__tests__/userDisplayName.spec.js
new file mode 100644
index 0000000000..72a7a429c4
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/userDisplayName.spec.js
@@ -0,0 +1,13 @@
+import { describe, expect, it } from "vitest";
+import userDisplayName from '../userDisplayName.js'
+
+describe('userDisplayName', () => {
+ it.each([
+ [{ id: 'fffffff' }, ''],
+ [{ displayName: 'test' }, 'test'],
+ [{ displayName: 'test', _meta: {} }, 'test'],
+ [{ _meta: { loading: true } }, ''],
+ ])('maps %p to %p', (input, expected) => {
+ expect(userDisplayName(input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/userInitials.spec.js b/frontend-vue3/src/common/helpers/__tests__/userInitials.spec.js
new file mode 100644
index 0000000000..9dbb8c9e1d
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/userInitials.spec.js
@@ -0,0 +1,17 @@
+import { describe, expect, it } from "vitest";
+import userInitials from '../userInitials.js'
+
+describe('userInitials', () => {
+ it.each([
+ [{}, ''],
+ [null, ''],
+ [undefined, ''],
+ [{ id: 'fffffff' }, ''],
+ [{ displayName: 'test' }, 'TE'],
+ [{ displayName: 'test', _meta: {} }, 'TE'],
+ [{ _meta: { loading: true } }, ''],
+ [{ abbreviation: 'V3', displayName: 'test' }, 'V3'],
+ ])('maps %o to "%s"', (input, expected) => {
+ expect(userInitials(input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/__tests__/userLegalName.spec.js b/frontend-vue3/src/common/helpers/__tests__/userLegalName.spec.js
new file mode 100644
index 0000000000..236bade2fd
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/__tests__/userLegalName.spec.js
@@ -0,0 +1,14 @@
+import { describe, expect, it } from 'vitest'
+import userLegalName from '../userLegalName.js'
+
+describe('userLegalName', () => {
+ it.each([
+ [{ id: 'fffffff', profile: () => ({ _meta: {} }) }, ''],
+ [{ profile: () => ({ legalName: 'test', _meta: {} }) }, 'test'],
+ [{ profile: () => ({ legalName: 'test', _meta: {} }), _meta: {} }, 'test'],
+ [{ profile: () => ({ _meta: {} }), _meta: { loading: true } }, ''],
+ [{ profile: () => ({ _meta: { loading: true } }) }, ''],
+ ])('maps %p to %p', (input, expected) => {
+ expect(userLegalName(input)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/activityResponsibles.js b/frontend-vue3/src/common/helpers/activityResponsibles.js
new file mode 100644
index 0000000000..b2fd9ab8ec
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/activityResponsibles.js
@@ -0,0 +1,17 @@
+import campCollaborationDisplayName from './campCollaborationDisplayName.js'
+
+/**
+ * Returns a display name for a camp collaboration based on its status
+ */
+const activityResponsiblesCommaSeparated = (activity, tc) => {
+ if (!activity) return ''
+
+ return activity
+ .activityResponsibles()
+ .items.map((activityResponsible) =>
+ campCollaborationDisplayName(activityResponsible.campCollaboration(), tc)
+ )
+ .join(', ')
+}
+
+export { activityResponsiblesCommaSeparated }
diff --git a/frontend-vue3/src/common/helpers/campCollaborationDisplayName.js b/frontend-vue3/src/common/helpers/campCollaborationDisplayName.js
new file mode 100644
index 0000000000..96a5101c28
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/campCollaborationDisplayName.js
@@ -0,0 +1,21 @@
+import userDisplayName from './userDisplayName.js'
+
+/**
+ * Returns a display name for a camp collaboration based on its status
+ */
+export default function (campCollaboration, tc, indicateInactive = true) {
+ if (!campCollaboration) {
+ return ''
+ }
+
+ let text =
+ typeof campCollaboration.user === 'function'
+ ? userDisplayName(campCollaboration.user())
+ : campCollaboration.inviteEmail || ''
+
+ if (campCollaboration.status === 'inactive' && indicateInactive) {
+ text += ' (' + tc('entity.campCollaboration.status.inactive') + ')'
+ }
+
+ return text
+}
diff --git a/frontend-vue3/src/common/helpers/campCollaborationInitials.js b/frontend-vue3/src/common/helpers/campCollaborationInitials.js
new file mode 100644
index 0000000000..3ca2823bf5
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/campCollaborationInitials.js
@@ -0,0 +1,24 @@
+import userDisplayName from './userDisplayName.js'
+import initials from './initials.js'
+
+/**
+ * Returns two characters to display for a camp collaboration based on its user
+ */
+export default function (campCollaboration) {
+ if (!campCollaboration) {
+ return ''
+ }
+
+ if (campCollaboration?.abbreviation) {
+ return campCollaboration.abbreviation
+ }
+
+ if (typeof campCollaboration.user === 'function') {
+ if (campCollaboration.user().abbreviation) {
+ return campCollaboration.user().abbreviation
+ }
+ return initials(userDisplayName(campCollaboration.user()))
+ }
+
+ return initials(campCollaboration.inviteEmail || '')
+}
diff --git a/frontend-vue3/src/common/helpers/campCollaborationLegalName.js b/frontend-vue3/src/common/helpers/campCollaborationLegalName.js
new file mode 100644
index 0000000000..a9e1522fb5
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/campCollaborationLegalName.js
@@ -0,0 +1,14 @@
+import userLegalName from './userLegalName.js'
+
+/**
+ * Returns a legal name for a camp collaboration based on its status
+ */
+export default function (campCollaboration) {
+ if (!campCollaboration) {
+ return ''
+ }
+
+ return typeof campCollaboration.user === 'function'
+ ? userLegalName(campCollaboration.user())
+ : ''
+}
diff --git a/frontend-vue3/src/common/helpers/campShortTitle.js b/frontend-vue3/src/common/helpers/campShortTitle.js
new file mode 100644
index 0000000000..f173096e03
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/campShortTitle.js
@@ -0,0 +1,76 @@
+const AUTOMATIC_SHORTNERS = [
+ { regex: /So(?:mmer)?la(?:ger)?/gi, text: 'SoLa' },
+ { regex: /Pfi(?:ngst)?la(?:ger)?/gi, text: 'PfiLa' },
+ { regex: /He(?:rbst)?la(?:ger)?/gi, text: 'HeLa' },
+]
+
+const ADDITIONAL_SHORTNERS = [
+ { regex: /Auslandssola/gi, text: 'AuLa' },
+ { regex: /Auffahrtslager/gi, text: 'AufLa' },
+ { regex: /Abteilungslager/gi, text: 'AbLa' },
+ { regex: /Klassenlager/gi, text: 'KlaLa' },
+ {
+ regex: /(Bez)irks?(So|Ab|Au|Auf|He|Pfi)La|(Ka)ntonslager|(Bu)ndeslager/gi,
+ text: '$1$2$3$4La',
+ },
+ {
+ regex:
+ /(?.*?\b)?(?(?:[A-Za-z]{2,}La)|(?:[A-Za-z]{2,}lager))(?(?:\s(?!19|20))|.*?)\s?(?:(?:19|20)(?\d{2}))(?.*)/g,
+ text: '$$$$$',
+ },
+ { regex: /(Pfadi|Pio|Rover)stufe(?!n)/g, text: '$1s' },
+ { regex: /(B)ie?berstufe(?!n)/gi, text: '$1iberli' },
+ { regex: /(W)olfs?stufe(?!n)/gi, text: '$1ölfli' },
+ { regex: /(E)sploratori/gi, text: '$1splos' },
+ {
+ regex: /(Bie?ber|Wolfs?|Pfadi|Pio|Rover)stufen(So|Ab|Au|Auf|He|Pfi)La/gi,
+ text: '$1$2La',
+ },
+ {
+ regex: /Campo? (.*? ?)(?:(?: ?d[ei] )?(Pentec[ôo]te|Pentecoste|primavera|printemps|p[âa]ques|pasqua)|(?:d')?([ée]t[eé]|automne|hiver)|(estivo|autunnale|invernale)|(?:de[l ]l[' ])?(Ascensione?))? (.*? ?)*?((?:19|20)\d{2})?/gi,
+ text: '$2$3$4$5 $1$6$7',
+ },
+ { regex: /\bPrintemps/gi, text: 'Prt', },
+ { regex: /\bPrimavera/gi, text: 'Prim', },
+ { regex: /\bP[aâ]ques/gi, text: 'Pâq', },
+ { regex: /\bPasqua/gi, text: 'Pas', },
+ { regex: /\bAutomne/gi, text: 'Aut', },
+ { regex: /\bAutunno/gi, text: 'Aut', },
+ { regex: /\bHiver/gi, text: 'Hiv', },
+ { regex: /\bInverno/gi, text: 'Inv', },
+ { regex: /\bPentec[oô]s?te/gi, text: 'Pent', },
+ { regex: /\bAscensione?/gi, text: 'Asc', },
+ { regex: /\bEstate/gi, text: 'Est', },
+
+ { regex: /\b(?:und|et?)\b/g, text: '&' },
+ { regex: /\b(?:19|20)(\d{2})\b/g, text: '$1' },
+ { regex: /\s/g, text: '' },
+]
+
+function campShortTitle(camp) {
+ if (camp?.shortTitle != null && camp.shortTitle !== '' && typeof camp.shortTitle !== 'symbol') {
+ return `${camp.shortTitle}`.substring(0, 16)
+ }
+
+ let title = camp?.title ?? ''
+
+ for (const { regex, text } of AUTOMATIC_SHORTNERS) {
+ title = title.replace(regex, text)
+ }
+
+ if (title.length <= 16) {
+ return title
+ }
+
+ for (const { regex, text } of ADDITIONAL_SHORTNERS) {
+ title = title.replace(regex, text)
+ if (title.length <= 16) {
+ return title
+ }
+ }
+ return title.substring(0, 16)
+}
+
+export { campShortTitle }
+
+export default campShortTitle
diff --git a/frontend-vue3/src/common/helpers/colors.js b/frontend-vue3/src/common/helpers/colors.js
new file mode 100644
index 0000000000..4e654108c2
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/colors.js
@@ -0,0 +1,76 @@
+import Color from 'colorjs.io'
+
+/**
+ * @param color {string} CSS compatible string color
+ * @returns {string} colorblack or white depending on input color
+ */
+function contrastColor(color) {
+ const input = new Color(color)
+ const black = new Color('#000')
+ const white = new Color('#fff')
+ const blackContrast = Math.abs(input.contrast(black, 'APCA'))
+ const whiteContrast = Math.abs(input.contrast(white, 'APCA'))
+ return blackContrast > whiteContrast
+ ? black.toString({ format: 'hex' })
+ : white.toString({ format: 'hex' })
+}
+
+/**
+ * @param id {string} generated id
+ * @param inactive {boolean} status
+ * @returns {string} hsl color
+ */
+function idToColor(id, inactive = false) {
+ if (!id) {
+ return new Color('HSL', [0, 0, 30]).to('srgb').toString({ format: 'hex' })
+ }
+ return new Color('HSL', [parseInt(id, 16) % 360 || 0, inactive ? 0 : 100, 30])
+ .to('srgb')
+ .toString({ format: 'hex' })
+}
+
+/**
+ * @returns {string}
+ */
+function defaultColor() {
+ return new Color('HSL', [0, 0, 10]).toString({
+ format: 'hex',
+ })
+}
+
+/**
+ * @returns {string} color for a user based on their id
+ */
+function userColor(user, inactive = user._meta?.loading) {
+ if (user.color && !inactive) {
+ return user.color
+ }
+ return idToColor(user.id, inactive)
+}
+
+/**
+ * @returns {string} color for a camp collaboration based on its user id and status
+ */
+function campCollaborationColor(campCollaboration) {
+ if (!campCollaboration) {
+ return idToColor('', true)
+ }
+
+ const inactive =
+ campCollaboration._meta?.loading || campCollaboration.status === 'inactive'
+
+ if (campCollaboration?.color && !inactive) {
+ return campCollaboration.color
+ }
+
+ if (typeof campCollaboration.user === 'function') {
+ return userColor(
+ campCollaboration.user(),
+ inactive || campCollaboration.user()._meta?.loading
+ )
+ } else {
+ return idToColor(campCollaboration.id, inactive)
+ }
+}
+
+export { contrastColor, defaultColor, userColor, campCollaborationColor, idToColor }
diff --git a/frontend-vue3/src/common/helpers/dateFormat.js b/frontend-vue3/src/common/helpers/dateFormat.js
new file mode 100644
index 0000000000..43e34d5c45
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/dateFormat.js
@@ -0,0 +1,6 @@
+const HTML5_FMT = {
+ DATE: 'YYYY-MM-DD',
+ TIME: 'HH:mm',
+}
+
+export { HTML5_FMT }
diff --git a/frontend-vue3/src/common/helpers/dateHelperUTCFormatted.js b/frontend-vue3/src/common/helpers/dateHelperUTCFormatted.js
new file mode 100644
index 0000000000..2022715fd8
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/dateHelperUTCFormatted.js
@@ -0,0 +1,111 @@
+import dayjs from './dayjs.js'
+
+function dateShort(dateTimeString, tc) {
+ return dayjs.utc(dateTimeString).format(tc('global.datetime.dateShort'))
+}
+
+function dateLong(dateTimeString, tc) {
+ return dayjs.utc(dateTimeString).format(tc('global.datetime.dateLong'))
+}
+
+function hourShort(dateTimeString, tc) {
+ return dayjs.utc(dateTimeString).format(tc('global.datetime.hourShort'))
+}
+
+function hourLong(dateTimeString, tc) {
+ return dayjs.utc(dateTimeString).format(tc('global.datetime.hourLong'))
+}
+
+function timeDurationShort(start, end, tc) {
+ const startTime = dayjs.utc(start)
+ const endTime = dayjs.utc(end)
+ const duration = dayjs.duration(endTime.diff(startTime))
+
+ return tc(
+ duration.asDays() >= 1
+ ? duration.hours() === 0
+ ? duration.minutes() === 0
+ ? 'global.datetime.duration.daysOnly'
+ : 'global.datetime.duration.daysAndMinutes'
+ : duration.minutes() === 0
+ ? 'global.datetime.duration.daysAndHours'
+ : 'global.datetime.duration.daysAndHoursAndMinutes'
+ : duration.asMinutes() < 60
+ ? 'global.datetime.duration.minutesOnly'
+ : duration.minutes() === 0
+ ? 'global.datetime.duration.hoursOnly'
+ : 'global.datetime.duration.hoursAndMinutes',
+ 0,
+ {
+ days: Math.floor(duration.asDays()),
+ hours: duration.hours(),
+ minutes: duration.minutes(),
+ }
+ )
+}
+
+// short format of dateTime range
+// doesn't show any date
+function rangeTime(start, end, tc) {
+ return hourShort(start, tc) + ' - ' + hourShort(end, tc)
+}
+
+// short format of dateTime range
+// doesn't repeat end date if on the same day
+function rangeShort(start, end, tc) {
+ let result = ''
+
+ result += dateShort(start, tc)
+ result += ' '
+ result += hourShort(start, tc)
+
+ result += ' - '
+
+ if (dateShort(start, tc) !== dateShort(end, tc)) {
+ result += dateShort(end, tc)
+ result += ' '
+ }
+
+ result += hourShort(end, tc)
+
+ return result
+}
+
+// long end part of dateTime range format
+// doesn't repeat end date if on the same day
+function rangeLongEnd(start, end, tc) {
+ let result = ''
+
+ result += hourLong(start, tc)
+
+ result += ' - '
+
+ if (dateShort(start, tc) !== dateShort(end, tc)) {
+ result += dateShort(end, tc)
+ result += ' '
+ }
+
+ result += hourLong(end, tc)
+
+ return result
+}
+
+// format of date range
+function dateRange(start, end, tc) {
+ if (dateLong(start, tc) === dateLong(end, tc)) {
+ return dateLong(start, tc)
+ }
+ return `${dateShort(start, tc)} - ${dateLong(end, tc)}`
+}
+
+export {
+ dateShort,
+ dateLong,
+ timeDurationShort,
+ hourShort,
+ hourLong,
+ dateRange,
+ rangeTime,
+ rangeShort,
+ rangeLongEnd,
+}
diff --git a/frontend-vue3/src/common/helpers/dayResponsibles.js b/frontend-vue3/src/common/helpers/dayResponsibles.js
new file mode 100644
index 0000000000..43fb3f0a47
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/dayResponsibles.js
@@ -0,0 +1,26 @@
+import campCollaborationDisplayName from './campCollaborationDisplayName.js'
+
+/**
+ * Local filtering of dayResponsibles by day
+ * (avoids separate network request for each day)
+ */
+const filterDayResponsiblesByDay = (day) => {
+ if (!day) return []
+
+ return day
+ .period()
+ .dayResponsibles()
+ .items.filter((dayResponsible) => dayResponsible.day()._meta.self === day._meta.self)
+}
+
+const dayResponsiblesCommaSeparated = (day, tc) => {
+ if (!day) return ''
+
+ return filterDayResponsiblesByDay(day)
+ .map((dayResponsible) =>
+ campCollaborationDisplayName(dayResponsible.campCollaboration(), tc)
+ )
+ .join(', ')
+}
+
+export { filterDayResponsiblesByDay, dayResponsiblesCommaSeparated }
diff --git a/frontend-vue3/src/common/helpers/dayjs.js b/frontend-vue3/src/common/helpers/dayjs.js
new file mode 100644
index 0000000000..4b2c81b075
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/dayjs.js
@@ -0,0 +1,45 @@
+import dayjs from 'dayjs'
+
+import 'dayjs/locale/en-gb'
+import 'dayjs/locale/de'
+import 'dayjs/locale/de-ch'
+import 'dayjs/locale/fr'
+import 'dayjs/locale/fr-ch'
+import 'dayjs/locale/it'
+import 'dayjs/locale/it-ch'
+
+import utc from 'dayjs/plugin/utc'
+import customParseFormat from 'dayjs/plugin/customParseFormat'
+import objectSupport from 'dayjs/plugin/objectSupport'
+import localizedFormat from 'dayjs/plugin/localizedFormat'
+import isBetween from 'dayjs/plugin/isBetween'
+import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'
+import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'
+import duration from 'dayjs/plugin/duration'
+import formatDatePeriod from './dayjs/formatDatePeriod.js'
+import timezone from 'dayjs/plugin/timezone'
+
+dayjs.extend(utc)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+dayjs.extend(objectSupport)
+dayjs.extend(localizedFormat)
+dayjs.extend(isBetween)
+dayjs.extend(isSameOrBefore)
+dayjs.extend(isSameOrAfter)
+dayjs.extend(duration)
+dayjs.extend(formatDatePeriod)
+
+export const dayjsLocaleMap = {
+ de: 'de-ch',
+ en: 'en-gb',
+ it: 'it-ch',
+ fr: 'fr-ch',
+}
+
+/**
+ * @typedef {import('dayjs').Dayjs} Dayjs
+ * @property {Dayjs} utc
+ * @property {Dayjs} tz
+ */
+export default dayjs
diff --git a/frontend-vue3/src/common/helpers/dayjs/__tests__/formatDatePeriod.spec.js b/frontend-vue3/src/common/helpers/dayjs/__tests__/formatDatePeriod.spec.js
new file mode 100644
index 0000000000..41942d7057
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/dayjs/__tests__/formatDatePeriod.spec.js
@@ -0,0 +1,19 @@
+import { describe, beforeEach, expect, it } from 'vitest'
+import dayjs from '@/common/helpers/dayjs.js'
+
+describe('formatDatePeriod dayjs plugin', () => {
+ beforeEach(() => {
+ dayjs.locale('de')
+ })
+
+ it.each([
+ ['', ''],
+ [null, ''],
+ [undefined, ''],
+ ['L', '03.04.2023 - 07.04.2023'],
+ ])('maps %p to %p', (input, expected) => {
+ const startDate = dayjs('2023-04-03 0:00')
+ const endDate = dayjs('2023-04-07 0:00')
+ expect(dayjs.formatDatePeriod(startDate, endDate, input, 'de')).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/dayjs/__tests__/parseTime.spec.js b/frontend-vue3/src/common/helpers/dayjs/__tests__/parseTime.spec.js
new file mode 100644
index 0000000000..a12a3f0987
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/dayjs/__tests__/parseTime.spec.js
@@ -0,0 +1,103 @@
+import { describe, beforeEach, expect, it } from 'vitest'
+import { default as dayjs, dayjsLocaleMap } from '../../dayjs'
+import parseTime from '../parseTime'
+import { padStart, range } from 'lodash-es'
+import { HTML5_FMT } from '../../dateFormat'
+
+/**
+ * Source: https://github.com/sbb-design-systems/sbb-angular/blob/24d4a804a55fa671cdf441a4556741ecfa2c638c/src/angular/time-input/time-input.spec.ts#L38
+ */
+describe('parseTime', () => {
+ describe.each(Object.keys(dayjsLocaleMap))('`%s` locale', (locale) => {
+ beforeEach(() => {
+ dayjs.locale(locale)
+ })
+
+ const numbersFrom1to23 = range(1, 24).map((number) => [
+ `${number}`,
+ `${padStart(number, 2, '0')}:00`,
+ ])
+
+ it.each([
+ ['00:00', '00:00'],
+ ['12:00', '12:00'],
+ ['23:59', '23:59'],
+ ['01:01', '01:01'],
+ ['09:59', '09:59'],
+ ['20:00', '20:00'],
+ ['10:11', '10:11'],
+ ['010:11', '10:11', { en: '00:10' }],
+ ['00010:11', '10:11', { en: '00:01' }],
+ ['18:30', '18:30'],
+ ['001:11', '01:11', { en: '00:01' }],
+ ['000001:11', '01:11', { en: '00:00' }],
+ ['16:30', '16:30'],
+ ...numbersFrom1to23,
+ [0, '00:00'],
+ [-0, '00:00'],
+ ['123', '01:23'],
+ ['1234', '12:34'],
+ ['13567', '13:56'],
+ ['407', '04:07'],
+ ['3.56', '03:56'],
+ ['23,4', '23:04'],
+ ['1,30', '01:30'],
+ ['1:2', '01:02'],
+ ['1.2', '01:02'],
+ ['1,2', '01:02'],
+ ['1-2', '01:02'],
+ ['1;2', '01:02'],
+ ['01', '01:00'],
+ ['18', '18:00'],
+ ['23', '23:00'],
+ // not specified like this, but the current behaviour
+ ['010', '00:10'],
+ ['023', '00:23'],
+ ['145', '01:45'],
+ ['159', '01:59'],
+ ['200', '02:00'],
+ ['214', '02:14'],
+ ['313', '03:13'],
+ ['659', '06:59'],
+ ])(
+ `parses %s to %s (but special case for %s)`,
+ (input, output, specialCaseForLocale = {}) => {
+ const { isValid, parsedDateTime } = parseTime(input)
+
+ const expectedOutput =
+ locale in specialCaseForLocale ? specialCaseForLocale[locale] : output
+
+ expect(parsedDateTime.format('HH:mm')).toEqual(expectedOutput)
+ // the resulting dayjs object should not flow over to the next day
+ expect(parsedDateTime.format(HTML5_FMT.DATE)).toEqual(
+ dayjs().format(HTML5_FMT.DATE)
+ )
+ expect(isValid).toEqual(true)
+ }
+ )
+
+ it.each([
+ [null],
+ [undefined],
+ [''],
+ [' '],
+ ['\t'],
+ [[]],
+ [{}],
+ ['invalid time'],
+ ['a very long time that the cases are in multiple lines'],
+ ['24'],
+ ['99'],
+ ['2525'],
+ ['160'],
+ ['189'],
+ ['191'],
+ ['260'],
+ ['269'],
+ ['999'],
+ ])(`rejects %s`, (input) => {
+ const { isValid } = parseTime(input)
+ expect(isValid).toEqual(false)
+ })
+ })
+})
diff --git a/frontend-vue3/src/common/helpers/dayjs/formatDatePeriod.js b/frontend-vue3/src/common/helpers/dayjs/formatDatePeriod.js
new file mode 100644
index 0000000000..5ec56e4e96
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/dayjs/formatDatePeriod.js
@@ -0,0 +1,14 @@
+export default (option, dayjsClass, dayjsFactory) => {
+ // Callable as follows: dayjs.formatDatePeriod(start, end, format, locale)
+ dayjsFactory.formatDatePeriod = (start, end, format, _ /* locale */) => {
+ if (!format) return ''
+ // TODO implement intelligent shortening, e.g. in German, you can write
+ // Fr 14. - So 16.04.2023 instead of Fr 14.04.2023 - So 16.04.2023.
+ // But careful, the same may or may not be possible in other locales.
+ // E.g. in English dates like 4/17/2023, it may not be possible to leave
+ // out the date. Proper research on this topic is needed.
+ const startFormatted = start.format(format)
+ const endFormatted = end.format(format)
+ return `${startFormatted} - ${endFormatted}`
+ }
+}
diff --git a/frontend-vue3/src/common/helpers/dayjs/parseTime.js b/frontend-vue3/src/common/helpers/dayjs/parseTime.js
new file mode 100644
index 0000000000..3e8ef075c7
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/dayjs/parseTime.js
@@ -0,0 +1,55 @@
+import dayjs from '../dayjs'
+import { HTML5_FMT } from '../dateFormat'
+
+/**
+ * Source: https://github.com/sbb-design-systems/sbb-angular/blob/24d4a804a55fa671cdf441a4556741ecfa2c638c/src/angular/time-input/time-input.ts
+ */
+const REGEX_WITH_COLON = /([0-9]{1,2})[.:,\-;_hH]?([0-9]{1,2})?/
+const REGEX_WITHOUT_COLON = /([0-9]{1,2})([0-9]{2})/
+
+function matchDigitGroups(input) {
+ if (input.match(/^\d{1,2}$/)) {
+ return [input, '0']
+ }
+ const matchWithoutColon = input.match(REGEX_WITHOUT_COLON)
+ if (matchWithoutColon) {
+ return matchWithoutColon.slice(1)
+ }
+ const matchWithColon = input.match(REGEX_WITH_COLON)
+ if (matchWithColon) {
+ return matchWithColon.slice(1)
+ }
+ return []
+}
+
+export default (val) => {
+ const stringVal = `${val}`
+ let valIgnoringLeadingZero = stringVal.replace(/^0*?([\d]{1,2}):/, '$1:')
+ const parsedDateTime = dayjs.utc(valIgnoringLeadingZero, 'LT')
+ const formatted = parsedDateTime.format('LT')
+ if (!formatted.startsWith('0') && valIgnoringLeadingZero.match(/^0\d/)) {
+ valIgnoringLeadingZero = valIgnoringLeadingZero.slice(1)
+ }
+ const isValid = parsedDateTime.isValid() && formatted === valIgnoringLeadingZero
+
+ if (isValid) {
+ return { parsedDateTime, isValid }
+ }
+
+ const digitGroups = matchDigitGroups(stringVal)
+ if (!digitGroups || digitGroups.length < 2) {
+ return { parsedDateTime, isValid }
+ }
+
+ const hours = digitGroups[0]
+ const minutes = digitGroups[1]
+ const fuzzyMatchedTime = dayjs.utc(`${hours}:${minutes}`, HTML5_FMT.TIME)
+ const fuzzyMatchedTimeToday = dayjs.utc(
+ fuzzyMatchedTime.format(HTML5_FMT.TIME),
+ HTML5_FMT.TIME
+ )
+ if (hours > 23 || minutes > 59) {
+ return { parsedDateTime, isValid: false }
+ }
+ return { parsedDateTime: fuzzyMatchedTimeToday, isValid: fuzzyMatchedTime.isValid() }
+}
diff --git a/frontend-vue3/src/common/helpers/filterMatchScheduleEntry.js b/frontend-vue3/src/common/helpers/filterMatchScheduleEntry.js
new file mode 100644
index 0000000000..dd3a4f6465
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/filterMatchScheduleEntry.js
@@ -0,0 +1,50 @@
+/**
+ * Filtering of schedule entries by various criteria.
+ * Only the matcher function for matching a single scheduleEntry with
+ * a set of filter criteria is implemented here, because this can be
+ * used more flexibly in the application.
+ */
+const filterMatchScheduleEntry = (scheduleEntry, filter) => {
+ if (!filter) return true
+ return (
+ // filter by period
+ (filter.period === null ||
+ filter.period === undefined ||
+ scheduleEntry.period()._meta.self === filter.period) &&
+ // filter by days: OR filter
+ (filter.day === null ||
+ filter.day === undefined ||
+ filter.day.length === 0 ||
+ filter.day.includes(
+ scheduleEntry.day()._meta.self
+ )) &&
+ // filter by categories: OR filter
+ (filter.category === null ||
+ filter.category === undefined ||
+ filter.category.length === 0 ||
+ filter.category.includes(
+ scheduleEntry.activity().category()._meta.self
+ )) &&
+ // filter by responsibles: AND filter
+ (filter.responsible === null ||
+ filter.responsible === undefined ||
+ filter.responsible.length === 0 ||
+ filter.responsible.every((responsible) => {
+ return scheduleEntry
+ .activity()
+ .activityResponsibles()
+ .items.map((responsible) => responsible.campCollaboration()._meta.self)
+ .includes(responsible)
+ }) ||
+ (filter.responsible[0] === 'none' &&
+ scheduleEntry.activity().activityResponsibles().items.length === 0)) &&
+ (filter.progressLabel === null ||
+ filter.progressLabel === undefined ||
+ filter.progressLabel.length === 0 ||
+ filter.progressLabel.includes(
+ scheduleEntry.activity().progressLabel?.()._meta.self ?? 'none'
+ ))
+ )
+}
+
+export { filterMatchScheduleEntry }
diff --git a/frontend-vue3/src/common/helpers/initials.js b/frontend-vue3/src/common/helpers/initials.js
new file mode 100644
index 0000000000..6f7c7c7782
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/initials.js
@@ -0,0 +1,21 @@
+import runes from 'runes'
+
+/**
+ * Returns two characters to display for a display name
+ */
+export default function (displayName) {
+ if (!displayName) return ''
+
+ let items = displayName.split(' ', 2)
+ if (items.length === 1) {
+ items = items.shift().split(/[,._-]/, 2)
+ }
+ if (items.length === 1) {
+ return runes.substr(displayName, 0, 2).toUpperCase()
+ } else {
+ return (
+ runes.substr(items[0], 0, 1).toUpperCase() +
+ runes.substr(items[1], 0, 1).toUpperCase()
+ )
+ }
+}
diff --git a/frontend-vue3/src/common/helpers/interpolation.js b/frontend-vue3/src/common/helpers/interpolation.js
new file mode 100644
index 0000000000..5ea4f7bb09
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/interpolation.js
@@ -0,0 +1,39 @@
+/**
+ * Curve fitting
+ * @param x
+ * @param y
+ * @param a
+ * @returns {number}
+ */
+export const lerp = (x, y, a) => x * (1 - a) + y * a
+
+/**
+ * Clamps value between min and max
+ * @param a
+ * @param min
+ * @param max
+ * @returns {number}
+ */
+export const clamp = (a, min = 0, max = 1) => Math.min(max, Math.max(min, a))
+
+/**
+ * Inverse curve fitting function
+ * @param x
+ * @param y
+ * @param a
+ * @returns {number}
+ */
+export const invlerp = (x, y, a) => clamp((a - x) / (y - x))
+
+/**
+ * Maps input to output range
+ * @param inputStart
+ * @param inputEnd
+ * @param outputStart
+ * @param outputEnd
+ * @param input
+ * @returns number
+ */
+export function range(inputStart, inputEnd, outputStart, outputEnd, input) {
+ return lerp(outputStart, outputEnd, invlerp(inputStart, inputEnd, input))
+}
diff --git a/frontend-vue3/src/common/helpers/materialListsSorted.js b/frontend-vue3/src/common/helpers/materialListsSorted.js
new file mode 100644
index 0000000000..ee9fd57e11
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/materialListsSorted.js
@@ -0,0 +1,10 @@
+import sortBy from 'lodash-es/sortBy.js'
+
+export default function (materialLists) {
+ return sortBy(
+ materialLists,
+ (list) =>
+ (list.campCollaboration == null ? 'NonUserList_' : 'UserList_') +
+ list.name.toLowerCase()
+ )
+}
diff --git a/frontend-vue3/src/common/helpers/picasso.js b/frontend-vue3/src/common/helpers/picasso.js
new file mode 100644
index 0000000000..2931e458cb
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/picasso.js
@@ -0,0 +1,356 @@
+import minBy from 'lodash-es/minBy.js'
+import maxBy from 'lodash-es/maxBy.js'
+import sortBy from 'lodash-es/sortBy.js'
+import keyBy from 'lodash-es/keyBy.js'
+import dayjs from './dayjs.js'
+import { arrange } from './scheduleEntryLayout.js'
+
+/**
+ * @typedef {import('./dayjs.js').dayjs} Dayjs
+ */
+
+/**
+ * Splits a set of days into pages, such that all pages contain a similar number of days.
+ *
+ * @param days {array} set of days to split into pages
+ * @param maxDaysPerPage {number} maximum number of days to put on one page
+ * @returns {array} list of pages, each containing a list of the days on the page
+ */
+export function splitDaysIntoPages(days, maxDaysPerPage) {
+ if (!maxDaysPerPage) return []
+ const numberOfDays = days.length
+ const numberOfPages = Math.ceil(numberOfDays / maxDaysPerPage)
+ const daysPerPage = Math.floor(numberOfDays / numberOfPages)
+ const numLargerPages = numberOfDays % numberOfPages
+ let nextUnassignedDayIndex = 0
+
+ return [...Array(numberOfPages).keys()].map((i) => {
+ const isLargerPage = i < numLargerPages
+ const numDaysOnCurrentPage = daysPerPage + (isLargerPage ? 1 : 0)
+ const firstDayIndex = nextUnassignedDayIndex
+ nextUnassignedDayIndex = firstDayIndex + numDaysOnCurrentPage
+
+ return days.filter((day, index) => {
+ return index >= firstDayIndex && index < nextUnassignedDayIndex
+ })
+ })
+}
+
+/**
+ * Finds the largest consecutive time period during the night, in which no schedule entries start or end.
+ * This time period can be treated as the common "bedtime" in the camp, during which
+ * the people in the camp are not active. This time period can be safely hidden on the picasso.
+ *
+ * @param scheduleEntries set of schedule entries to consider
+ * @param dayjs a dayjs helper object, needed to do time calculations
+ * @param firstDayStart dayjs object describing the start of the first day displayed. Is used to make sure that schedule
+ * entries starting on this day may not be assigned to the preceding day, because that would mean they would become
+ * invisible on the picasso
+ * @param lastDayEnd dayjs object describing the end of the last day displayed. Is used to make sure that schedule
+ * entries ending on this day may not be assigned to the following day, because that would mean they would become
+ * invisible on the picasso
+ * @param timeBucketSize size of the time buckets into which the schedule entry boundaries are quantized, in hours
+ * @returns {{bedtime: number, getUpTime: number}}
+ */
+export function calculateBedtime(
+ scheduleEntries,
+ dayjs,
+ firstDayStart,
+ lastDayEnd,
+ timeBucketSize = 1
+) {
+ const scheduleEntryBounds = getScheduleEntryBounds(
+ scheduleEntries,
+ dayjs,
+ firstDayStart.unix(),
+ lastDayEnd.unix()
+ )
+ if (!scheduleEntryBounds.length) return { bedtime: 24, getUpTime: 0 }
+
+ const gaps = scheduleEntryBounds.reduce((gaps, current, index) => {
+ if (index === 0) return gaps
+ const previous = scheduleEntryBounds[index - 1]
+ const duration = current.hours - previous.hours
+ if (duration === 0) return gaps
+ gaps.push({
+ start: previous.hours,
+ end: current.hours,
+ duration,
+ })
+ return gaps
+ }, [])
+
+ // The first and last day on our picasso impose some constraints on the range of bedtimes we can choose.
+ const { earliestBedtime, latestGetUpTime } = bedtimeConstraintsFromFirstAndLastDay(
+ scheduleEntryBounds,
+ firstDayStart,
+ lastDayEnd,
+ dayjs,
+ timeBucketSize
+ )
+
+ const largestBedtimeGap = maxBy(
+ gaps.filter((gap) => {
+ // Prevent bedtimes which would hide some schedule entry on the first or last day
+ if (gap.start < earliestBedtime || gap.end > latestGetUpTime) return false
+ // Prevent bedtimes which are not during the night
+ if (gap.start > 30 || gap.end < 24) return false
+ return true
+ }),
+ (gap) => gap.duration
+ )
+
+ return {
+ bedtime: optimalBedtime(largestBedtimeGap, scheduleEntryBounds, timeBucketSize),
+ getUpTime:
+ optimalGetUpTime(largestBedtimeGap, scheduleEntryBounds, timeBucketSize) - 24,
+ }
+}
+
+function getScheduleEntryBounds(
+ scheduleEntries,
+ dayjs,
+ firstDayStartTimestamp,
+ lastDayEndTimestamp
+) {
+ const bounds = scheduleEntries
+ .flatMap((scheduleEntry) => {
+ const start = dayjs.utc(scheduleEntry.start)
+ const end = dayjs.utc(scheduleEntry.end)
+ const startHours = start.hour() + start.minute() / 60
+ const endHours = end.hour() + end.minute() / 60
+ const duration = end.diff(start, 'minute') / 60
+ return [
+ { hours: startHours, time: start, type: 'start', duration },
+ { hours: endHours, time: end, type: 'end', duration },
+ ]
+ })
+ .filter(
+ (bound) =>
+ bound.time.unix() >= firstDayStartTimestamp &&
+ bound.time.unix() <= lastDayEndTimestamp
+ )
+ // Add a copy of all bounds 24 hours later, to simplify working with the circular characteristics of daytimes
+ const shifted = bounds.map((bound) => ({
+ ...bound,
+ hours: bound.hours + 24,
+ time: bound.time.add(24, 'hours'),
+ }))
+ return sortBy([...bounds, ...shifted], (bound) => bound.hours)
+}
+
+function bedtimeConstraintsFromFirstAndLastDay(
+ scheduleEntryBounds,
+ firstDayStart,
+ lastDayEnd
+) {
+ // The start of the very first schedule entry on the first day (if any) must always be displayed on the first day.
+ // We must make sure that our calculated "get up time" lies before this, so we do not accidentally hide a
+ // schedule entry.
+ const latestGetUpTime = earliestScheduleEntryBoundOnFirstDay(
+ scheduleEntryBounds,
+ firstDayStart
+ )
+
+ // Similarly, the end of the very last schedule entry end must always be displayed on the last day.
+ // So we must make sure that our calculated "go to bed time" lies after this.
+ const earliestBedtime = latestScheduleEntryBoundOnLastDay(
+ scheduleEntryBounds,
+ lastDayEnd.subtract(1, 'second')
+ )
+
+ return {
+ earliestBedtime: earliestBedtime === undefined ? 0 : earliestBedtime,
+ latestGetUpTime: latestGetUpTime === undefined ? 48 : latestGetUpTime + 24,
+ }
+}
+
+function earliestScheduleEntryBoundOnFirstDay(scheduleEntryBounds, firstDayStart) {
+ const earliestBound = minBy(scheduleEntryBounds, (bound) => bound.time.unix())
+ if (
+ earliestBound.hours < 24 &&
+ earliestBound.time.diff(firstDayStart, 'minute') / 60 < 24
+ ) {
+ return earliestBound.hours
+ }
+ return undefined
+}
+
+function latestScheduleEntryBoundOnLastDay(scheduleEntryBounds, lastDayEnd) {
+ const latestBound = maxBy(scheduleEntryBounds, (bound) => bound.time.unix())
+ if (latestBound.hours < 24 && lastDayEnd.diff(latestBound.time, 'minute') / 60 < 24) {
+ return latestBound.hours
+ }
+ return undefined
+}
+
+function optimalBedtime(gap, scheduleEntryBounds, timeBucketSize) {
+ const bedtime = Math.ceil(gap.start / timeBucketSize) * timeBucketSize
+ if (
+ scheduleEntryBounds.some(
+ (bound) =>
+ bound.type === 'start' &&
+ bound.hours <= bedtime &&
+ bound.hours > bedtime - timeBucketSize / 2 &&
+ bound.duration > bedtime - bound.hours
+ )
+ ) {
+ // There exists a schedule entry which starts at the bedtime or less than half a time bucket before it.
+ // Move the bedtime later, so that this schedule entry is still clearly visible.
+ return bedtime + timeBucketSize
+ }
+ // There is already a large enough margin, or there are no schedule entries starting around the bedtime.
+ return bedtime
+}
+
+function optimalGetUpTime(gap, scheduleEntryBounds, timeBucketSize) {
+ const getUpTime = Math.floor(gap.end / timeBucketSize) * timeBucketSize
+ if (
+ scheduleEntryBounds.some(
+ (bound) =>
+ bound.type === 'end' &&
+ bound.hours >= getUpTime &&
+ bound.hours < getUpTime + timeBucketSize / 2 &&
+ bound.duration > bound.hours - getUpTime
+ )
+ ) {
+ // There exists a schedule entry which ends at the getUpTime or less than half a time bucket after it.
+ // Move the getUpTime later, so that this schedule entry is still clearly visible.
+ return getUpTime - timeBucketSize
+ }
+ // There is already a large enough margin, or there are no schedule entries ending around the getUpTime.
+ return getUpTime
+}
+
+/**
+ * Generates an array of time row descriptions, used for labeling the vertical axis of the picasso.
+ * Format of each array element: [hour, weight] where weight determines how tall the time row is rendered.
+ *
+ * @typedef {*[[hour: number, weight: number]]} TimeWeights
+ * @returns TimeWeights
+ */
+export function times(getUpTime, bedTime, timeStep) {
+ const times = [[getUpTime - timeStep / 2, 0.5]]
+ for (let i = 0; getUpTime + i * timeStep < bedTime; i++) {
+ // TODO The weight could also be generated depending on the schedule entries present in the camp:
+ // e.g. give less weight to hours that contain no schedule entries.
+ const weight = 1
+ times.push([getUpTime + i * timeStep, weight])
+ }
+ times.push([bedTime, 0.5])
+ // this last hour is only needed for defining the length of the day. The weight should be 0.
+ times.push([bedTime + timeStep / 2, 0])
+
+ return times
+}
+
+/**
+ * Returns the total sum of weights in the times array (with times format as generated by times() function)
+ */
+export function timesWeightsSum(times) {
+ return times.reduce((sum, [_, weight]) => sum + weight, 0)
+}
+
+/**
+ * Calculates the relative positioning in percentage of "milliseconds" within the times array
+ */
+export function positionPercentage(milliseconds, times) {
+ const hours = milliseconds / (3600.0 * 1000)
+ let matchingTimeIndex = times.findIndex(([time, _]) => time > hours) - 1
+ matchingTimeIndex = Math.min(
+ Math.max(matchingTimeIndex === -2 ? times.length : matchingTimeIndex, 0),
+ times.length - 1
+ )
+ const remainder =
+ times[matchingTimeIndex][1] !== 0
+ ? (hours - times[matchingTimeIndex][0]) / times[matchingTimeIndex][1]
+ : 0 // avoid division by zero, in case the schedule entry ends on a later day
+ const positionWeightsSum =
+ timesWeightsSum(times.slice(0, matchingTimeIndex)) +
+ remainder * times[Math.min(matchingTimeIndex, times.length)][1]
+ const totalWeightsSum = timesWeightsSum(times)
+ if (totalWeightsSum === 0) {
+ return 0
+ }
+ const result = (positionWeightsSum * 100.0) / totalWeightsSum
+ return Math.max(0, Math.min(100, result))
+}
+
+export function filterScheduleEntriesByDay(scheduleEntries, day, times) {
+ return scheduleEntries.filter((scheduleEntry) => {
+ return (
+ dayjs.utc(scheduleEntry.start).isBefore(dayEnd(day, times)) &&
+ dayjs.utc(scheduleEntry.end).isAfter(dayStart(day, times))
+ )
+ })
+}
+
+/**
+ * @param day a day object of the api
+ * @param offset {number} the offset hour of the day
+ * @returns {Dayjs}
+ */
+function dayOffset(day, offset) {
+ return dayjs.utc(day.start).add(offset, 'hour')
+}
+
+/**
+ * Calculates the day start dayjs object according to times
+ *
+ * @param day a day object of the api
+ * @param times {TimeWeights}
+ * @returns {Dayjs}
+ */
+export function dayStart(day, times) {
+ const dayStart = times[0][0]
+ return dayOffset(day, dayStart)
+}
+
+/**
+ * Calculates the day end dayjs object according to times
+ *
+ * @param day a day object of the api
+ * @param times {TimeWeights}
+ * @returns {Dayjs}
+ */
+export function dayEnd(day, times) {
+ const dayEnd = times[times.length - 1][0]
+ return dayOffset(day, dayEnd)
+}
+
+function leftAndWith(scheduleEntries) {
+ return keyBy(arrange(scheduleEntries), 'id')
+}
+
+/**
+ * Calculates the positions styles (in percentages) for all scheduleEntries
+ */
+export function positionStyles(scheduleEntries, day, times) {
+ const leftAndWidth = leftAndWith(scheduleEntries)
+
+ return keyBy(
+ scheduleEntries.map((scheduleEntry) => {
+ const left = leftAndWidth[scheduleEntry.id]?.left || 0
+ const width = leftAndWidth[scheduleEntry.id]?.width || 0
+ const top = positionPercentage(
+ dayjs.utc(scheduleEntry.start).valueOf() - dayjs.utc(day.start).valueOf(),
+ times
+ )
+ const bottom =
+ 100 -
+ positionPercentage(
+ dayjs.utc(scheduleEntry.end).valueOf() - dayjs.utc(day.start).valueOf(),
+ times
+ )
+ return {
+ id: scheduleEntry.id,
+ top: top + '%',
+ bottom: bottom + '%',
+ left: left + '%',
+ right: 100 - width - left + '%',
+ percentageHeight: 100 - bottom - top,
+ }
+ }),
+ 'id'
+ )
+}
diff --git a/frontend-vue3/src/common/helpers/scheduleEntryLayout.js b/frontend-vue3/src/common/helpers/scheduleEntryLayout.js
new file mode 100644
index 0000000000..9e8cf6fc32
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/scheduleEntryLayout.js
@@ -0,0 +1,119 @@
+// This file contains an algorithm for automatically arranging schedule entries in terms
+// of horizontal placement, such that they do not overlap with each other.
+// Taken and adapted from Vuetify 2's v-calendar event overlap logic:
+// https://github.com/vuetifyjs/vuetify/blob/v2-stable/packages/vuetify/src/components/VCalendar/modes/column.ts
+
+import dayjs from './dayjs.js'
+
+const FULL_WIDTH = 100
+
+function getVisuals(events) {
+ const visuals = events.map((event) => ({
+ id: event.id,
+ columnCount: 0,
+ column: 0,
+ left: 0,
+ width: 100,
+ startTimestamp: dayjs.utc(event.start).unix(),
+ endTimestamp: dayjs.utc(event.end).unix(),
+ }))
+
+ visuals.sort((a, b) => {
+ return a.startTimestamp - b.startTimestamp || b.endTimestamp - a.endTimestamp
+ })
+
+ return visuals
+}
+
+function hasOverlap(s0, e0, s1, e1) {
+ return !(s0 >= e1 || e0 <= s1)
+}
+
+function setColumnCount(groups) {
+ groups.forEach((group) => {
+ group.visuals.forEach((groupVisual) => {
+ groupVisual.columnCount = groups.length
+ groupVisual.left = (groupVisual.column * FULL_WIDTH) / groupVisual.columnCount
+ groupVisual.width = FULL_WIDTH / groupVisual.columnCount
+ })
+ })
+}
+
+function getOpenGroup(groups, eventStart, eventEnd) {
+ for (let i = 0; i < groups.length; i++) {
+ const group = groups[i]
+ let intersected = false
+
+ if (hasOverlap(eventStart, eventEnd, group.start, group.end)) {
+ for (let k = 0; k < group.visuals.length; k++) {
+ const groupVisual = group.visuals[k]
+ const groupStart = groupVisual.startTimestamp
+ const groupEnd = groupVisual.endTimestamp
+
+ if (hasOverlap(eventStart, eventEnd, groupStart, groupEnd)) {
+ intersected = true
+ break
+ }
+ }
+ }
+
+ if (!intersected) {
+ return i
+ }
+ }
+
+ return -1
+}
+
+/**
+ * Calculates left and width for each schedule entry, such that no two schedule entries overlap visually.
+ * For this, schedule entries are sorted by ascending start ascendingly (and descending end time for ties),
+ * and any sets of overlapping schedule entries are divided into groups. The groups can then be displayed
+ * besides each other, because the groups are chosen such that no two schedule entries in the same group overlap.
+ * @param scheduleEntries list of schedule entries to arrange
+ * @returns list of objects with information about the spatial arrangement
+ */
+export function arrange(scheduleEntries) {
+ let groups = []
+ let min = -1
+ let max = -1
+ const visuals = getVisuals(scheduleEntries)
+
+ visuals.forEach((visual) => {
+ const eventStart = visual.startTimestamp
+ const eventEnd = visual.endTimestamp
+
+ if (groups.length > 0 && !hasOverlap(eventStart, eventEnd, min, max)) {
+ setColumnCount(groups)
+ groups = []
+ min = max = -1
+ }
+
+ let targetGroup = getOpenGroup(groups, eventStart, eventEnd)
+
+ if (targetGroup === -1) {
+ targetGroup = groups.length
+
+ groups.push({ start: eventStart, end: eventEnd, visuals: [] })
+ }
+
+ const target = groups[targetGroup]
+ target.visuals.push(visual)
+ target.start = Math.min(target.start, eventStart)
+ target.end = Math.max(target.end, eventEnd)
+
+ visual.column = targetGroup
+
+ if (min === -1) {
+ min = eventStart
+ max = eventEnd
+ } else {
+ min = Math.min(min, eventStart)
+ max = Math.max(max, eventEnd)
+ }
+ })
+
+ setColumnCount(groups)
+
+ return visuals
+}
diff --git a/frontend-vue3/src/common/helpers/userDisplayName.js b/frontend-vue3/src/common/helpers/userDisplayName.js
new file mode 100644
index 0000000000..7f44be53ce
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/userDisplayName.js
@@ -0,0 +1,6 @@
+/**
+ * Returns a display name for a user
+ */
+export default function (user) {
+ return user.displayName || ''
+}
diff --git a/frontend-vue3/src/common/helpers/userInitials.js b/frontend-vue3/src/common/helpers/userInitials.js
new file mode 100644
index 0000000000..cdb6d9e225
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/userInitials.js
@@ -0,0 +1,15 @@
+import userDisplayName from './userDisplayName.js'
+import initials from './initials.js'
+
+/**
+ * Returns two characters to display for a user
+ */
+export default function (user) {
+ if (!user) {
+ return ''
+ }
+ if (user.abbreviation) {
+ return user.abbreviation
+ }
+ return initials(userDisplayName(user))
+}
diff --git a/frontend-vue3/src/common/helpers/userLegalName.js b/frontend-vue3/src/common/helpers/userLegalName.js
new file mode 100644
index 0000000000..23067fd10e
--- /dev/null
+++ b/frontend-vue3/src/common/helpers/userLegalName.js
@@ -0,0 +1,7 @@
+/**
+ * Returns the legal name for a user
+ */
+export default function (user) {
+ if (!user || !user.profile() || user.profile()._meta.loading) return ''
+ return user.profile().legalName || ''
+}
diff --git a/frontend-vue3/src/common/locales/de-CH-scout.json b/frontend-vue3/src/common/locales/de-CH-scout.json
new file mode 100644
index 0000000000..2dcdd1dbae
--- /dev/null
+++ b/frontend-vue3/src/common/locales/de-CH-scout.json
@@ -0,0 +1,12 @@
+{
+ "entity": {
+ "camp": {
+ "fields": {
+ "courseKind": "Kursbezeichnung (bei J+S Kurs: J+S Bezeichnung)",
+ "courseNumber": "Kursnummer",
+ "printYSLogoOnPicasso": "J+S-Logo auf Grobprogramm drucken (bei J+S-Kursen aktivieren)",
+ "trainingAdvisorName": "Bürgerlicher Name von LKB"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/common/locales/de.json b/frontend-vue3/src/common/locales/de.json
new file mode 100644
index 0000000000..0b137def97
--- /dev/null
+++ b/frontend-vue3/src/common/locales/de.json
@@ -0,0 +1,298 @@
+{
+ "components": {
+ "summary": {
+ "summaryDay": {
+ "noContent": "Die Blöcke an diesem Tag enthalten keine {contentType} Inhalte."
+ }
+ }
+ },
+ "contentNode": {
+ "checklist": {
+ "info": "Wähle die relevanten Checklisten-Einträge aus, die von dieser Aktivität abgedeckt werden (Kursziele, etc.).",
+ "name": "Checklisten"
+ },
+ "columnLayout": {
+ "entity": {
+ "column": {
+ "name": "Spalte|Spalte {name}"
+ }
+ },
+ "name": "Spaltenlayout"
+ },
+ "laThematicArea": {
+ "entity": {
+ "option": {
+ "campsiteAndSurroundings": {
+ "description": "Einrichten von Lagerplatz/Umgebung, Abbau, Erstellen von Spielplatzeinrichtungen und Sportgeräten.",
+ "name": "Lagerplatz/Umgebung"
+ },
+ "natureAndEnvironment": {
+ "description": "Tier- und Pflanzenwelt, Umweltschutz im Lager, Wetter- und Sternkunde, Übermittlungstechniken, Feuer machen.",
+ "name": "Natur und Umwelt"
+ },
+ "outdoorTechnique": {
+ "description": "Wanderplanung, Kartenlesen (z.B. NORDA), Krokieren, Hilfsmittel (z.B. Kompass, GPS, Höhenmeter usw.), orientieren im Gelände.",
+ "name": "Outdoortechniken"
+ },
+ "pioneeringTechnique": {
+ "description": "Biwakbau, Iglubau, Material- und Ausrüstungskunde, Materialpflege, Erstellen und Abbau von Pionierbauten, Seil- und Knotenkunde, Seilbahnen, Seilbrücken, Abseilen.",
+ "name": "Pioniertechnik"
+ },
+ "preventionAndIntegration": {
+ "description": "Aktivitäten, welche der Prävention und der Integration dienen und die Kompetenzen der Teilnehmenden in diesem Bereich fördern.",
+ "name": "Prävention und Integration"
+ },
+ "security": {
+ "description": "Sicherheit bei Aktivitäten im Lager, Unfallorganisation und Alarmierung, 1. Hilfe, Sicherheitsüberlegungen.",
+ "name": "Sicherheit"
+ }
+ }
+ },
+ "info": "Eine J+S Lageraktivität muss mindestens eines der aufgeführten Themen behandeln.{br}Erfasse, welche Themen in diesem Block behandelt werden.",
+ "name": "LA Themenbereich"
+ },
+ "learningObjectives": {
+ "info": "Formuliere die Kompetenzen, über welche die Teilnehmenden nach diesem Block verfügen, in der Form von Lernzielen.",
+ "name": "Blockziele"
+ },
+ "learningTopics": {
+ "info": "Liste die Ausbildungs-Themen auf, mit welchen die Teilnehmenden sich in diesem Block auseinandersetzen werden.",
+ "name": "Blockinhalte"
+ },
+ "material": {
+ "info": "Hier kannst du den Material-Bedarf für diesen Block erfassen.{br}Die Materiallisten kannst du im Menu 'Admin' verwalten.{br}Eine Zusammenstellung für den Einkauf findest du im Menu 'Material'.",
+ "name": "Material"
+ },
+ "notes": {
+ "info": "Hier kannst du beliebige Notizen erfassen.{br}z.B. Ideen, Todo's, offene Fragen, Kontakte, ÖV-Verbindungen, usw.",
+ "name": "Notizen"
+ },
+ "responsiveLayout": {
+ "mainContent": "Hauptinhalt",
+ "name": "Standardlayout",
+ "printAboveMainContent": "Über dem Hauptinhalt drucken",
+ "printBelowMainContent": "Unter dem Hauptinhalt drucken"
+ },
+ "safetyConsiderations": {
+ "info": "Einige Blöcke erfordern, dass ihr euch Gedanken zu den Risiken macht. Hier könnt ihr diese Gedanken erfassen.{br}Haltet fest, welche Risiken ihr erkannt habt - und wie ihr diesen begegnen könnt.",
+ "name": "Sicherheitsüberlegungen"
+ },
+ "storyboard": {
+ "entity": {
+ "section": {
+ "fields": {
+ "column1": "Zeit",
+ "column2Html": "Programm",
+ "column3": "Verantwortlich"
+ },
+ "name": "Programmpunkt | Programmpunkte"
+ }
+ },
+ "info": "Hier kannst du den Inhalt von diesem Block planen.{br}In der linken Spalte [Zeit] kannst du die Dauer der einzelnen Elemente erfassen.{br}In der rechten Spalte [Verantwortlich] kannst du Personen zuteilen.",
+ "name": "Programmabschnitt"
+ },
+ "storycontext": {
+ "info": "Beschreibe, wie sich dieser Block in die Geschichte vom Lager einbettet.{br}Eine Zusammenstellung aller Geschichts-Elemente findest du im Menu 'Geschichte'.{br}Ihr könnt auch erst im Menu 'Geschichte' zuerst eine durchgängige Geschichte erarbeiten - so dass man den Block-Inhalt perfekt in die Geschichte einbetten kann.",
+ "name": "Geschichte"
+ }
+ },
+ "entity": {
+ "activity": {
+ "fields": {
+ "category": "Block-Kategorie",
+ "location": "Ort",
+ "progressLabel": "Status",
+ "responsible": "Verantwortlich",
+ "title": "Titel"
+ },
+ "name": "Aktivität | Aktivitäten",
+ "new": "Neue Aktivität"
+ },
+ "activityProgressLabel": {
+ "fields": {
+ "title": "Titel"
+ }
+ },
+ "camp": {
+ "collaborators": {
+ "guest": "Gast",
+ "invite": "Einladen",
+ "manager": "Administration",
+ "member": "Mitglied"
+ },
+ "fields": {
+ "addressCity": "Ort",
+ "addressName": "Name",
+ "addressStreet": "Strasse",
+ "addressZipcode": "PLZ",
+ "coachName": "Name des J+S-Coachs",
+ "courseKind": "Kursbezeichnung (bei J+S Kurs: J+S Bezeichnung)",
+ "courseNumber": "Kursnummer",
+ "kind": "Lagerart (Haus-, Zelt-, Unterwegslager, Sommer-, Herbstlager)",
+ "motto": "Motto / Thema",
+ "organizer": "Organisator",
+ "printYSLogoOnPicasso": "J+S-Logo auf Grobprogramm drucken (bei J+S-Kursen aktivieren)",
+ "shortTitle": "Kurzer Lagertitel",
+ "title": "Lagertitel",
+ "trainingAdvisorName": "Bürgerlicher Name der Betreuungsperson"
+ },
+ "name": "Lager",
+ "prototype": "Lagervorlage"
+ },
+ "campCollaboration": {
+ "fields": {
+ "abbreviation": "Abkürzung",
+ "color": "Farbe",
+ "inviteEmail": "E-Mail",
+ "role": "Rolle",
+ "status": "Status"
+ },
+ "status": {
+ "established": "Aktiv",
+ "inactive": "Inaktiv",
+ "invited": "Eingeladen"
+ }
+ },
+ "category": {
+ "fields": {
+ "color": "Farbe",
+ "name": "Name",
+ "numberingStyle": "Nummerierung",
+ "short": "Kürzel"
+ },
+ "name": "Block-Kategorien",
+ "numberingStyles": {
+ "-": "keine Nummerierung",
+ "1": "1, 2, 3 - Zahlen",
+ "A": "A, B, C - grosse Buchstaben",
+ "I": "I, II, III - grosse römische Zahlen",
+ "a": "a, b, c - kleine Buchstaben",
+ "i": "i, ii, iii - kleine römische Zahlen"
+ }
+ },
+ "checklist": {
+ "fields": {
+ "copyChecklistSource": "Vorlage",
+ "name": "Name"
+ },
+ "name": "Checkliste | Checklisten"
+ },
+ "checklistItem": {
+ "fields": {
+ "text": "Text"
+ },
+ "name": "Checklisten-Eintrag"
+ },
+ "contentType": {
+ "name": "Inhalttyp | Inhalttypen"
+ },
+ "day": {
+ "fields": {
+ "dayResponsibles": "Tagesverantwortliche"
+ },
+ "name": "Tag | Tage"
+ },
+ "materialItem": {
+ "fields": {
+ "article": "Artikel",
+ "list": "Materialliste",
+ "quantity": "Menge",
+ "reference": "Aktivität / Lagerabschnitt",
+ "unit": "Einheit"
+ }
+ },
+ "materialList": {
+ "fields": {
+ "name": "Name"
+ },
+ "name": "Materialliste"
+ },
+ "period": {
+ "defaultDescription": "Hauptlager",
+ "fields": {
+ "description": "Beschreibung",
+ "end": "Bis",
+ "start": "Von"
+ },
+ "name": "Lagerabschnitt | Lagerabschnitte"
+ },
+ "profile": {
+ "fields": {
+ "abbreviation": "Abkürzung",
+ "color": "Farbe",
+ "email": "E-Mail-Adresse",
+ "firstname": "Vorname",
+ "language": "Sprache",
+ "nickname": "Spitzname",
+ "password": "Passwort",
+ "surname": "Nachname"
+ },
+ "name": "Profil"
+ },
+ "scheduleEntry": {
+ "fields": {
+ "duration": "Dauer",
+ "endDate": "Enddatum",
+ "endDatetime": "Endzeit",
+ "nr": "Nr.",
+ "startDate": "Startdatum",
+ "startDatetime": "Startzeit",
+ "time": "Zeitpunkt"
+ },
+ "name": "Zeitplaneintrag"
+ }
+ },
+ "global": {
+ "datetime": {
+ "dateLong": "dd L",
+ "dateShort": "dd D.M.",
+ "dateTimeLong": "dd L LT",
+ "duration": {
+ "daysAndHours": "{days} d {hours} h",
+ "daysAndHoursAndMinutes": "{days} d {hours} h {minutes} min",
+ "daysAndMinutes": "{days} d {minutes} min",
+ "hoursAndMinutes": "{hours} h {minutes} min",
+ "daysOnly": "{days} d",
+ "hoursOnly": "{hours} h",
+ "minutesOnly": "{minutes} min"
+ },
+ "hourLong": "LT",
+ "hourShort": "H:mm"
+ },
+ "shortScheduleEntryDescription": "Tag {dayNumber} {startTime}"
+ },
+ "print": {
+ "activityList": {
+ "title": "Aktivitätsliste"
+ },
+ "config": {
+ "periods": "Lagerabschnitt(e)"
+ },
+ "cover": {
+ "title": "Titelseite"
+ },
+ "picasso": {
+ "picassoFooter": {
+ "coach": "Coach: {coach}",
+ "courseNumber": "Kursnummer: {courseNumber}",
+ "leaders": "Leitung: {leaders}",
+ "trainingAdvisor": "LKB: {trainingAdvisor}"
+ },
+ "title": "Grobprogramm {period}"
+ },
+ "program": {
+ "title": "Detailprogramm"
+ },
+ "summary": {
+ "safetyConsiderations": {
+ "title": "Sicherheitsüberlegungen"
+ },
+ "storycontext": {
+ "title": "Geschichte"
+ }
+ },
+ "toc": {
+ "title": "Inhaltsverzeichnis"
+ }
+ }
+}
diff --git a/frontend-vue3/src/common/locales/en-CH-scout.json b/frontend-vue3/src/common/locales/en-CH-scout.json
new file mode 100644
index 0000000000..9e26dfeeb6
--- /dev/null
+++ b/frontend-vue3/src/common/locales/en-CH-scout.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/frontend-vue3/src/common/locales/en.json b/frontend-vue3/src/common/locales/en.json
new file mode 100644
index 0000000000..e3d5709ef2
--- /dev/null
+++ b/frontend-vue3/src/common/locales/en.json
@@ -0,0 +1,298 @@
+{
+ "components": {
+ "summary": {
+ "summaryDay": {
+ "noContent": "The activities on this day do not contain any {contentType} content."
+ }
+ }
+ },
+ "contentNode": {
+ "checklist": {
+ "info": "Select the relevant checklist items, which are covered by this activity (course objectives, etc.).",
+ "name": "Checklists"
+ },
+ "columnLayout": {
+ "entity": {
+ "column": {
+ "name": "Column|Column {name}"
+ }
+ },
+ "name": "Column layout"
+ },
+ "laThematicArea": {
+ "entity": {
+ "option": {
+ "campsiteAndSurroundings": {
+ "description": "Construction of a camp / surroundings, dismantling / setting up of a playground and fabrication of sports equipment.",
+ "name": "Campsite and Surroundings"
+ },
+ "natureAndEnvironment": {
+ "description": "Fauna and flora, environmental protection in the camp, meteorology and astronomy, transmission techniques, preparation and making a fire.",
+ "name": "Nature and Environment"
+ },
+ "outdoorTechnique": {
+ "description": "Planning a hike, map reading (e.g. NORDA checklist), croquis, use of instruments (e.g. compass, GPS receiver, altimeter, etc.), orientation in the terrain.",
+ "name": "Outdoor Technique"
+ },
+ "pioneeringTechnique": {
+ "description": "Setting up a bivouac, building an igloo, knowledge of materials and equipment, equipment maintenance, construction and dismantling of pioneer structures, ropes and knots, zip lines, rope bridges, abseiling.",
+ "name": "Pioneering Technique"
+ },
+ "preventionAndIntegration": {
+ "description": "Activities promoting prevention and integration or developing participants' skills in this area.",
+ "name": "Prevention and Integration"
+ },
+ "security": {
+ "description": "Safety during camp activities, measures to be taken in case of accident and alert, first aid, safety considerations.",
+ "name": "Security"
+ }
+ }
+ },
+ "info": "A Y+S camp activity must address at least one of the listed topics.{br}Select what topics are covered in this block.",
+ "name": "LA thematic area"
+ },
+ "learningObjectives": {
+ "info": "Formulate as goals the competences which the participants will have after this activity.",
+ "name": "Learning objectives"
+ },
+ "learningTopics": {
+ "info": "List the topics about which the participants will learn something in this activity.",
+ "name": "Learning topics"
+ },
+ "material": {
+ "info": "Here you can enter the material requirements for this block.{br}You can manage the material lists in the menu 'Admin'.{br}You can find a summary for the purchase in the menu 'Material'.",
+ "name": "Material"
+ },
+ "notes": {
+ "info": "Here you can enter any notes.{br}e.g. ideas, todo's, open questions, contacts, public transport connections, etc.",
+ "name": "Notes"
+ },
+ "responsiveLayout": {
+ "mainContent": "Main content",
+ "name": "Default layout",
+ "printAboveMainContent": "Print above main content",
+ "printBelowMainContent": "Print below main content"
+ },
+ "safetyConsiderations": {
+ "info": "Some blocks require to think about the risks. Here you can record these thoughts.{br}Record what risks you have identified - and how you can address them.",
+ "name": "Safety considerations"
+ },
+ "storyboard": {
+ "entity": {
+ "section": {
+ "fields": {
+ "column1": "Time",
+ "column2Html": "Program",
+ "column3": "Responsible"
+ },
+ "name": "Storyboard | Storyboards"
+ }
+ },
+ "info": "Here you can plan the content of this block.{br}In the left column [Time] you can record the duration of the individual elements.{br}In the right column [Responsible] you can assign persons.",
+ "name": "Storyboard"
+ },
+ "storycontext": {
+ "info": "Describe how this block fits into the story of the camp.{br}You can find a summary of all story elements in the menu 'Story'.{br}You can also first work out a continuous story in the 'Story' menu - so that you can perfectly embed the block content into the story.",
+ "name": "Story"
+ }
+ },
+ "entity": {
+ "activity": {
+ "fields": {
+ "category": "Category",
+ "location": "Location",
+ "progressLabel": "State",
+ "responsible": "Responsible",
+ "title": "Title"
+ },
+ "name": "Activity | Activities",
+ "new": "New activity"
+ },
+ "activityProgressLabel": {
+ "fields": {
+ "title": "Title"
+ }
+ },
+ "camp": {
+ "collaborators": {
+ "guest": "Guest",
+ "invite": "Invite",
+ "manager": "Administration",
+ "member": "Member"
+ },
+ "fields": {
+ "addressCity": "City",
+ "addressName": "Name",
+ "addressStreet": "Street",
+ "addressZipcode": "Zipcode",
+ "coachName": "Name of Y+S coach",
+ "courseKind": "Course kind (for Y+S courses: Y+S course term)",
+ "courseNumber": "Course number",
+ "kind": "Camp kind (house, tent, traveling, summer, autumn)",
+ "motto": "Motto / Theme",
+ "organizer": "Organizer",
+ "printYSLogoOnPicasso": "Print the Y+S logo on the picasso (required for Y+S courses)",
+ "shortTitle": "Short camp title",
+ "title": "Camp title",
+ "trainingAdvisorName": "Name of training advisor"
+ },
+ "name": "Camp | Camps",
+ "prototype": "Camp prototype"
+ },
+ "campCollaboration": {
+ "fields": {
+ "abbreviation": "Abbreviation",
+ "color": "Color",
+ "inviteEmail": "Email",
+ "role": "Role",
+ "status": "Status"
+ },
+ "status": {
+ "established": "Active",
+ "inactive": "Inactive",
+ "invited": "Invited"
+ }
+ },
+ "category": {
+ "fields": {
+ "color": "Color",
+ "name": "Name",
+ "numberingStyle": "Numbering style",
+ "short": "Abbreviation"
+ },
+ "name": "Activity categories",
+ "numberingStyles": {
+ "-": "no numbering",
+ "1": "1, 2, 3 - numbers",
+ "A": "A, B, C - uppercase letters",
+ "I": "I, II, III - uppercase roman numerals",
+ "a": "a, b, c - lowercase letters",
+ "i": "i, ii, iii - lowercase roman numerals"
+ }
+ },
+ "checklist": {
+ "fields": {
+ "copyChecklistSource": "Prototype",
+ "name": "Name"
+ },
+ "name": "Checklist | Checklists"
+ },
+ "checklistItem": {
+ "fields": {
+ "text": "Text"
+ },
+ "name": "Checklist entry"
+ },
+ "contentType": {
+ "name": "Contenttype | Contenttypes"
+ },
+ "day": {
+ "fields": {
+ "dayResponsibles": "Responsible of the day"
+ },
+ "name": "Day | Days"
+ },
+ "materialItem": {
+ "fields": {
+ "article": "Article",
+ "list": "Material list",
+ "quantity": "Quantity",
+ "reference": "Activity / Period",
+ "unit": "Unit"
+ }
+ },
+ "materialList": {
+ "fields": {
+ "name": "Name"
+ },
+ "name": "Material list"
+ },
+ "period": {
+ "defaultDescription": "Main",
+ "fields": {
+ "description": "Description",
+ "end": "End",
+ "start": "Start"
+ },
+ "name": "Period | Periods"
+ },
+ "profile": {
+ "fields": {
+ "abbreviation": "Abbreviation",
+ "color": "Color",
+ "email": "Email address",
+ "firstname": "Firstname",
+ "language": "Language",
+ "nickname": "Nickname",
+ "password": "Password",
+ "surname": "Lastname"
+ },
+ "name": "Profile"
+ },
+ "scheduleEntry": {
+ "fields": {
+ "duration": "Duration",
+ "endDate": "Enddate",
+ "endDatetime": "Endtime",
+ "nr": "No.",
+ "startDate": "Startdate",
+ "startDatetime": "Starttime",
+ "time": "Time"
+ },
+ "name": "Activity scheduled"
+ }
+ },
+ "global": {
+ "datetime": {
+ "dateLong": "dd L",
+ "dateShort": "dd M/D",
+ "dateTimeLong": "dd L LT",
+ "duration": {
+ "daysAndHours": "{days} d {hours} h",
+ "daysAndHoursAndMinutes": "{days} d {hours} h {minutes} min",
+ "daysAndMinutes": "{days} d {minutes} min",
+ "hoursAndMinutes": "{hours} h {minutes} m",
+ "daysOnly": "{days} s",
+ "hoursOnly": "{hours} h",
+ "minutesOnly": "{minutes} m"
+ },
+ "hourLong": "LT",
+ "hourShort": "H:mm"
+ },
+ "shortScheduleEntryDescription": "day {dayNumber} {startTime}"
+ },
+ "print": {
+ "activityList": {
+ "title": "Activity list"
+ },
+ "config": {
+ "periods": "Period(s)"
+ },
+ "cover": {
+ "title": "Cover page"
+ },
+ "picasso": {
+ "picassoFooter": {
+ "coach": "Coach: {coach}",
+ "courseNumber": "Course number: {courseNumber}",
+ "leaders": "Lead: {leaders}",
+ "trainingAdvisor": "Training advisor: {trainingAdvisor}"
+ },
+ "title": "Program overview {period}"
+ },
+ "program": {
+ "title": "Program"
+ },
+ "summary": {
+ "safetyConsiderations": {
+ "title": "Safety considerations"
+ },
+ "storycontext": {
+ "title": "Story"
+ }
+ },
+ "toc": {
+ "title": "Table of contents"
+ }
+ }
+}
diff --git a/frontend-vue3/src/common/locales/fr-CH-scout.json b/frontend-vue3/src/common/locales/fr-CH-scout.json
new file mode 100644
index 0000000000..34679437cb
--- /dev/null
+++ b/frontend-vue3/src/common/locales/fr-CH-scout.json
@@ -0,0 +1,7 @@
+{
+ "print": {
+ "story": {
+ "title": "Fil rouge"
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/common/locales/fr.json b/frontend-vue3/src/common/locales/fr.json
new file mode 100644
index 0000000000..5631aa95ed
--- /dev/null
+++ b/frontend-vue3/src/common/locales/fr.json
@@ -0,0 +1,298 @@
+{
+ "components": {
+ "summary": {
+ "summaryDay": {
+ "noContent": "Les activités de cette journée ne contiennent aucun contenu {contentType}."
+ }
+ }
+ },
+ "contentNode": {
+ "checklist": {
+ "info": "Sélectionnez les éléments pertinents de la check-list qui sont couverts par cette activité (objectifs du cours, etc.).",
+ "name": "Check-lists"
+ },
+ "columnLayout": {
+ "entity": {
+ "column": {
+ "name": "Colonne|Colonne {name}"
+ }
+ },
+ "name": "Disposition des colonnes"
+ },
+ "laThematicArea": {
+ "entity": {
+ "option": {
+ "campsiteAndSurroundings": {
+ "description": "Aménagement d’un camp/des environs, démontage, aménagement d’une place de jeu et fabrication d’engins de sport.",
+ "name": "Campement/Environs"
+ },
+ "natureAndEnvironment": {
+ "description": "Faune et flore, protection de l’environnement dans le cadre du camp, météorologie et astronomie, techniques de transmission, préparation et allumage d’un feu.",
+ "name": "Nature et environment"
+ },
+ "outdoorTechnique": {
+ "description": "Planification d’une randonnée, lecture de carte (p. ex. check-list NORDA), croquis, utilisation d’instruments (p.ex. boussole, récepteur GPS, alti- mètre, etc.), orientation dans le terrain.",
+ "name": "Techniques de plein air"
+ },
+ "pioneeringTechnique": {
+ "description": "Aménagement d’un bivouac, construction d’un igloo, connaissance du matériel et de l’équipement, entretien du matériel, construction et démontage des installations, cordages et nœuds, tyroliennes, ponts de cordes, descentes en rappel.",
+ "name": "Technique de pionnier"
+ },
+ "preventionAndIntegration": {
+ "description": "Activités favorisant la prévention et l’intégration ou développant les compétences des participants dans ce domaine.",
+ "name": "Prévention et intégration"
+ },
+ "security": {
+ "description": "Sécurité lors des activités au camp, mesures à prendre en cas d’accident et alerte, premiers secours, réflexions sur la sécurité.",
+ "name": "Sécurité"
+ }
+ }
+ },
+ "info": "Une activité de camp J+S doit aborder au moins un des sujets énumérés.{br}Sélectionne les sujets abordés dans ce bloc.",
+ "name": "Domaine thématique AC"
+ },
+ "learningObjectives": {
+ "info": "Formuler en objectifs les compétences que les participant·e·s auront après cette activité.",
+ "name": "Objectifs d’apprentissage"
+ },
+ "learningTopics": {
+ "info": "Lister les sujets sur lesquels les participant·e·s apprendront quelque chose dans cette activité.",
+ "name": "Sujets d'apprentissage"
+ },
+ "material": {
+ "info": "Tu peux saisir ici les besoins en matériel pour ce bloc.{br}Tu peux gérer les listes de matériel dans le menu 'Admin'.{br}Tu peux trouver un résumé des achats dans le menu 'Matériel'.",
+ "name": "Matériel"
+ },
+ "notes": {
+ "info": "Tu peux y inscrire tes notes, par exemple des idées, des tâches à faire, des questions ouvertes, des contacts, des correspondances avec les transports publics, etc.",
+ "name": "Remarques"
+ },
+ "responsiveLayout": {
+ "mainContent": "Contenu principal",
+ "name": "Disposition par défaut",
+ "printAboveMainContent": "Imprimer au-dessus du contenu principal",
+ "printBelowMainContent": "Imprimer sous le contenu principal"
+ },
+ "safetyConsiderations": {
+ "info": "Certains blocs nécessitent de réfléchir aux risques. Tu peux enregistrer ces réflexions ici.{br}Enregistre les risques que tu as identifiés - et comment tu peux y faire face.",
+ "name": "Considérations sur la sécurité"
+ },
+ "storyboard": {
+ "entity": {
+ "section": {
+ "fields": {
+ "column1": "Heure",
+ "column2Html": "Programme",
+ "column3": "Responsable"
+ },
+ "name": "Section du programme | Sections du programme"
+ }
+ },
+ "info": "Ici, tu peux planifier le contenu de ce bloc.{br}Dans la colonne de gauche [Temps], tu peux enregistrer la durée des différents éléments.{br}Dans la colonne de droite [Responsable], tu peux assigner des personnes.",
+ "name": "Sections du programme"
+ },
+ "storycontext": {
+ "info": "Décris comment ce bloc s'intègre dans l'histoire du camp.{br}Tu peux trouver un résumé de tous les éléments de l'histoire dans le menu 'Histoire'.{br}Tu peux aussi d'abord élaborer une histoire continue dans le menu 'Histoire' - pour que tu puisses parfaitement intégrer le contenu du bloc dans l'histoire.",
+ "name": "Histoire"
+ }
+ },
+ "entity": {
+ "activity": {
+ "fields": {
+ "category": "Catégorie d'activité",
+ "location": "Lieu",
+ "progressLabel": "Statut",
+ "responsible": "Responsable",
+ "title": "Titre"
+ },
+ "name": "Activité",
+ "new": "Nouvelle activité"
+ },
+ "activityProgressLabel": {
+ "fields": {
+ "title": "Titre"
+ }
+ },
+ "camp": {
+ "collaborators": {
+ "guest": "Invité",
+ "invite": "Inviter",
+ "manager": "Administration",
+ "member": "Membre"
+ },
+ "fields": {
+ "addressCity": "Ville",
+ "addressName": "Nom",
+ "addressStreet": "Rue",
+ "addressZipcode": "Code postal",
+ "coachName": "Nom du·de la coach J+S",
+ "courseKind": "Type de cours (pour les cours J+S : terminologie J+S)",
+ "courseNumber": "Numéro de cours",
+ "kind": "Type de camp (chalet, tente, itinérant, été, automne)",
+ "motto": "Fil rouge / Thème",
+ "organizer": "Organisateur",
+ "printYSLogoOnPicasso": "Imprimer le logo J+S sur le programme général (requis pour les cours J+S)",
+ "shortTitle": "Nom du camp court",
+ "title": "Nom du camp",
+ "trainingAdvisorName": "Nom du coach J+S"
+ },
+ "name": "Camp",
+ "prototype": "Modèle de camp"
+ },
+ "campCollaboration": {
+ "fields": {
+ "abbreviation": "Abréviation",
+ "color": "Couleur",
+ "inviteEmail": "E-mail",
+ "role": "Role",
+ "status": "Statut"
+ },
+ "status": {
+ "established": "Actif",
+ "inactive": "Inactif",
+ "invited": "Invité"
+ }
+ },
+ "category": {
+ "fields": {
+ "color": "Couleur",
+ "name": "Nom",
+ "numberingStyle": "Style de numérotation",
+ "short": "Abréviation"
+ },
+ "name": "Catégories d'activités",
+ "numberingStyles": {
+ "-": "pas de numérotation",
+ "1": "1, 2, 3 - numéros",
+ "A": "A, B, C - lettres majuscules",
+ "I": "I, II, III - chiffres romains majuscules",
+ "a": "a, b, c - lettres minuscules",
+ "i": "i, ii, iii - chiffres romains minuscules"
+ }
+ },
+ "checklist": {
+ "fields": {
+ "copyChecklistSource": "Exemple",
+ "name": "Nom"
+ },
+ "name": "Check-list | Check-lists"
+ },
+ "checklistItem": {
+ "fields": {
+ "text": "Texte"
+ },
+ "name": "Elément de check-list"
+ },
+ "contentType": {
+ "name": "Type de contenu | Types de contenu"
+ },
+ "day": {
+ "fields": {
+ "dayResponsibles": "Responsable du jour"
+ },
+ "name": "Jour | Jours"
+ },
+ "materialItem": {
+ "fields": {
+ "article": "Article",
+ "list": "Liste de matériel",
+ "quantity": "Quantité",
+ "reference": "Activité / Période",
+ "unit": "Unité"
+ }
+ },
+ "materialList": {
+ "fields": {
+ "name": "Nom"
+ },
+ "name": "Liste de matériel"
+ },
+ "period": {
+ "defaultDescription": "Camp principal",
+ "fields": {
+ "description": "Description",
+ "end": "Fin",
+ "start": "Début"
+ },
+ "name": "Période | Périodes"
+ },
+ "profile": {
+ "fields": {
+ "abbreviation": "Abréviation",
+ "color": "Couleur",
+ "email": "Adresse e-mail",
+ "firstname": "Prénom",
+ "language": "Langue",
+ "nickname": "Surnom",
+ "password": "Mot de passe",
+ "surname": "Nom de famille"
+ },
+ "name": "Profil"
+ },
+ "scheduleEntry": {
+ "fields": {
+ "duration": "Durée",
+ "endDate": "Date de fin",
+ "endDatetime": "Heure de fin",
+ "nr": "No.",
+ "startDate": "Date de début",
+ "startDatetime": "Heure de début",
+ "time": "Moment"
+ },
+ "name": "Inscription au calendrier"
+ }
+ },
+ "global": {
+ "datetime": {
+ "dateLong": "dd L",
+ "dateShort": "dd D.M.",
+ "dateTimeLong": "dd L LT",
+ "duration": {
+ "daysAndHours": "{days} d {hours} h",
+ "daysAndHoursAndMinutes": "{days} d {hours} h {minutes} min",
+ "daysAndMinutes": "{days} d {minutes} min",
+ "hoursAndMinutes": "{hours} h {minutes} min",
+ "daysOnly": "{days} d",
+ "hoursOnly": "{hours} h",
+ "minutesOnly": "{minutes} min"
+ },
+ "hourLong": "LT",
+ "hourShort": "H:mm"
+ },
+ "shortScheduleEntryDescription": "jour{dayNumber} {startTime}"
+ },
+ "print": {
+ "activityList": {
+ "title": "Liste d'activités"
+ },
+ "config": {
+ "periods": "Période(s) du camp"
+ },
+ "cover": {
+ "title": "Page de couverture"
+ },
+ "picasso": {
+ "picassoFooter": {
+ "coach": "Coach: {coach}",
+ "courseNumber": "Numéro de cours: {courseNumber}",
+ "leaders": "Responsable: {leaders}",
+ "trainingAdvisor": "Conseiller à la formation: {trainingAdvisor}"
+ },
+ "title": "Aperçu du programme {period}"
+ },
+ "program": {
+ "title": "Programme"
+ },
+ "summary": {
+ "safetyConsiderations": {
+ "title": "Considérations sur la sécurité"
+ },
+ "storycontext": {
+ "title": "Histoire"
+ }
+ },
+ "toc": {
+ "title": "Table des matières"
+ }
+ }
+}
diff --git a/frontend-vue3/src/common/locales/it-CH-scout.json b/frontend-vue3/src/common/locales/it-CH-scout.json
new file mode 100644
index 0000000000..9e26dfeeb6
--- /dev/null
+++ b/frontend-vue3/src/common/locales/it-CH-scout.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/frontend-vue3/src/common/locales/it.json b/frontend-vue3/src/common/locales/it.json
new file mode 100644
index 0000000000..a35244b580
--- /dev/null
+++ b/frontend-vue3/src/common/locales/it.json
@@ -0,0 +1,249 @@
+{
+ "components": {
+ "summary": {
+ "summaryDay": {
+ "noContent": "Nessun contenuto '{contentType}' trovato in questo giorno..."
+ }
+ }
+ },
+ "contentNode": {
+ "columnLayout": {
+ "entity": {
+ "column": {
+ "name": "Colonna|Colonna {name}"
+ }
+ },
+ "name": "Layout delle colonne"
+ },
+ "laThematicArea": {
+ "entity": {
+ "option": {
+ "campsiteAndSurroundings": {
+ "description": "Allestire campo/dintorni, smontare le costruzioni, preparare le installazioni per il terreno da gioco e le attrezzature sportive.",
+ "name": "Campo/dintorni"
+ },
+ "natureAndEnvironment": {
+ "description": "Flora e fauna, tutela dell’ambiente al campo, meteorologia e astronomia, tecniche di trasmissione, accensione di un fuoco.",
+ "name": "Natura e ambiente"
+ },
+ "outdoorTechnique": {
+ "description": "Pianificazione delle escursioni, lettura delle carte topografiche (p. es. NORDA), schizzi topografici, strumenti di supporto (p.es. bussola, GPS, altimetro, ecc.), orientamento sul terreno.",
+ "name": "Tecniche outdoor"
+ },
+ "pioneeringTechnique": {
+ "description": "Installare il bivacco, costruire un igloo, tecniche relative a materiali ed equipaggiamento, effettuare la manutenzione del materiale, montare e smontare le costruzioni pionieristiche, tecniche delle corde e dei nodi, tirolese, ponti di corda, discesa in corda doppia.",
+ "name": "Tecnica pionieristica"
+ },
+ "preventionAndIntegration": {
+ "description": "Attività volte a promuovere la prevenzione e l’integrazione nonché a migliorare le competenze dei partecipanti in questo ambito.",
+ "name": "Prevenzione e integrazione"
+ },
+ "security": {
+ "description": "Sicurezza durante le attività al campo, organizzazione in caso di infortuni e sistema di allerta, primi soccorsi, riflessioni sulla sicurezza.",
+ "name": "Sicurezza"
+ }
+ }
+ },
+ "info": "Un'attività del campo Y+S deve trattare almeno uno degli argomenti elencati.{br}Seleziona gli argomenti da trattare in questo blocco.",
+ "name": "Area tematica AC"
+ },
+ "material": {
+ "info": "Qui puoi inserire i requisiti del materiale per questo blocco.{br}Puoi gestire gli elenchi dei materiali nel menu 'Amministrazione'.{br}Puoi trovare un riepilogo degli acquisti nel menu 'Materiale'.",
+ "name": "Materiale"
+ },
+ "notes": {
+ "info": "Qui puoi inserire qualsiasi nota, ad esempio idee, impegni, domande aperte, contatti, collegamenti con i mezzi pubblici, ecc.",
+ "name": "Noti"
+ },
+ "responsiveLayout": {
+ "mainContent": "Contenuto principale",
+ "name": "Layout di default",
+ "printAboveMainContent": "Stampa sopra il contenuto principale",
+ "printBelowMainContent": "Stampa sotto il contenuto principale"
+ },
+ "safetyConsiderations": {
+ "info": "Alcuni blocchi richiedono una riflessione sui rischi. Qui puoi registrare questi pensieri.{br}Registra i rischi che hai identificato e come puoi affrontarli.",
+ "name": "Considerazioni sulla sicurezza"
+ },
+ "storyboard": {
+ "entity": {
+ "section": {
+ "fields": {
+ "column1": "Tempo",
+ "column2Html": "Programma",
+ "column3": "Responsabile"
+ },
+ "name": "Sezione del programma | Sezioni del programma"
+ }
+ },
+ "info": "Qui puoi pianificare il contenuto di questo blocco.{br}Nella colonna di sinistra [Tempo] puoi registrare la durata dei singoli elementi.{br}Nella colonna di destra [Responsabile] puoi assegnare delle persone.",
+ "name": "Programma"
+ },
+ "storycontext": {
+ "info": "Descrivi come questo blocco si inserisce nella storia del campo.{br}Puoi trovare un riepilogo di tutti gli elementi della storia nel menu \"Storia\".{br}Puoi anche elaborare prima una storia continua nel menu \"Storia\", in modo da incorporare perfettamente il contenuto del blocco nella storia.",
+ "name": "Storia"
+ }
+ },
+ "entity": {
+ "activity": {
+ "fields": {
+ "category": "Categoria di attività",
+ "location": "Posto",
+ "progressLabel": "Stato",
+ "responsible": "Responsabile",
+ "title": "Titolo"
+ },
+ "name": "Attività",
+ "new": "Nuova attività"
+ },
+ "activityProgressLabel": {
+ "fields": {
+ "title": "Titolo"
+ }
+ },
+ "camp": {
+ "collaborators": {
+ "guest": "Ospite",
+ "invite": "Invita",
+ "manager": "Amministrazione",
+ "member": "Membro"
+ },
+ "fields": {
+ "addressCity": "Città",
+ "addressName": "Nome",
+ "addressStreet": "Via",
+ "addressZipcode": "Codice postale",
+ "motto": "Motto / Tema",
+ "shortTitle": "Titolo breve",
+ "title": "Titolo"
+ },
+ "name": "Campo",
+ "prototype": "Modello di campo"
+ },
+ "campCollaboration": {
+ "fields": {
+ "abbreviation": "Abbreviazione",
+ "color": "Colore",
+ "inviteEmail": "E-mail",
+ "role": "Ruolo",
+ "status": "Stato"
+ },
+ "status": {
+ "inactive": "non attivo"
+ }
+ },
+ "category": {
+ "fields": {
+ "color": "Colore",
+ "name": "Nome",
+ "numberingStyle": "Stile della numerazione",
+ "short": "Abbreviazione"
+ },
+ "name": "Categorie di attività",
+ "numberingStyles": {
+ "1": "1, 2, 3 - numeri",
+ "A": "A, B, C - maiuscole di blocco",
+ "I": "I, II, III - numeri romani maiuscoli",
+ "a": "a, b, c - lettere minuscole",
+ "i": "i, ii, iii - numeri romani minuscoli"
+ }
+ },
+ "contentType": {
+ "name": "Tipo di contenuto | Tipi di contenuto"
+ },
+ "day": {
+ "fields": {
+ "dayResponsibles": "Responsabile del giorno"
+ },
+ "name": "Giorno | Giorni"
+ },
+ "materialItem": {
+ "fields": {
+ "article": "Articolo",
+ "list": "Elenco dei materiali",
+ "quantity": "Quantità",
+ "reference": "Attività / Periodo",
+ "unit": "Unità"
+ }
+ },
+ "materialList": {
+ "fields": {
+ "name": "Nome"
+ },
+ "name": "Elenco dei materiali"
+ },
+ "period": {
+ "defaultDescription": "Campo principale",
+ "fields": {
+ "description": "Descrizione",
+ "end": "Fine",
+ "start": "Inizio"
+ },
+ "name": "Periodo | Periodi"
+ },
+ "profile": {
+ "fields": {
+ "abbreviation": "Abbreviazione",
+ "color": "Colore",
+ "email": "Indirizzo email",
+ "firstname": "Nome",
+ "language": "Lingua",
+ "nickname": "Soprannome",
+ "password": "Parola d'ordine",
+ "surname": "Cognome"
+ },
+ "name": "Profilo"
+ },
+ "scheduleEntry": {
+ "fields": {
+ "duration": "Durata",
+ "endDate": "Data di fine",
+ "endDatetime": "Ora di fine",
+ "nr": "N.",
+ "startDate": "Data di inizio",
+ "startDatetime": "Ora di inizio",
+ "time": "Tempo"
+ },
+ "name": "Inserimento nel programma"
+ }
+ },
+ "global": {
+ "datetime": {
+ "dateLong": "dd L",
+ "dateShort": "dd D.M.",
+ "dateTimeLong": "dd L LT",
+ "duration": {
+ "hoursAndMinutes": "{hours}h {minutes}min",
+ "hoursOnly": "{hours}h",
+ "minutesOnly": "{minutes}min"
+ },
+ "hourLong": "LT",
+ "hourShort": "H:mm"
+ }
+ },
+ "print": {
+ "config": {
+ "periods": "Sezione/i portante/i"
+ },
+ "cover": {
+ "title": "Pagina di copertina"
+ },
+ "picasso": {
+ "title": "Panoramica del programma {period}"
+ },
+ "program": {
+ "title": "Programma"
+ },
+ "summary": {
+ "safetyConsiderations": {
+ "title": "Considerazioni sulla sicurezza"
+ },
+ "storycontext": {
+ "title": "Storia"
+ }
+ },
+ "toc": {
+ "title": "Indice dei contenuti"
+ }
+ }
+}
diff --git a/frontend-vue3/src/common/locales/rm-CH-scout.json b/frontend-vue3/src/common/locales/rm-CH-scout.json
new file mode 100644
index 0000000000..0851f8f04f
--- /dev/null
+++ b/frontend-vue3/src/common/locales/rm-CH-scout.json
@@ -0,0 +1,7 @@
+{
+ "print": {
+ "story": {
+ "title": "Fil cotschen"
+ }
+ }
+}
diff --git a/frontend-vue3/src/common/locales/rm.json b/frontend-vue3/src/common/locales/rm.json
new file mode 100644
index 0000000000..ea13c3db30
--- /dev/null
+++ b/frontend-vue3/src/common/locales/rm.json
@@ -0,0 +1,16 @@
+{
+ "entity": {
+ "profile": {
+ "fields": {
+ "abbreviation": "Abbreviaziun",
+ "color": "Colur",
+ "email": "Adressa dad e-mail",
+ "firstname": "Prenum",
+ "language": "Lingua",
+ "nickname": "Surnum",
+ "password": "Pled-clav",
+ "surname": "Num da famiglia"
+ }
+ }
+ }
+}
diff --git a/frontend-vue3/src/components/activity/ActivityResponsibles.vue b/frontend-vue3/src/components/activity/ActivityResponsibles.vue
new file mode 100644
index 0000000000..709cb3d967
--- /dev/null
+++ b/frontend-vue3/src/components/activity/ActivityResponsibles.vue
@@ -0,0 +1,195 @@
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/ButtonNestedContentNodeAdd.vue b/frontend-vue3/src/components/activity/ButtonNestedContentNodeAdd.vue
new file mode 100644
index 0000000000..4b31c5f67e
--- /dev/null
+++ b/frontend-vue3/src/components/activity/ButtonNestedContentNodeAdd.vue
@@ -0,0 +1,184 @@
+
+
+
+
+
+ mdi-plus-circle-outline
+ {{ $t('global.button.add') }}
+
+
+
+
+
+
+ {{ $t(contentTypeIconKey(contentType)) }}
+
+
+ {{ $t(contentTypeNameKey(contentType)) }}
+
+
+
+
+
+
+
+
+ {{ $t(contentTypeIconKey(contentType)) }}
+
+
+ {{ $t(contentTypeNameKey(contentType)) }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/ContentNode.vue b/frontend-vue3/src/components/activity/ContentNode.vue
new file mode 100644
index 0000000000..5b9d393811
--- /dev/null
+++ b/frontend-vue3/src/components/activity/ContentNode.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/DaySwitcher.vue b/frontend-vue3/src/components/activity/DaySwitcher.vue
new file mode 100644
index 0000000000..1927df1baa
--- /dev/null
+++ b/frontend-vue3/src/components/activity/DaySwitcher.vue
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+
+ mdi-menu-down
+
+
+
+
+
+ {{ daySelection.number }}.
+
+
+ {{ $date.utc(daySelection.start).format('dd. DD. MMM') }}
+
+
+
+
+
+
+
+ {{ day.number }}.
+
+
+ {{ $date.utc(day.start).format('dd. DD. MMM') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/DraggableContentNodes.vue b/frontend-vue3/src/components/activity/DraggableContentNodes.vue
new file mode 100644
index 0000000000..9575e359ed
--- /dev/null
+++ b/frontend-vue3/src/components/activity/DraggableContentNodes.vue
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/MenuCardlessContentNode.vue b/frontend-vue3/src/components/activity/MenuCardlessContentNode.vue
new file mode 100644
index 0000000000..cddba342a8
--- /dev/null
+++ b/frontend-vue3/src/components/activity/MenuCardlessContentNode.vue
@@ -0,0 +1,78 @@
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
+
+ mdi-trash-can-outline
+
+
+ {{ deleteCaption }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/RootNode.vue b/frontend-vue3/src/components/activity/RootNode.vue
new file mode 100644
index 0000000000..052d65946a
--- /dev/null
+++ b/frontend-vue3/src/components/activity/RootNode.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/ScheduleEntry.vue b/frontend-vue3/src/components/activity/ScheduleEntry.vue
new file mode 100644
index 0000000000..e9bb80b21d
--- /dev/null
+++ b/frontend-vue3/src/components/activity/ScheduleEntry.vue
@@ -0,0 +1,535 @@
+
+
+
+
+
+
+
+ {{ scheduleEntry.number }}
+
+
+
+
+
+
+ mdi-autorenew
+
+ mdi-alert
+
+ mdi-chevron-down
+
+
+
+
+
+
+
+
+ {{ cat.name }}
+
+
+
+
+
+ {{ activity.title }}
+
+
+
+ mdi-pencil
+
+
+
+
+
+
+
+
+
+ mdi-file-document-edit-outline
+ {{ $t('components.activity.scheduleEntry.backToContents') }}
+
+ {{ $t('global.button.back') }}
+
+
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-puzzle-edit-outline
+
+
+ {{ $t('components.activity.scheduleEntry.changeLayout') }}
+
+
+
+
+
+
+
+ mdi-content-copy
+
+
+ {{ $t('components.activity.scheduleEntry.copyScheduleEntry') }}
+
+
+
+
+
+
+
+
+
+
+
+ mdi-delete
+
+
+ {{ $t('global.button.delete') }}
+
+
+
+ {{ $t('components.activity.scheduleEntry.deleteWarning') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/TogglePaperSize.vue b/frontend-vue3/src/components/activity/TogglePaperSize.vue
new file mode 100644
index 0000000000..33e87d66c5
--- /dev/null
+++ b/frontend-vue3/src/components/activity/TogglePaperSize.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+ {{
+ value
+ ? $t('components.activity.togglePaperSize.switchToFullSize')
+ : $t('components.activity.togglePaperSize.switchToPaperSize')
+ }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/Checklist.vue b/frontend-vue3/src/components/activity/content/Checklist.vue
new file mode 100644
index 0000000000..85e5184507
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/Checklist.vue
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+
+
+
+ {{ $t('global.button.edit') }}
+
+
+
+
+
+
+
+
+
+
+ {{ checklist.name }}
+
+ ({{
+ selectionContentNode.filter(
+ (item) =>
+ checkedItems.includes(item.id) &&
+ item.checklist()._meta.self === checklist?._meta?.self
+ ).length
+ }}
+ selected)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/ColumnLayout.vue b/frontend-vue3/src/components/activity/content/ColumnLayout.vue
new file mode 100644
index 0000000000..de1a98a61e
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/ColumnLayout.vue
@@ -0,0 +1,212 @@
+
+
+
+
+ $columnLayout
+ {{ $t('contentNode.columnLayout.name') }}
+
+
+
+
+
+
+ resizeColumn(slot, newWidth)"
+ @resize-stop="saveColumnWidths"
+ >
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/LAThematicArea.vue b/frontend-vue3/src/components/activity/content/LAThematicArea.vue
new file mode 100644
index 0000000000..9627adade6
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/LAThematicArea.vue
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+ {{ $t(`contentNode.laThematicArea.entity.option.${key}.name`) }}
+
+
+ {{
+ $t(`contentNode.laThematicArea.entity.option.${key}.description`)
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.text }}
+ {{ item.description }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/LearningObjectives.vue b/frontend-vue3/src/components/activity/content/LearningObjectives.vue
new file mode 100644
index 0000000000..f3c2232ffb
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/LearningObjectives.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/LearningTopics.vue b/frontend-vue3/src/components/activity/content/LearningTopics.vue
new file mode 100644
index 0000000000..a45a623b2a
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/LearningTopics.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/Material.vue b/frontend-vue3/src/components/activity/content/Material.vue
new file mode 100644
index 0000000000..db78fe5c85
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/Material.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/Notes.vue b/frontend-vue3/src/components/activity/content/Notes.vue
new file mode 100644
index 0000000000..df269748e6
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/Notes.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/ResponsiveLayout.vue b/frontend-vue3/src/components/activity/content/ResponsiveLayout.vue
new file mode 100644
index 0000000000..c055410562
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/ResponsiveLayout.vue
@@ -0,0 +1,191 @@
+
+
+
+
+ $responsiveLayout
+ {{ $t('contentNode.responsiveLayout.name') }}
+
+
+
+
+
+
+ {{ $t('contentNode.responsiveLayout.mainContent') }}
+
+
+
+
+
+ {{ $t('contentNode.responsiveLayout.printAboveMainContent') }}
+
+
+
+
+
+
+ {{ $t('contentNode.responsiveLayout.printBelowMainContent') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/SafetyConsiderations.vue b/frontend-vue3/src/components/activity/content/SafetyConsiderations.vue
new file mode 100644
index 0000000000..ce88a04358
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/SafetyConsiderations.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/Storyboard.vue b/frontend-vue3/src/components/activity/content/Storyboard.vue
new file mode 100644
index 0000000000..1a87ee2005
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/Storyboard.vue
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+ {{ $t('components.activity.content.storyboard.reorder') }}
+
+
+
+ {{ $t('contentNode.storyboard.entity.section.fields.column1') }}
+
+
+ {{ $t('contentNode.storyboard.entity.section.fields.column2Html') }}
+
+
+ {{ $t('contentNode.storyboard.entity.section.fields.column3') }}
+
+
+
+ {{ $t('components.activity.content.storyboard.controls') }}
+
+
+
+
+
+
+
+
+
+
+ mdi-plus
+
+
+
+
+
+
+ mdi-plus
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/Storycontext.vue b/frontend-vue3/src/components/activity/content/Storycontext.vue
new file mode 100644
index 0000000000..fd16cbb610
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/Storycontext.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/checklist/ChecklistItem.vue b/frontend-vue3/src/components/activity/content/checklist/ChecklistItem.vue
new file mode 100644
index 0000000000..4ae9e7883e
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/checklist/ChecklistItem.vue
@@ -0,0 +1,60 @@
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/checklist/ChecklistItems.vue b/frontend-vue3/src/components/activity/content/checklist/ChecklistItems.vue
new file mode 100644
index 0000000000..83cf028e7b
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/checklist/ChecklistItems.vue
@@ -0,0 +1,55 @@
+
+
+
+ {{ checklist.name }}
+
+
+
+
+ /
+ {{
+ parent.text
+ }}
+
+
+
+ {{ parents.map(({ position }) => position + 1 + '.').join('')
+ }}{{ item.position + 1 }}. {{ item.text }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/columnLayout/ColumnIndicator.vue b/frontend-vue3/src/components/activity/content/columnLayout/ColumnIndicator.vue
new file mode 100644
index 0000000000..345bf732cd
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/columnLayout/ColumnIndicator.vue
@@ -0,0 +1,37 @@
+
+
+
+ {{ $t('contentNode.columnLayout.entity.column.name', 2, { name: slotName }) }}
+ {{ width + '0%' }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/columnLayout/ColumnOperations.vue b/frontend-vue3/src/components/activity/content/columnLayout/ColumnOperations.vue
new file mode 100644
index 0000000000..1c6fe5dc80
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/columnLayout/ColumnOperations.vue
@@ -0,0 +1,97 @@
+
+
+
+
+ mdi-playlist-plus
+
+
+ {{ $t('components.activity.content.columnLayout.columnOperations.addColumn') }}
+
+
+
+
+ mdi-playlist-minus
+
+
+ {{
+ $t('components.activity.content.columnLayout.columnOperations.removeColumn')
+ }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/columnLayout/ResizableColumn.vue b/frontend-vue3/src/components/activity/content/columnLayout/ResizableColumn.vue
new file mode 100644
index 0000000000..b58a4aa4fc
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/columnLayout/ResizableColumn.vue
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/columnLayout/ResizableColumnHeader.vue b/frontend-vue3/src/components/activity/content/columnLayout/ResizableColumnHeader.vue
new file mode 100644
index 0000000000..0791270e7b
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/columnLayout/ResizableColumnHeader.vue
@@ -0,0 +1,169 @@
+
+
+
+
+ mdi-arrow-split-vertical
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/columnLayout/__tests__/calculateNextSlotName.spec.js b/frontend-vue3/src/components/activity/content/columnLayout/__tests__/calculateNextSlotName.spec.js
new file mode 100644
index 0000000000..a2a2324432
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/columnLayout/__tests__/calculateNextSlotName.spec.js
@@ -0,0 +1,73 @@
+import { describe, expect, it } from 'vitest'
+import { calculateNextSlotName, adjustColumnWidths } from '../calculateNextSlotName.js'
+
+describe('generating a next slot name', () => {
+ const examples = [
+ [[], '1'],
+ [[''], '1'],
+ [['0'], '1'],
+ [['1'], '2'],
+ [['a'], '1'],
+ [['A'], '1'],
+ [['9'], '1'],
+ [['z'], '1'],
+ [['Z'], '1'],
+ [['0.'], '1'],
+ [['9.'], '1'],
+ [['999'], '1'],
+ [['1', '2'], '3'],
+ [['1', '3'], '2'],
+ [['1z', '1'], '2'],
+ [['mitte', 'oben', 'unten'], '1'],
+ [['😋'], '1'],
+ [['a😋'], '1'],
+ [['1', '2', '3', '4', '5', '6', '7', '8', '9'], '10'],
+ [['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], '11'],
+ ]
+
+ examples.forEach(([input, expected]) => {
+ it(input.toString(), () => {
+ expect(calculateNextSlotName(input)).toEqual(expected)
+ })
+ })
+})
+
+describe('adjusting the column widths', () => {
+ // prettier-ignore
+ const examples = [
+ [[], []],
+ // compacting columns
+ [[{ name: '1', width: 20 }], [12]],
+ [[{ name: '1', width: 12 }, { name: '2', width: 3 }], [9, 3]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 9 }, { name: '3', width: 3 }], [3, 6, 3]],
+ [[{ name: '1', width: 4 }, { name: '2', width: 8 }, { name: '3', width: 3 }], [4, 5, 3]],
+ [[{ name: '1', width: 5 }, { name: '2', width: 7 }, { name: '3', width: 3 }], [5, 4, 3]],
+ [[{ name: '1', width: 6 }, { name: '2', width: 6 }, { name: '3', width: 3 }], [6, 3, 3]],
+ [[{ name: '1', width: 7 }, { name: '2', width: 5 }, { name: '3', width: 3 }], [6, 3, 3]],
+ [[{ name: '1', width: 8 }, { name: '2', width: 4 }, { name: '3', width: 3 }], [6, 3, 3]],
+ [[{ name: '1', width: 9 }, { name: '2', width: 3 }, { name: '3', width: 3 }], [6, 3, 3]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 3 }, { name: '3', width: 6 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 4 }, { name: '3', width: 5 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 4 }, { name: '2', width: 3 }, { name: '3', width: 5 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 5 }, { name: '3', width: 4 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 4 }, { name: '2', width: 4 }, { name: '3', width: 4 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 5 }, { name: '2', width: 3 }, { name: '3', width: 4 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 6 }, { name: '3', width: 3 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 4 }, { name: '2', width: 5 }, { name: '3', width: 3 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 5 }, { name: '2', width: 4 }, { name: '3', width: 3 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 6 }, { name: '2', width: 3 }, { name: '3', width: 3 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ // expanding columns
+ [[{ name: '1', width: 10 }], [12]],
+ [[{ name: '1', width: 1 }, { name: '2', width: 3 }], [3, 9]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 3 }], [3, 9]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 3 }, { name: '3', width: 3 }], [3, 3, 6]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 3 }, { name: '3', width: 2 }, { name: '4', width: 3 }], [3, 3, 3, 3]],
+ [[{ name: '1', width: 3 }, { name: '2', width: 3 }, { name: '3', width: 3 }, { name: '4', width: 3 }], [3, 3, 3, 3]]
+ ]
+
+ examples.forEach(([input, expected]) => {
+ it(input.map((col) => col.width).toString(), () => {
+ expect(adjustColumnWidths(input).map((col) => col.width)).toEqual(expected)
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/activity/content/columnLayout/calculateNextSlotName.js b/frontend-vue3/src/components/activity/content/columnLayout/calculateNextSlotName.js
new file mode 100644
index 0000000000..4230abb92c
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/columnLayout/calculateNextSlotName.js
@@ -0,0 +1,32 @@
+import cloneDeep from 'lodash-es/cloneDeep'
+
+export function calculateNextSlotName(slotNames) {
+ let i = 0
+
+ while (true) {
+ if (!slotNames.includes((++i).toString())) return i.toString()
+ }
+}
+
+export function adjustColumnWidths(columns, minWidth = 3, maxWidth = 12) {
+ const cols = cloneDeep(columns)
+
+ if (cols.length < 1) return cols
+
+ // Enforce minimum column widths
+ cols.forEach((col) => {
+ col.width = Math.max(minWidth, col.width)
+ })
+
+ // Make sure the column widths sum up to maxWidth
+ let excess = cols.reduce((sum, col) => sum + col.width, 0) - maxWidth
+ let i = cols.length - 1
+ while (excess !== 0 && i >= 0) {
+ const diff = Math.min(Math.max(0, cols[i].width - minWidth), excess)
+ cols[i].width -= diff
+ excess -= diff
+ i--
+ }
+
+ return cols
+}
diff --git a/frontend-vue3/src/components/activity/content/contentTypeIcons.js b/frontend-vue3/src/components/activity/content/contentTypeIcons.js
new file mode 100644
index 0000000000..c327708e20
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/contentTypeIcons.js
@@ -0,0 +1,18 @@
+/**
+ * Maps content type to mdi icon
+ */
+const contentTypeIcons = {
+ checklist: 'mdi-clipboard-list-outline',
+ columnLayout: 'mdi-view-column',
+ laThematicArea: 'mdi-shape',
+ learningObjectives: 'mdi-school',
+ learningTopics: 'mdi-school',
+ material: 'mdi-package-variant',
+ notes: 'mdi-pen',
+ responsiveLayout: 'mdi-view-compact',
+ safetyConsiderations: 'mdi-security',
+ storyboard: 'mdi-script-text-outline',
+ storycontext: 'mdi-book-open-variant',
+}
+
+export default contentTypeIcons
diff --git a/frontend-vue3/src/components/activity/content/layout/ContentNodeCard.vue b/frontend-vue3/src/components/activity/content/layout/ContentNodeCard.vue
new file mode 100644
index 0000000000..77cd22c118
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/layout/ContentNodeCard.vue
@@ -0,0 +1,173 @@
+
+
+
+
+ {{ icon }}
+
+
+
+
+
+
+ {{ instanceOrContentTypeName }}
+
+
+
+ mdi-pencil
+
+
+
+
+
+
+
+
+ mdi-trash-can-outline
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/layout/LayoutItem.vue b/frontend-vue3/src/components/activity/content/layout/LayoutItem.vue
new file mode 100644
index 0000000000..b439c67edc
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/layout/LayoutItem.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/layout/LayoutNodeCard.vue b/frontend-vue3/src/components/activity/content/layout/LayoutNodeCard.vue
new file mode 100644
index 0000000000..d6f32a6886
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/layout/LayoutNodeCard.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/storyboard/StoryboardDialogRemoveSection.vue b/frontend-vue3/src/components/activity/content/storyboard/StoryboardDialogRemoveSection.vue
new file mode 100644
index 0000000000..0d3a25e8cf
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/storyboard/StoryboardDialogRemoveSection.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+ {{
+ $t(
+ 'components.activity.content.storyboard.storyboardDialogRemoveSection.deleteWarning'
+ )
+ }}
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/storyboard/StoryboardRowDefault.vue b/frontend-vue3/src/components/activity/content/storyboard/StoryboardRowDefault.vue
new file mode 100644
index 0000000000..6800cbc2ce
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/storyboard/StoryboardRowDefault.vue
@@ -0,0 +1,105 @@
+
+
+
+
+ mdi-drag
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-delete-outline
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/storyboard/StoryboardRowDense.vue b/frontend-vue3/src/components/activity/content/storyboard/StoryboardRowDense.vue
new file mode 100644
index 0000000000..ecd6fbf2dd
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/storyboard/StoryboardRowDense.vue
@@ -0,0 +1,121 @@
+
+
+
+
+ mdi-drag
+
+
+
+
+
+
+
+
+
+ mdi-delete-outline
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/content/storyboard/StoryboardSortable.vue b/frontend-vue3/src/components/activity/content/storyboard/StoryboardSortable.vue
new file mode 100644
index 0000000000..dc6a036cd4
--- /dev/null
+++ b/frontend-vue3/src/components/activity/content/storyboard/StoryboardSortable.vue
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/dialog/DialogActivityEdit.vue b/frontend-vue3/src/components/activity/dialog/DialogActivityEdit.vue
new file mode 100644
index 0000000000..0043eb1a77
--- /dev/null
+++ b/frontend-vue3/src/components/activity/dialog/DialogActivityEdit.vue
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/dialog/DialogActivityForm.vue b/frontend-vue3/src/components/activity/dialog/DialogActivityForm.vue
new file mode 100644
index 0000000000..b28db8a9d7
--- /dev/null
+++ b/frontend-vue3/src/components/activity/dialog/DialogActivityForm.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/dialog/FormScheduleEntryItem.vue b/frontend-vue3/src/components/activity/dialog/FormScheduleEntryItem.vue
new file mode 100644
index 0000000000..5daee45abb
--- /dev/null
+++ b/frontend-vue3/src/components/activity/dialog/FormScheduleEntryItem.vue
@@ -0,0 +1,348 @@
+
+
+
+
+
+
+
+
-
+
+
+
+ {{ item.label }} ({{ item.duration }})
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/activity/dialog/FormScheduleEntryList.vue b/frontend-vue3/src/components/activity/dialog/FormScheduleEntryList.vue
new file mode 100644
index 0000000000..1520279553
--- /dev/null
+++ b/frontend-vue3/src/components/activity/dialog/FormScheduleEntryList.vue
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/buttons/ButtonAdd.vue b/frontend-vue3/src/components/buttons/ButtonAdd.vue
new file mode 100644
index 0000000000..5ec7fbe396
--- /dev/null
+++ b/frontend-vue3/src/components/buttons/ButtonAdd.vue
@@ -0,0 +1,27 @@
+
+
+ {{ icon }}
+
+ {{ $t('global.button.add') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/buttons/ButtonBack.vue b/frontend-vue3/src/components/buttons/ButtonBack.vue
new file mode 100644
index 0000000000..fe96c591cc
--- /dev/null
+++ b/frontend-vue3/src/components/buttons/ButtonBack.vue
@@ -0,0 +1,27 @@
+
+
+ mdi-arrow-left
+
+ {{ $t('global.button.back') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/buttons/ButtonCancel.vue b/frontend-vue3/src/components/buttons/ButtonCancel.vue
new file mode 100644
index 0000000000..85b58839ff
--- /dev/null
+++ b/frontend-vue3/src/components/buttons/ButtonCancel.vue
@@ -0,0 +1,11 @@
+
+
+ {{ $t('global.button.cancel') }}
+
+
+
+
diff --git a/frontend-vue3/src/components/buttons/ButtonContinue.vue b/frontend-vue3/src/components/buttons/ButtonContinue.vue
new file mode 100644
index 0000000000..b605a8b39c
--- /dev/null
+++ b/frontend-vue3/src/components/buttons/ButtonContinue.vue
@@ -0,0 +1,11 @@
+
+
+ {{ $t('global.button.continue') }}
+
+
+
+
diff --git a/frontend-vue3/src/components/buttons/ButtonDelete.vue b/frontend-vue3/src/components/buttons/ButtonDelete.vue
new file mode 100644
index 0000000000..addcb1a40c
--- /dev/null
+++ b/frontend-vue3/src/components/buttons/ButtonDelete.vue
@@ -0,0 +1,41 @@
+
+
+ {{ icon }}
+ {{ icon }}
+ {{ icon }}
+
+
+ {{ $t('global.button.delete') }}
+
+
+ {{ $t('global.button.delete') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/buttons/ButtonEdit.vue b/frontend-vue3/src/components/buttons/ButtonEdit.vue
new file mode 100644
index 0000000000..773a34982f
--- /dev/null
+++ b/frontend-vue3/src/components/buttons/ButtonEdit.vue
@@ -0,0 +1,27 @@
+
+
+ {{ $t('global.button.edit') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/buttons/ButtonRetry.vue b/frontend-vue3/src/components/buttons/ButtonRetry.vue
new file mode 100644
index 0000000000..7b36033998
--- /dev/null
+++ b/frontend-vue3/src/components/buttons/ButtonRetry.vue
@@ -0,0 +1,12 @@
+
+
+ mdi-refresh
+ {{ $t('global.button.tryagain') }}
+
+
+
+
diff --git a/frontend-vue3/src/components/buttons/IconButton.vue b/frontend-vue3/src/components/buttons/IconButton.vue
new file mode 100644
index 0000000000..b941009aa5
--- /dev/null
+++ b/frontend-vue3/src/components/buttons/IconButton.vue
@@ -0,0 +1,48 @@
+
+
+
+ {{ icon }}
+
+
+
+
+
+ {{ icon }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/camp/CampListItem.vue b/frontend-vue3/src/components/camp/CampListItem.vue
new file mode 100644
index 0000000000..5b28ccf631
--- /dev/null
+++ b/frontend-vue3/src/components/camp/CampListItem.vue
@@ -0,0 +1,43 @@
+
+
+
+
+ {{ camp.title }}
+ {{ date }}
+
+
+ {{ camp.motto }}
+ {{ camp.organizer }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CampActivityProgressLabels.vue b/frontend-vue3/src/components/campAdmin/CampActivityProgressLabels.vue
new file mode 100644
index 0000000000..513c387207
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CampActivityProgressLabels.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+ {{ $t('components.campAdmin.campActivityProgressLabels.create') }}
+
+
+
+
+
+
+
+
+ {{
+ parseInt(idx) + 1
+ }}
+
+
+ {{ progressLabel.title }}
+
+
+
+
+
+
+
+
+ {{
+ parseInt(idx) + 1
+ }}
+
+
+ {{ progressLabel.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ itemPosition + 1
+ }}
+
+
+ {{ item.title }}
+
+
+
+
+
+ mdi-drag
+
+
+
+
+
+
+
+ {{ reorder ? 'mdi-close' : 'mdi-sort' }}
+ {{
+ reorder
+ ? $t('components.campAdmin.campActivityProgressLabels.exit')
+ : $t('components.campAdmin.campActivityProgressLabels.reorder')
+ }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CampAddress.vue b/frontend-vue3/src/components/campAdmin/CampAddress.vue
new file mode 100644
index 0000000000..14b7a66487
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CampAddress.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CampCategories.vue b/frontend-vue3/src/components/campAdmin/CampCategories.vue
new file mode 100644
index 0000000000..47cf96af90
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CampCategories.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+ {{ $t('components.campAdmin.campCategories.create') }}
+
+
+
+
+
+
+
+
+
+
+ (1.{{ category.numberingStyle }}) {{ category.short }}: {{ category.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CampConditionalFields.vue b/frontend-vue3/src/components/campAdmin/CampConditionalFields.vue
new file mode 100644
index 0000000000..e98f852745
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CampConditionalFields.vue
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+ {{
+ $i18n.locale.includes('it') ? '$gs' : '$js'
+ }}
+ {{ $t('components.campAdmin.campConditionalFields.title') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CampDangerZone.vue b/frontend-vue3/src/components/campAdmin/CampDangerZone.vue
new file mode 100644
index 0000000000..2a44263480
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CampDangerZone.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+ {{ $t('components.campAdmin.campDangerZone.title') }}
+
+
+
+
+
+
+
+
+
+ {{ $t('components.campAdmin.campDangerZone.deleteCamp.title') }}
+
+
+ {{ $t('components.campAdmin.campDangerZone.deleteCamp.description') }}
+
+
+
+
+
+
+ {{ $t('global.button.delete') }}
+
+
+
+ {{
+ $t('components.campAdmin.campDangerZone.deleteCamp.explanation', 0, {
+ campTitle: camp.title,
+ })
+ }}
+
+
+ {{
+ $t('components.campAdmin.campDangerZone.deleteCamp.label', 0, {
+ campTitle: camp.title,
+ })
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CampPeriods.vue b/frontend-vue3/src/components/campAdmin/CampPeriods.vue
new file mode 100644
index 0000000000..9e7db1dde8
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CampPeriods.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+ {{ $t('components.campAdmin.campPeriods.createPeriod') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CampPeriodsListItem.vue b/frontend-vue3/src/components/campAdmin/CampPeriodsListItem.vue
new file mode 100644
index 0000000000..b5bcead9b5
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CampPeriodsListItem.vue
@@ -0,0 +1,150 @@
+
+
+
+
+
+ {{ period.description }}
+
+ {{ dateRange(period.start, period.end) }}
+
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
+ mdi-pencil
+
+ {{
+ $t('components.campAdmin.campPeriodsListItem.changePeriodDescription')
+ }}
+
+
+
+
+
+
+
+
+ mdi-arrow-left-right
+
+
+ {{ $t('components.campAdmin.campPeriodsListItem.movePeriod') }}
+
+
+
+
+
+
+
+
+
+ mdi-arrow-collapse-left
+
+
+ {{
+ $t('components.campAdmin.campPeriodsListItem.periodChangeStart')
+ }}
+
+
+
+
+
+
+
+
+ mdi-arrow-collapse-right
+
+
+ {{
+ $t('components.campAdmin.campPeriodsListItem.periodChangeEnd')
+ }}
+
+
+
+
+
+
+
+
+
+
+ mdi-delete
+
+
+ {{ $t('global.button.delete') }}
+
+
+
+
+ {{ $t('components.campAdmin.campPeriodsListItem.lastPeriodNotDeletable') }}
+
+
+ {{ $t('components.campAdmin.campPeriodsListItem.deleteWarning') }}
+
+
+ {{ period.description }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CampSettings.vue b/frontend-vue3/src/components/campAdmin/CampSettings.vue
new file mode 100644
index 0000000000..80573cbb00
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CampSettings.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/CreateCampPeriods.vue b/frontend-vue3/src/components/campAdmin/CreateCampPeriods.vue
new file mode 100644
index 0000000000..6cf3b809c8
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/CreateCampPeriods.vue
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+ {{ $t('entity.period.name') }}
+
+
+
+
+ mdi-close
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-plus
+ {{ $t('components.campAdmin.createCampPeriods.add') }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelCreate.vue b/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelCreate.vue
new file mode 100644
index 0000000000..b36aee8dfe
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelCreate.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelEdit.vue b/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelEdit.vue
new file mode 100644
index 0000000000..6aacbb9658
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelEdit.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelForm.vue b/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelForm.vue
new file mode 100644
index 0000000000..10b234db90
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogActivityProgressLabelForm.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogCategoryCreate.vue b/frontend-vue3/src/components/campAdmin/DialogCategoryCreate.vue
new file mode 100644
index 0000000000..ae31f768b6
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogCategoryCreate.vue
@@ -0,0 +1,244 @@
+
+
+
+
+
+
+
+
+
+
+ mdi-information-outline
+ {{ $t('components.campAdmin.dialogCategoryCreate.copyPasteCategory') }}
+
+
+
+
+
+
+
+
+ {{ $t('components.campAdmin.dialogCategoryCreate.clipboard') }}
+
+
+
+
+ mdi-clipboard-check-outline
+
+
+
+
+ {{ clipboardEntity.title }}
+
+
+ {{ clipboardEntity.camp().title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-content-paste
+
+
+ {{ $t('components.campAdmin.dialogCategoryCreate.copySourceInfo') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogCategoryForm.vue b/frontend-vue3/src/components/campAdmin/DialogCategoryForm.vue
new file mode 100644
index 0000000000..df18d9ff48
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogCategoryForm.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogMaterialListCreate.vue b/frontend-vue3/src/components/campAdmin/DialogMaterialListCreate.vue
new file mode 100644
index 0000000000..b35b8303f1
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogMaterialListCreate.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogMaterialListEdit.vue b/frontend-vue3/src/components/campAdmin/DialogMaterialListEdit.vue
new file mode 100644
index 0000000000..d3dc65aa46
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogMaterialListEdit.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogMaterialListForm.vue b/frontend-vue3/src/components/campAdmin/DialogMaterialListForm.vue
new file mode 100644
index 0000000000..c5338d8623
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogMaterialListForm.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogPeriodCreate.vue b/frontend-vue3/src/components/campAdmin/DialogPeriodCreate.vue
new file mode 100644
index 0000000000..579011ef68
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogPeriodCreate.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogPeriodDateEdit.vue b/frontend-vue3/src/components/campAdmin/DialogPeriodDateEdit.vue
new file mode 100644
index 0000000000..6b5f119db0
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogPeriodDateEdit.vue
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+ {{ $t('components.campAdmin.dialogPeriodDateEdit.movePeriod') }}
+
+
+
+
+ {{ $t('components.campAdmin.dialogPeriodDateEdit.periodChangeStart') }}
+
+
+
+
+ {{ $t('components.campAdmin.dialogPeriodDateEdit.periodChangeEnd') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogPeriodDescriptionEdit.vue b/frontend-vue3/src/components/campAdmin/DialogPeriodDescriptionEdit.vue
new file mode 100644
index 0000000000..80fbab432d
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogPeriodDescriptionEdit.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/DialogPeriodForm.vue b/frontend-vue3/src/components/campAdmin/DialogPeriodForm.vue
new file mode 100644
index 0000000000..05f42cf3b1
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/DialogPeriodForm.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campAdmin/ErrorExistingActivitiesList.vue b/frontend-vue3/src/components/campAdmin/ErrorExistingActivitiesList.vue
new file mode 100644
index 0000000000..4639472a44
--- /dev/null
+++ b/frontend-vue3/src/components/campAdmin/ErrorExistingActivitiesList.vue
@@ -0,0 +1,56 @@
+
+
+
+ {{ $t('components.campAdmin.errorExistingActivitiesList.description') }}
+
+
+
+ {{ activity.title }}
+
+
+
+ {{ scheduleEntry.number }}
+ {{ rangeShort(scheduleEntry.start, scheduleEntry.end, translate) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campCreate/CampCreate.vue b/frontend-vue3/src/components/campCreate/CampCreate.vue
new file mode 100644
index 0000000000..e30525d7fc
--- /dev/null
+++ b/frontend-vue3/src/components/campCreate/CampCreate.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+ {{ $t('components.campCreate.campCreate.steps.infos') }}
+
+
+
+ {{ $t('components.campCreate.campCreate.steps.template') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campCreate/CampCreateStep1.vue b/frontend-vue3/src/components/campCreate/CampCreateStep1.vue
new file mode 100644
index 0000000000..9fde37cb87
--- /dev/null
+++ b/frontend-vue3/src/components/campCreate/CampCreateStep1.vue
@@ -0,0 +1,101 @@
+
+
+
+
+ $emit('next-step'))">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('global.button.continue') }}
+
+
+ {{ $t('components.campCreate.campCreateStep1.submitTooltip') }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/campCreate/CampCreateStep2.vue b/frontend-vue3/src/components/campCreate/CampCreateStep2.vue
new file mode 100644
index 0000000000..6fc63bc8c7
--- /dev/null
+++ b/frontend-vue3/src/components/campCreate/CampCreateStep2.vue
@@ -0,0 +1,377 @@
+
+
+
+
+ $emit('create-camp'))">
+
+
+
+
+
+
+
+
+
+
+ mdi-content-paste
+
+
+
+
+
+ mdi-content-paste
+
+
+
+
+ {{ $t('components.campCreate.campCreateStep2.preview') }}
+
+
+
+ {{ $t('components.campCreate.campCreateStep2.category') }}
+
+
+
+
+ {{ category.name }}
+ {{
+ category
+ .preferredContentTypes()
+ .items.map((item) =>
+ $t('contentNode.' + camelCase(item.name) + '.name')
+ )
+ .join(', ') ||
+ $t('components.campCreate.campCreateStep2.noContent')
+ }}
+
+
+
+
+
+
+ {{ $t('components.campCreate.campCreateStep2.progressLabels') }}
+
+
+
+ {{
+ idx + 1
+ }}
+ {{ progressLabel.title }}
+
+
+
+
+
+ {{ $t('components.campCreate.campCreateStep2.materialLists') }}
+
+
+
+ {{ materialList.name }}
+
+
+
+
+
+
+ {{ $t('components.campCreate.campCreateStep2.checklists') }}
+
+
+
+ {{ checklist.name }}
+ {{
+ $t(
+ 'components.campCreate.campCreateStep2.checklistItemCount',
+ checklist.checklistItems().items.length
+ )
+ }}
+
+
+
+
+
+ {{
+ $t('components.campCreate.campCreateStep2.noPrototypeAlert.title')
+ }}
+
+ {{
+ $t('components.campCreate.campCreateStep2.noPrototypeAlert.description')
+ }}
+
+
+
+
+
+ mdi-arrow-left
+ {{ $t('global.button.back') }}
+
+
+
+
+ {{ $t('components.campCreate.campCreateStep2.create') }}
+
+
+
+
+ {{ $t('components.campCreate.campCreateStep2.create') }}
+
+
+ {{ $t('components.campCreate.campCreateStep2.submitTooltipPrototype') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/category/CategoryProperties.vue b/frontend-vue3/src/components/category/CategoryProperties.vue
new file mode 100644
index 0000000000..ecf8cc7ea0
--- /dev/null
+++ b/frontend-vue3/src/components/category/CategoryProperties.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/category/CategoryTemplate.vue b/frontend-vue3/src/components/category/CategoryTemplate.vue
new file mode 100644
index 0000000000..54e7e2cfd4
--- /dev/null
+++ b/frontend-vue3/src/components/category/CategoryTemplate.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-view-compact-outline
+ {{ $t('components.category.categoryTemplate.layout') }}
+
+
+ mdi-text
+ {{ $t('components.category.categoryTemplate.contents') }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('components.category.categoryTemplate.noTemplate') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/checklist/ChecklistCreate.vue b/frontend-vue3/src/components/checklist/ChecklistCreate.vue
new file mode 100644
index 0000000000..8522568ec7
--- /dev/null
+++ b/frontend-vue3/src/components/checklist/ChecklistCreate.vue
@@ -0,0 +1,104 @@
+
+
+
+ {{ $t('components.checklist.checklistCreate.title') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/checklist/ChecklistDetail.vue b/frontend-vue3/src/components/checklist/ChecklistDetail.vue
new file mode 100644
index 0000000000..d834688d1c
--- /dev/null
+++ b/frontend-vue3/src/components/checklist/ChecklistDetail.vue
@@ -0,0 +1,137 @@
+
+
+
+
+ {{ checklist.name }}
+
+
+ mdi-pencil
+
+
+
+
+
+
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
+
+ mdi-delete
+
+
+ {{ $t('global.button.delete') }}
+
+
+
+ {{ $t('components.checklist.checklistDetail.deleteWarning') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/checklist/ChecklistItemCreate.vue b/frontend-vue3/src/components/checklist/ChecklistItemCreate.vue
new file mode 100644
index 0000000000..3537f6859d
--- /dev/null
+++ b/frontend-vue3/src/components/checklist/ChecklistItemCreate.vue
@@ -0,0 +1,83 @@
+
+
+
+
+ {{ $t('components.checklist.checklistItemCreate.title') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/checklist/ChecklistItemEdit.vue b/frontend-vue3/src/components/checklist/ChecklistItemEdit.vue
new file mode 100644
index 0000000000..056658fa68
--- /dev/null
+++ b/frontend-vue3/src/components/checklist/ChecklistItemEdit.vue
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+ {{
+ $t('components.checklist.checklistItemEdit.delete', 0, {
+ text: checklistItem.text,
+ })
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/checklist/ChecklistItemParent.vue b/frontend-vue3/src/components/checklist/ChecklistItemParent.vue
new file mode 100644
index 0000000000..7bc1926990
--- /dev/null
+++ b/frontend-vue3/src/components/checklist/ChecklistItemParent.vue
@@ -0,0 +1,159 @@
+
+
+
+ {{ getPositionNumber(checklistItem) }}
+
+
+ {{ checklistItem.text }}
+
+
+
+ mdi-clipboard-check-multiple-outline
+
+
+
+
+
+
+ mdi-clipboard-check-multiple-outline
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/checklist/ChecklistOverview.vue b/frontend-vue3/src/components/checklist/ChecklistOverview.vue
new file mode 100644
index 0000000000..6f45701479
--- /dev/null
+++ b/frontend-vue3/src/components/checklist/ChecklistOverview.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+ {{ checklist.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/checklist/SortableChecklist.vue b/frontend-vue3/src/components/checklist/SortableChecklist.vue
new file mode 100644
index 0000000000..c6b71ffd8c
--- /dev/null
+++ b/frontend-vue3/src/components/checklist/SortableChecklist.vue
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+
+
+ mdi-plus
+
+ {{
+ $t('components.checklist.sortableChecklist.add', null, {
+ parent: parent?.text ?? checklist.name,
+ })
+ }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/checklist/SortableChecklistItem.vue b/frontend-vue3/src/components/checklist/SortableChecklistItem.vue
new file mode 100644
index 0000000000..973951a0a0
--- /dev/null
+++ b/frontend-vue3/src/components/checklist/SortableChecklistItem.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+ mdi-drag
+
+ {{
+ itemPosition + 1
+ }}
+
+ {{
+ item.text
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/collaborator/CollaboratorCreate.vue b/frontend-vue3/src/components/collaborator/CollaboratorCreate.vue
new file mode 100644
index 0000000000..b05140ace3
--- /dev/null
+++ b/frontend-vue3/src/components/collaborator/CollaboratorCreate.vue
@@ -0,0 +1,87 @@
+
+
+
+
+ {{ $t('components.collaborator.collaboratorCreate.inviteCta') }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/collaborator/CollaboratorEdit.vue b/frontend-vue3/src/components/collaborator/CollaboratorEdit.vue
new file mode 100644
index 0000000000..a39c68bad2
--- /dev/null
+++ b/frontend-vue3/src/components/collaborator/CollaboratorEdit.vue
@@ -0,0 +1,232 @@
+
+
+
+
+ {{
+ $t('components.collaborator.collaboratorEdit.delete', 0, {
+ name: name,
+ })
+ }}
+
+
+ {{
+ emailSent && !resendingEmail
+ ? $t('components.collaborator.collaboratorEdit.resentEmail')
+ : $t('components.collaborator.collaboratorEdit.resendEmail')
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('components.collaborator.collaboratorEdit.deactivate') }}
+
+
+
+
+
+ {{
+ $t('components.collaborator.collaboratorEdit.cannotRemoveLastManager')
+ }}
+
+
+ {{ $t('components.collaborator.collaboratorEdit.inviteAgain') }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/collaborator/CollaboratorForm.vue b/frontend-vue3/src/components/collaborator/CollaboratorForm.vue
new file mode 100644
index 0000000000..dc2a926beb
--- /dev/null
+++ b/frontend-vue3/src/components/collaborator/CollaboratorForm.vue
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+ {{ item.role }} ·
+ {{ icon }}
+
+
+
+
+
+
+
+ {{ item.role }}
+ {{ item.abilities }}
+
+
+ {{ icon }}
+
+
+
+
+ {{ item.role }} ·
+ {{ icon }}
+
+
+
+
+
+
+ {{ $t('components.collaborator.collaboratorForm.overrideAvatar') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/collaborator/CollaboratorList.vue b/frontend-vue3/src/components/collaborator/CollaboratorList.vue
new file mode 100644
index 0000000000..bc24af469c
--- /dev/null
+++ b/frontend-vue3/src/components/collaborator/CollaboratorList.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/collaborator/CollaboratorListItem.vue b/frontend-vue3/src/components/collaborator/CollaboratorListItem.vue
new file mode 100644
index 0000000000..c80abb2e25
--- /dev/null
+++ b/frontend-vue3/src/components/collaborator/CollaboratorListItem.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ {{ name }}
+
+
+
+
+
+ {{ $t(roles[collaborator.role].roleTranslation)
+ }}
+ ·
+ {{ icon }}
+
+
+ {{ $t(roles[collaborator.role].abilitiesTranslation) }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/collaborator/PromptCollaboratorDeactivate.vue b/frontend-vue3/src/components/collaborator/PromptCollaboratorDeactivate.vue
new file mode 100644
index 0000000000..89caf34be1
--- /dev/null
+++ b/frontend-vue3/src/components/collaborator/PromptCollaboratorDeactivate.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+ {{
+ $t('components.collaborator.promptCollaboratorDeactivate.warningText', 1, {
+ name: displayName,
+ })
+ }}
+
+
+
+ {{ error }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/collaborator/isOwnCampCollaboration.js b/frontend-vue3/src/components/collaborator/isOwnCampCollaboration.js
new file mode 100644
index 0000000000..1d6ef659cc
--- /dev/null
+++ b/frontend-vue3/src/components/collaborator/isOwnCampCollaboration.js
@@ -0,0 +1,19 @@
+/**
+ * @typedef Collaborator {
+ * user: () => { id: string },
+ * }
+ *
+ * @typedef Auth {
+ * user: { id: string },
+ * }
+ *
+ * @param {Collaborator} collaborator
+ * @param {Auth} auth
+ * @returns {boolean}
+ */
+export default function isOwnCampCollaboration(collaborator, auth) {
+ if (!(typeof collaborator.user === 'function')) {
+ return false
+ }
+ return auth.user?.id === collaborator.user().id
+}
diff --git a/frontend-vue3/src/components/dashboard/ActivityRow.vue b/frontend-vue3/src/components/dashboard/ActivityRow.vue
new file mode 100644
index 0000000000..45c897e88e
--- /dev/null
+++ b/frontend-vue3/src/components/dashboard/ActivityRow.vue
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+ {{
+ scheduleEntry.number
+ }}
+
+
+
+
+
+
+
+
+ {{ start }}
+ {{ duration }}
+
+
+
+
+
+
+
+ {{ title }}
+
+
+
+ {{ progressLabel }}
+
+
+
+
+ {{ location }}
+
+
+
+
+
+ {{ progressLabel }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/dashboard/BooleanFilter.vue b/frontend-vue3/src/components/dashboard/BooleanFilter.vue
new file mode 100644
index 0000000000..ced32fb1b4
--- /dev/null
+++ b/frontend-vue3/src/components/dashboard/BooleanFilter.vue
@@ -0,0 +1,19 @@
+
+ {{ label }}
+
+
+
diff --git a/frontend-vue3/src/components/dashboard/CountBadge.vue b/frontend-vue3/src/components/dashboard/CountBadge.vue
new file mode 100644
index 0000000000..b565599a2a
--- /dev/null
+++ b/frontend-vue3/src/components/dashboard/CountBadge.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/dashboard/FilterDivider.vue b/frontend-vue3/src/components/dashboard/FilterDivider.vue
new file mode 100644
index 0000000000..ff1d156e3a
--- /dev/null
+++ b/frontend-vue3/src/components/dashboard/FilterDivider.vue
@@ -0,0 +1,16 @@
+
+ |
+
+
+
+
+
diff --git a/frontend-vue3/src/components/dashboard/SelectFilter.vue b/frontend-vue3/src/components/dashboard/SelectFilter.vue
new file mode 100644
index 0000000000..77122cd7dc
--- /dev/null
+++ b/frontend-vue3/src/components/dashboard/SelectFilter.vue
@@ -0,0 +1,141 @@
+
+
+
+
+ {{
+ labelValue ? `${label}: ${labelValue}` : label
+ }}
+ {{ labelValue || label }}
+ mdi-chevron-down
+
+
+
+
+
+ {{
+ $t('components.dashboard.selectFilter.clear')
+ }}
+ mdi-close
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/dialog/DialogBase.vue b/frontend-vue3/src/components/dialog/DialogBase.vue
new file mode 100644
index 0000000000..0ae5508643
--- /dev/null
+++ b/frontend-vue3/src/components/dialog/DialogBase.vue
@@ -0,0 +1,167 @@
+
diff --git a/frontend-vue3/src/components/dialog/DialogBottomSheet.vue b/frontend-vue3/src/components/dialog/DialogBottomSheet.vue
new file mode 100644
index 0000000000..95ce4a831d
--- /dev/null
+++ b/frontend-vue3/src/components/dialog/DialogBottomSheet.vue
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ icon }}
+
+
+ {{ title }}
+
+
+ mdi-close
+ {{ $t('global.button.cancel') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ cancelLabel }}
+
+
+
+ {{ submitIcon }}
+
+ {{ submitLabel }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/dialog/DialogEntityDelete.vue b/frontend-vue3/src/components/dialog/DialogEntityDelete.vue
new file mode 100644
index 0000000000..f56e37f7b1
--- /dev/null
+++ b/frontend-vue3/src/components/dialog/DialogEntityDelete.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+ {{
+ $t('global.warning.delete', warningTextEntity ? 2 : 0, {
+ entity: warningTextEntity,
+ })
+ }}
+
+
+ {{ error }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/dialog/DialogForm.vue b/frontend-vue3/src/components/dialog/DialogForm.vue
new file mode 100644
index 0000000000..16c6ade583
--- /dev/null
+++ b/frontend-vue3/src/components/dialog/DialogForm.vue
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ icon }}
+
+
+ {{ title }}
+
+
+ mdi-close
+ {{ $t('global.button.cancel') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ cancelLabel }}
+
+
+
+ {{ submitIcon }}
+
+ {{ submitLabel }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/dialog/DialogUiBase.vue b/frontend-vue3/src/components/dialog/DialogUiBase.vue
new file mode 100644
index 0000000000..a150d5f0c6
--- /dev/null
+++ b/frontend-vue3/src/components/dialog/DialogUiBase.vue
@@ -0,0 +1,43 @@
+
diff --git a/frontend-vue3/src/components/form/ServerError.vue b/frontend-vue3/src/components/form/ServerError.vue
new file mode 100644
index 0000000000..e9a6fb04cf
--- /dev/null
+++ b/frontend-vue3/src/components/form/ServerError.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/ServerErrorContent.vue b/frontend-vue3/src/components/form/ServerErrorContent.vue
new file mode 100644
index 0000000000..c78629d4dd
--- /dev/null
+++ b/frontend-vue3/src/components/form/ServerErrorContent.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiCheckbox.vue b/frontend-vue3/src/components/form/api/ApiCheckbox.vue
new file mode 100644
index 0000000000..c4add43c94
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiCheckbox.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiColorField.vue b/frontend-vue3/src/components/form/api/ApiColorField.vue
new file mode 100644
index 0000000000..99adae9d08
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiColorField.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiColorPicker.vue b/frontend-vue3/src/components/form/api/ApiColorPicker.vue
new file mode 100644
index 0000000000..ab4187fa8d
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiColorPicker.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiDatePicker.vue b/frontend-vue3/src/components/form/api/ApiDatePicker.vue
new file mode 100644
index 0000000000..5fbce2f547
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiDatePicker.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiForm.vue b/frontend-vue3/src/components/form/api/ApiForm.vue
new file mode 100644
index 0000000000..e2ff169690
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiForm.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiNumberField.vue b/frontend-vue3/src/components/form/api/ApiNumberField.vue
new file mode 100644
index 0000000000..2ce6affc41
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiNumberField.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiRichtext.vue b/frontend-vue3/src/components/form/api/ApiRichtext.vue
new file mode 100644
index 0000000000..559af1fef3
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiRichtext.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiSelect.vue b/frontend-vue3/src/components/form/api/ApiSelect.vue
new file mode 100644
index 0000000000..ef45c04df2
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiSelect.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+ mdi-menu-down
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiSortable.vue b/frontend-vue3/src/components/form/api/ApiSortable.vue
new file mode 100644
index 0000000000..80fe07c586
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiSortable.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiSwitch.vue b/frontend-vue3/src/components/form/api/ApiSwitch.vue
new file mode 100644
index 0000000000..47ab4059b3
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiSwitch.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiTextField.vue b/frontend-vue3/src/components/form/api/ApiTextField.vue
new file mode 100644
index 0000000000..a216138b09
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiTextField.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiTextarea.vue b/frontend-vue3/src/components/form/api/ApiTextarea.vue
new file mode 100644
index 0000000000..52d8ca64db
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiTextarea.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiTimePicker.vue b/frontend-vue3/src/components/form/api/ApiTimePicker.vue
new file mode 100644
index 0000000000..c25716bb51
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiTimePicker.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiWrapper.vue b/frontend-vue3/src/components/form/api/ApiWrapper.vue
new file mode 100644
index 0000000000..07c28f4169
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiWrapper.vue
@@ -0,0 +1,299 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/ApiWrapperAppend.vue b/frontend-vue3/src/components/form/api/ApiWrapperAppend.vue
new file mode 100644
index 0000000000..d658066fe8
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/ApiWrapperAppend.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
+ mdi-content-save
+
+
+
+
+
+
+
+
+ mdi-refresh
+
+
+ {{ $t('global.button.tryagain') }}
+
+
+
+
+ mdi-close
+
+
+ {{ $t('global.button.cancel') }}
+
+
+
+
+
+
+
+ mdi-check
+
+
+ {{ $t('global.button.save') }}
+
+
+
+
+ mdi-close
+
+
+ {{ $t('global.button.cancel') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/IconSuccess.vue b/frontend-vue3/src/components/form/api/IconSuccess.vue
new file mode 100644
index 0000000000..0f8080fff9
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/IconSuccess.vue
@@ -0,0 +1,48 @@
+
+
+
+
+ mdi-check
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiCheckbox.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiCheckbox.spec.js
new file mode 100644
index 0000000000..0cfa44a3e7
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiCheckbox.spec.js
@@ -0,0 +1,98 @@
+import { describe, beforeEach, afterEach, vi, test, expect } from 'vitest'
+import ApiCheckbox from '../ApiCheckbox.vue'
+import ApiWrapper from '@/components/form/api/ApiWrapper.vue'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+import flushPromises from 'flush-promises'
+import formBaseComponents from '@/plugins/formBaseComponents'
+import merge from 'lodash-es/merge'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+import { i18n } from '@/plugins'
+import { mount as mountComponent } from '@vue/test-utils'
+import { waitForDebounce } from '@/test/util'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ApiCheckbox', () => {
+ let vuetify
+ let wrapper
+ let apiMock
+
+ const path = 'test-field/123'
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ wrapper.destroy()
+ })
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ApiCheckbox },
+ props: {
+ path: { type: String, default: path },
+ },
+ template: `
+
+ `,
+ })
+ apiMock.get().thenReturn(ApiMock.success(true).forPath(path))
+ const defaultOptions = {
+ mocks: {
+ $tc: () => {},
+ api: apiMock.getMocks(),
+ },
+ }
+ return mountComponent(app, {
+ vuetify,
+ i18n,
+ attachTo: document.body,
+ ...merge(defaultOptions, options),
+ })
+ }
+
+ test('triggers api.patch and status update if input changes', async () => {
+ apiMock.patch().thenReturn(ApiMock.success(false))
+ wrapper = mount()
+
+ await flushPromises()
+
+ const input = wrapper.find('input')
+ await input.trigger('click')
+ await input.trigger('submit')
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ expect(wrapper.findComponent(ApiWrapper).vm.localValue).toBe(false)
+ })
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ wrapper = mount()
+ apiMock.get().thenReturn(ApiMock.success(false).forPath(path))
+
+ wrapper.findComponent(ApiWrapper).vm.reload()
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(wrapper.findComponent(ApiWrapper).vm.localValue).toBe(false)
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('false')
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiColorField.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiColorField.spec.js
new file mode 100644
index 0000000000..134e705bac
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiColorField.spec.js
@@ -0,0 +1,93 @@
+import { describe, beforeEach, afterEach, vi, test, expect } from 'vitest'
+import ApiColorField from '../ApiColorField.vue'
+import { fireEvent, screen, waitFor } from '@testing-library/vue'
+import { render } from '@/test/renderWithVuetify.js'
+import user from '@testing-library/user-event'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+import { extend } from 'vee-validate'
+import { regex } from 'vee-validate/dist/rules'
+import { ColorSpace, sRGB } from 'colorjs.io/fn'
+
+extend('regex', regex)
+
+ColorSpace.register(sRGB)
+describe('An ApiColorField', () => {
+ let apiMock
+
+ const FIELD_PATH = 'test-field/123'
+ const FIELD_LABEL = 'Test field'
+ const COLOR_1 = '#FF0000'
+ const COLOR_2 = '#FAFFAF'
+
+ beforeEach(() => {
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ test('triggers api.patch and status update if input changes', async () => {
+ // given
+ apiMock.get().thenReturn(ApiMock.success(COLOR_1).forPath(FIELD_PATH))
+ apiMock.patch().thenReturn(ApiMock.success(COLOR_2))
+ render(ApiColorField, {
+ props: {
+ autoSave: false,
+ path: FIELD_PATH,
+ uri: 'test-field/123',
+ label: FIELD_LABEL,
+ required: true,
+ },
+ mocks: {
+ api: apiMock.getMocks(),
+ },
+ })
+
+ // when
+ const inputField = await screen.findByLabelText(FIELD_LABEL)
+ inputField.value = COLOR_2
+ await fireEvent.input(inputField)
+ // click the button to open the picker
+ // click the save button
+ await waitFor(async () => {
+ await user.click(screen.getByLabelText('Speichern'))
+ })
+
+ // then
+ await waitFor(async () => {
+ const inputField = await screen.findByLabelText(FIELD_LABEL)
+ expect(inputField.value).toBe(COLOR_2)
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ })
+ })
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ // given
+ apiMock.get().thenReturn(ApiMock.networkError().forPath(FIELD_PATH))
+ render(ApiColorField, {
+ props: {
+ autoSave: false,
+ path: FIELD_PATH,
+ uri: 'test-field/123',
+ label: FIELD_LABEL,
+ required: true,
+ },
+ mocks: {
+ api: apiMock.getMocks(),
+ },
+ })
+ await screen.findByText('A network error occurred.')
+ expect((await screen.findByLabelText(FIELD_LABEL)).value).not.toBe(COLOR_1)
+ const retryButton = await screen.findByText('Erneut versuchen')
+ apiMock.get().thenReturn(ApiMock.success(COLOR_1).forPath(FIELD_PATH))
+
+ // when
+ await user.click(retryButton)
+
+ // then
+ await waitFor(async () => {
+ expect((await screen.findByLabelText(FIELD_LABEL)).value).toBe(COLOR_1)
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiColorPicker.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiColorPicker.spec.js
new file mode 100644
index 0000000000..c8e67f30a6
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiColorPicker.spec.js
@@ -0,0 +1,95 @@
+import { describe, beforeEach, afterEach, vi, test, expect } from 'vitest'
+import ApiColorPicker from '../ApiColorPicker.vue'
+import { screen, waitFor } from '@testing-library/vue'
+import { render } from '@/test/renderWithVuetify.js'
+import user from '@testing-library/user-event'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+import { extend } from 'vee-validate'
+import { regex } from 'vee-validate/dist/rules'
+import { ColorSpace, sRGB } from 'colorjs.io/fn'
+
+extend('regex', regex)
+
+ColorSpace.register(sRGB)
+describe('An ApiColorPicker', () => {
+ let apiMock
+
+ const FIELD_PATH = 'test-field/123'
+ const FIELD_LABEL = 'Test field'
+ const COLOR_1 = '#FF0000'
+ const COLOR_2 = '#FAFFAF'
+ const PICKER_BUTTON_LABEL_TEXT = 'Dialog öffnen, um eine Farbe für Test field zu wählen'
+
+ beforeEach(() => {
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ test('triggers api.patch and status update if input changes', async () => {
+ // given
+ apiMock.get().thenReturn(ApiMock.success(COLOR_1).forPath(FIELD_PATH))
+ apiMock.patch().thenReturn(ApiMock.success(COLOR_2))
+ const { container } = render(ApiColorPicker, {
+ props: {
+ autoSave: false,
+ path: FIELD_PATH,
+ uri: 'test-field/123',
+ label: FIELD_LABEL,
+ required: true,
+ },
+ mocks: {
+ api: apiMock.getMocks(),
+ },
+ })
+
+ // when
+ // click the button to open the picker
+ await user.click(screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT))
+ // click inside the color picker canvas to select a different color
+ const canvas = container.querySelector('canvas')
+ await user.click(canvas, { clientX: 10, clientY: 10 })
+ // click the save button
+ await waitFor(async () => {
+ await user.click(screen.getByLabelText('Speichern'))
+ })
+
+ // then
+ await waitFor(async () => {
+ const inputField = await screen.findByLabelText(FIELD_LABEL)
+ expect(inputField.value).toBe(COLOR_2)
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ })
+ })
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ // given
+ apiMock.get().thenReturn(ApiMock.networkError().forPath(FIELD_PATH))
+ render(ApiColorPicker, {
+ props: {
+ autoSave: false,
+ path: FIELD_PATH,
+ uri: 'test-field/123',
+ label: FIELD_LABEL,
+ required: true,
+ },
+ mocks: {
+ api: apiMock.getMocks(),
+ },
+ })
+ await screen.findByText('A network error occurred.')
+ expect((await screen.findByLabelText(FIELD_LABEL)).value).not.toBe(COLOR_1)
+ const retryButton = await screen.findByText('Erneut versuchen')
+ apiMock.get().thenReturn(ApiMock.success(COLOR_1).forPath(FIELD_PATH))
+
+ // when
+ await user.click(retryButton)
+
+ // then
+ await waitFor(async () => {
+ expect((await screen.findByLabelText(FIELD_LABEL)).value).toBe(COLOR_1)
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiDatePicker.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiDatePicker.spec.js
new file mode 100644
index 0000000000..c1a7afbaf5
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiDatePicker.spec.js
@@ -0,0 +1,87 @@
+import { describe, beforeEach, afterEach, vi, test, expect, it } from 'vitest'
+import ApiDatePicker from '../ApiDatePicker.vue'
+import { screen, waitFor } from '@testing-library/vue'
+import { render, setTestLocale } from '@/test/renderWithVuetify.js'
+import user from '@testing-library/user-event'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+
+describe('An ApiDatePicker', () => {
+ let apiMock
+
+ const FIELD_PATH = 'test-field/123'
+ const FIELD_LABEL = 'Test field'
+ const DATE_1 = '2020-03-01'
+ const DATE_2 = '2020-03-19'
+ const PICKER_BUTTON_LABEL_TEXT = 'Dialog öffnen, um ein Datum für Test field zu wählen'
+
+ beforeEach(() => {
+ setTestLocale('de')
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ it('triggers api.patch and status update if input changes', async () => {
+ // given
+ apiMock.get().thenReturn(ApiMock.success(DATE_1).forPath(FIELD_PATH))
+ apiMock.patch().thenReturn(ApiMock.success(DATE_2))
+ render(ApiDatePicker, {
+ props: {
+ autoSave: false,
+ path: FIELD_PATH,
+ uri: 'test-field/123',
+ label: FIELD_LABEL,
+ required: true,
+ },
+ mocks: {
+ api: apiMock.getMocks(),
+ },
+ })
+
+ // when
+ // click the button to open the picker
+ await user.click(screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT))
+ // click the 19th day of the month
+ await user.click(screen.getByText('19'))
+ // click the save button
+ await user.click(screen.getByLabelText('Speichern'))
+
+ // then
+ await waitFor(async () => {
+ const inputField = await screen.findByLabelText(FIELD_LABEL)
+ expect(inputField.value).toBe('19.03.2020')
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ })
+ })
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ // given
+ apiMock.get().thenReturn(ApiMock.networkError().forPath(FIELD_PATH))
+ render(ApiDatePicker, {
+ props: {
+ autoSave: false,
+ path: FIELD_PATH,
+ uri: 'test-field/123',
+ label: FIELD_LABEL,
+ required: true,
+ },
+ mocks: {
+ api: apiMock.getMocks(),
+ },
+ })
+ await screen.findByText('A network error occurred.')
+ expect((await screen.findByLabelText(FIELD_LABEL)).value).not.toBe('01.03.2020')
+ const retryButton = await screen.findByText('Erneut versuchen')
+ apiMock.get().thenReturn(ApiMock.success(DATE_1).forPath(FIELD_PATH))
+
+ // when
+ await user.click(retryButton)
+
+ // then
+ await waitFor(async () => {
+ expect((await screen.findByLabelText(FIELD_LABEL)).value).toBe('01.03.2020')
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiMock.js b/frontend-vue3/src/components/form/api/__tests__/ApiMock.js
new file mode 100644
index 0000000000..96eb8438aa
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiMock.js
@@ -0,0 +1,125 @@
+import { vi } from 'vitest'
+
+function mockPromiseResolving(value) {
+ return new Promise((resolve) => {
+ const timer = setTimeout(() => {
+ clearTimeout(timer)
+ resolve(value)
+ }, 100)
+ })
+}
+
+class MockStubbing {
+ constructor(path, value) {
+ this._path = path
+ this._value = value
+ }
+
+ forPath(path) {
+ this._path = path
+ return this
+ }
+
+ get path() {
+ return this._path
+ }
+
+ get value() {
+ return this._value
+ }
+}
+
+class NetworkErrorMockStubbing extends MockStubbing {
+ constructor() {
+ super()
+ }
+}
+
+class ApiMockState {
+ constructor() {
+ this._get = vi.fn()
+ this._patch = vi.fn()
+ }
+
+ getMocks() {
+ return {
+ get: this._get,
+ patch: this._patch,
+ }
+ }
+
+ get() {
+ const apiMock = this
+ return {
+ thenReturn(mockStubbing) {
+ if (!(mockStubbing instanceof MockStubbing)) {
+ throw new Error('apiMock must be instance of MockStubbing')
+ }
+ if (mockStubbing instanceof NetworkErrorMockStubbing) {
+ if (mockStubbing.path === undefined || mockStubbing.value !== undefined) {
+ throw new Error('path must be defined and value must be undefined')
+ }
+ const result = {
+ _meta: {
+ load: Promise.reject({
+ name: 'Network error',
+ message: 'A network error occurred.',
+ }),
+ },
+ }
+ result[mockStubbing.path] = () => result
+ apiMock._get.mockReturnValue(result)
+ return this
+ }
+ if (mockStubbing.path === undefined || mockStubbing.value === undefined) {
+ throw new Error('path and value must be defined')
+ }
+ apiMock._get.mockReturnValue({
+ [mockStubbing.path]: mockStubbing.value,
+ _meta: {
+ load: Promise.resolve(mockStubbing.value),
+ },
+ })
+ return this
+ },
+ }
+ }
+
+ patch() {
+ const apiMock = this
+ return {
+ thenReturn(mockStubbing) {
+ if (!(mockStubbing instanceof MockStubbing)) {
+ throw new Error('apiMock must be instance of MockStubbing')
+ }
+ if (mockStubbing instanceof NetworkErrorMockStubbing) {
+ apiMock._patch.mockImplementation(() => {
+ throw {
+ name: 'NetworkError',
+ message: 'A network error occurred.',
+ }
+ })
+ return this
+ }
+ if (mockStubbing.path !== undefined || mockStubbing.value === undefined) {
+ throw new Error('path must be undefined and value must be defined')
+ }
+ apiMock._patch.mockReturnValue(mockPromiseResolving(mockStubbing.value))
+ return this
+ },
+ }
+ }
+}
+
+export class ApiMock {
+ static create() {
+ return new ApiMockState()
+ }
+
+ static success(value) {
+ return new MockStubbing(undefined, value)
+ }
+ static networkError() {
+ return new NetworkErrorMockStubbing()
+ }
+}
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiNumberField.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiNumberField.spec.js
new file mode 100644
index 0000000000..35735a5240
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiNumberField.spec.js
@@ -0,0 +1,96 @@
+import { describe, beforeEach, afterEach, vi, test, expect } from 'vitest'
+import ApiNumberField from '../ApiNumberField.vue'
+import ApiWrapper from '@/components/form/api/ApiWrapper.vue'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+import flushPromises from 'flush-promises'
+import formBaseComponents from '@/plugins/formBaseComponents'
+import merge from 'lodash-es/merge'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+import { i18n } from '@/plugins'
+import { mount as mountComponent } from '@vue/test-utils'
+import { waitForDebounce } from '@/test/util'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ApiNumberField', () => {
+ let vuetify
+ let wrapper
+ let apiMock
+
+ const path = 'test-field/123'
+ const NUMBER_1 = 1.2
+ const NUMBER_1_string = '1.2'
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ wrapper.destroy()
+ })
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ApiNumberField },
+ props: {
+ path: { type: String, default: path },
+ },
+ template: ``,
+ })
+ apiMock.get().thenReturn(ApiMock.success(NUMBER_1).forPath(path))
+ const defaultOptions = {
+ mocks: {
+ $tc: () => {},
+ api: apiMock.getMocks(),
+ },
+ }
+ return mountComponent(app, {
+ vuetify,
+ i18n,
+ attachTo: document.body,
+ ...merge(defaultOptions, options),
+ })
+ }
+
+ test('triggers api.patch and status update if input changes', async () => {
+ apiMock.patch().thenReturn(ApiMock.success(NUMBER_1))
+ wrapper = mount()
+
+ await flushPromises()
+
+ const input = wrapper.find('input')
+ await input.setValue(NUMBER_1)
+ await input.trigger('submit')
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ expect(wrapper.findComponent(ApiWrapper).vm.parsedLocalValue).toBe(NUMBER_1)
+ })
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ wrapper = mount()
+ apiMock.get().thenReturn(ApiMock.success(NUMBER_1).forPath(path))
+
+ wrapper.findComponent(ApiWrapper).vm.reload()
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(wrapper.findComponent(ApiWrapper).vm.parsedLocalValue).toBe(NUMBER_1)
+ expect(wrapper.find('input[type=text]').element.value).toBe(NUMBER_1_string)
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiSelect.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiSelect.spec.js
new file mode 100644
index 0000000000..9408d4d20b
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiSelect.spec.js
@@ -0,0 +1,113 @@
+// Libraries
+import { describe, beforeEach, afterEach, vi, test, expect } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+
+import { mount as mountComponent } from '@vue/test-utils'
+import ApiSelect from '../ApiSelect.vue'
+import flushPromises from 'flush-promises'
+import ApiWrapper from '@/components/form/api/ApiWrapper.vue'
+import { i18n } from '@/plugins'
+import merge from 'lodash-es/merge'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+import { waitForDebounce } from '@/test/util'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ApiSelect', () => {
+ let vuetify
+ let wrapper
+ let apiMock
+
+ const path = 'test-field/123'
+
+ const FIRST_OPTION = {
+ value: 1,
+ text: 'firstOption',
+ }
+ const SECOND_OPTION = {
+ value: '2',
+ text: 'secondOption',
+ }
+
+ const selectValues = [FIRST_OPTION, SECOND_OPTION]
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ wrapper.destroy()
+ })
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ApiSelect },
+ props: {
+ path: { type: String, default: path },
+ selectValues: { type: Array, default: () => selectValues },
+ },
+ template: `
+
+ `,
+ })
+ apiMock.get().thenReturn(ApiMock.success(FIRST_OPTION.value).forPath(path))
+ const defaultOptions = {
+ mocks: {
+ $tc: () => {},
+ api: apiMock.getMocks(),
+ },
+ }
+ return mountComponent(app, {
+ vuetify,
+ i18n,
+ attachTo: document.body,
+ ...merge(defaultOptions, options),
+ })
+ }
+
+ test('triggers api.patch and status update if input changes', async () => {
+ apiMock.patch().thenReturn(ApiMock.success(SECOND_OPTION.value))
+ wrapper = mount()
+
+ await flushPromises()
+
+ await wrapper.find('.v-input__slot').trigger('click')
+ await wrapper.findAll('[role="option"]').at(1).trigger('click')
+ await wrapper.find('input').trigger('submit')
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ expect(wrapper.findComponent(ApiWrapper).vm.localValue).toBe(SECOND_OPTION.value)
+ })
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ wrapper = mount()
+ apiMock.get().thenReturn(ApiMock.success(SECOND_OPTION.value).forPath(path))
+
+ wrapper.findComponent(ApiWrapper).vm.reload()
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(wrapper.findComponent(ApiWrapper).vm.localValue).toBe(SECOND_OPTION.value)
+ expect(wrapper.html()).toContain(SECOND_OPTION.text)
+ expect(wrapper.html()).not.toContain(FIRST_OPTION.text)
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiSwitch.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiSwitch.spec.js
new file mode 100644
index 0000000000..e399071663
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiSwitch.spec.js
@@ -0,0 +1,98 @@
+import { describe, beforeEach, afterEach, vi, test, expect } from 'vitest'
+import ApiSwitch from '../ApiSwitch.vue'
+import ApiWrapper from '@/components/form/api/ApiWrapper.vue'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+import flushPromises from 'flush-promises'
+import formBaseComponents from '@/plugins/formBaseComponents'
+import merge from 'lodash-es/merge'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+import { i18n } from '@/plugins'
+import { mount as mountComponent } from '@vue/test-utils'
+import { waitForDebounce } from '@/test/util'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ApiSwitch', () => {
+ let vuetify
+ let wrapper
+ let apiMock
+
+ const path = 'test-field/123'
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ wrapper.destroy()
+ })
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ApiSwitch },
+ props: {
+ path: { type: String, default: path },
+ },
+ template: `
+
+ `,
+ })
+ apiMock.get().thenReturn(ApiMock.success(true).forPath(path))
+ const defaultOptions = {
+ mocks: {
+ $tc: () => {},
+ api: apiMock.getMocks(),
+ },
+ }
+ return mountComponent(app, {
+ vuetify,
+ i18n,
+ attachTo: document.body,
+ ...merge(defaultOptions, options),
+ })
+ }
+
+ test('triggers api.patch and status update if input changes', async () => {
+ apiMock.patch().thenReturn(ApiMock.success(false))
+ wrapper = mount()
+
+ await flushPromises()
+
+ const input = wrapper.find('input')
+ await input.trigger('click')
+ await input.trigger('submit')
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ expect(wrapper.findComponent(ApiWrapper).vm.localValue).toBe(false)
+ })
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ wrapper = mount()
+ apiMock.get().thenReturn(ApiMock.success(false).forPath(path))
+
+ wrapper.findComponent(ApiWrapper).vm.reload()
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(wrapper.findComponent(ApiWrapper).vm.localValue).toBe(false)
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('false')
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiTextField.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiTextField.spec.js
new file mode 100644
index 0000000000..734dfba461
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiTextField.spec.js
@@ -0,0 +1,98 @@
+import { describe, beforeEach, afterEach, vi, test, expect } from 'vitest'
+import ApiTextField from '../ApiTextField.vue'
+import ApiWrapper from '@/components/form/api/ApiWrapper.vue'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+import flushPromises from 'flush-promises'
+import formBaseComponents from '@/plugins/formBaseComponents'
+import merge from 'lodash-es/merge'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+import { i18n } from '@/plugins'
+import { mount as mountComponent } from '@vue/test-utils'
+import { waitForDebounce } from '@/test/util'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ApiTextField', () => {
+ let vuetify
+ let wrapper
+ let apiMock
+
+ const path = 'test-field/123'
+ const TEXT_1 = 'some text'
+ const TEXT_2 = 'another text'
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ wrapper.destroy()
+ })
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ApiTextField },
+ props: {
+ path: { type: String, default: path },
+ },
+ template: ``,
+ })
+ apiMock.get().thenReturn(ApiMock.success(TEXT_1).forPath(path))
+ const defaultOptions = {
+ mocks: {
+ $tc: () => {},
+ api: apiMock.getMocks(),
+ },
+ }
+ return mountComponent(app, {
+ vuetify,
+ i18n,
+ attachTo: document.body,
+ ...merge(defaultOptions, options),
+ })
+ }
+
+ describe('text', () => {
+ test('triggers api.patch and status update if input changes', async () => {
+ apiMock.patch().thenReturn(ApiMock.success(TEXT_2))
+ wrapper = mount()
+
+ await flushPromises()
+
+ const input = wrapper.find('input')
+ await input.setValue(TEXT_2)
+ await input.trigger('submit')
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ expect(wrapper.findComponent(ApiWrapper).vm.localValue).toBe(TEXT_2)
+ })
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ wrapper = mount()
+ apiMock.get().thenReturn(ApiMock.success(TEXT_2).forPath(path))
+
+ wrapper.findComponent(ApiWrapper).vm.reload()
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(wrapper.findComponent(ApiWrapper).vm.localValue).toBe(TEXT_2)
+ expect(wrapper.find('input[type=text]').element.value).toBe(TEXT_2)
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiTextarea.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiTextarea.spec.js
new file mode 100644
index 0000000000..c4bf3dfd20
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiTextarea.spec.js
@@ -0,0 +1,85 @@
+import { describe, beforeEach, afterEach, vi, test, expect } from 'vitest'
+import ApiTextarea from '@/components/form/api/ApiTextarea.vue'
+import ApiWrapper from '@/components/form/api/ApiWrapper.vue'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+import flushPromises from 'flush-promises'
+import formBaseComponents from '@/plugins/formBaseComponents'
+import merge from 'lodash-es/merge'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+import { i18n } from '@/plugins'
+import { mount as mountComponent } from '@vue/test-utils'
+import { waitForDebounce } from '@/test/util'
+import { mockEventClass } from '@/test/mockEventClass'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+mockEventClass('ClipboardEvent')
+mockEventClass('DragEvent')
+
+describe('An ApiTextarea', () => {
+ let vuetify
+ let wrapper
+ let apiMock
+
+ const path = 'test-field/123'
+ const TEXT_1 = 'some text'
+ const TEXT_2 = 'another text'
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ wrapper.destroy()
+ })
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ApiTextarea },
+ props: {
+ path: { type: String, default: path },
+ },
+ template: `
+ `,
+ })
+ apiMock.get().thenReturn(ApiMock.success(TEXT_1).forPath(path))
+ const defaultOptions = {
+ mocks: {
+ $tc: () => {},
+ api: apiMock.getMocks(),
+ },
+ }
+ return mountComponent(app, {
+ vuetify,
+ i18n,
+ attachTo: document.body,
+ ...merge(defaultOptions, options),
+ })
+ }
+
+ test('updates state if value in store is refreshed and has new value', async () => {
+ wrapper = mount()
+ apiMock.get().thenReturn(ApiMock.success(TEXT_2).forPath(path))
+
+ wrapper.findComponent(ApiWrapper).vm.reload()
+
+ await waitForDebounce()
+ await flushPromises()
+
+ expect(wrapper.find('div.e-form-container').element.getAttribute('value')).toBe(
+ TEXT_2
+ )
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiTimePicker.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiTimePicker.spec.js
new file mode 100644
index 0000000000..463ba9b04f
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiTimePicker.spec.js
@@ -0,0 +1,89 @@
+import { describe, beforeEach, afterEach, vi, expect, it } from 'vitest'
+import ApiTimePicker from '../ApiTimePicker.vue'
+import { screen, waitFor } from '@testing-library/vue'
+import { render, setTestLocale } from '@/test/renderWithVuetify.js'
+import user from '@testing-library/user-event'
+import { ApiMock } from '@/components/form/api/__tests__/ApiMock'
+
+describe('An ApiTimePicker', () => {
+ let apiMock
+
+ const FIELD_PATH = 'test-field/123'
+ const FIELD_LABEL = 'Test field'
+ const TIME_1 = '2037-07-18T09:52:00+00:00'
+ const TIME_2 = '2037-07-18T00:52:00+00:00'
+ const PICKER_BUTTON_LABEL_TEXT = 'Dialog öffnen, um eine Zeit für Test field zu wählen'
+
+ beforeEach(() => {
+ setTestLocale('de')
+ apiMock = ApiMock.create()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ it('triggers api.patch and status update if input changes', async () => {
+ // given
+ apiMock.get().thenReturn(ApiMock.success(TIME_1).forPath(FIELD_PATH))
+ apiMock.patch().thenReturn(ApiMock.success(TIME_2))
+ render(ApiTimePicker, {
+ props: {
+ autoSave: false,
+ path: FIELD_PATH,
+ uri: 'test-field/123',
+ label: FIELD_LABEL,
+ required: true,
+ },
+ mocks: {
+ api: apiMock.getMocks(),
+ },
+ })
+
+ // when
+ // click the button to open the picker
+ await user.click(screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT))
+ // Click the 0th hour. We can only click this one, because
+ // testing library is missing the vuetify styles, and all the
+ // number elements overlap
+ await user.click(await screen.findByText('0'))
+ // click the save button
+ await user.click(screen.getByLabelText('Speichern'))
+
+ // then
+ await waitFor(async () => {
+ const inputField = await screen.findByLabelText(FIELD_LABEL)
+ expect(inputField.value).toBe('00:52')
+ expect(apiMock.getMocks().patch).toBeCalledTimes(1)
+ })
+ })
+
+ it('updates state if value in store is refreshed and has new value', async () => {
+ // given
+ apiMock.get().thenReturn(ApiMock.networkError().forPath(FIELD_PATH))
+ render(ApiTimePicker, {
+ props: {
+ autoSave: false,
+ path: FIELD_PATH,
+ uri: 'test-field/123',
+ label: FIELD_LABEL,
+ required: true,
+ },
+ mocks: {
+ api: apiMock.getMocks(),
+ },
+ })
+ await screen.findByText('A network error occurred.')
+ expect((await screen.findByLabelText(FIELD_LABEL)).value).not.toBe('09:52')
+ const retryButton = await screen.findByText('Erneut versuchen')
+ apiMock.get().thenReturn(ApiMock.success(TIME_1).forPath(FIELD_PATH))
+
+ // when
+ await user.click(retryButton)
+
+ // then
+ await waitFor(async () => {
+ expect((await screen.findByLabelText(FIELD_LABEL)).value).toBe('09:52')
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/form/api/__tests__/ApiWrapper.spec.js b/frontend-vue3/src/components/form/api/__tests__/ApiWrapper.spec.js
new file mode 100644
index 0000000000..05304c5cdd
--- /dev/null
+++ b/frontend-vue3/src/components/form/api/__tests__/ApiWrapper.spec.js
@@ -0,0 +1,552 @@
+import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+import flushPromises from 'flush-promises'
+import { createLocalVue, shallowMount } from '@vue/test-utils'
+import veeValidatePlugin from '@/plugins/veeValidate'
+import ApiWrapper from '../ApiWrapper.vue'
+import { VBtn, VForm } from 'vuetify/components'
+import { ValidationObserver } from 'vee-validate'
+
+const { cloneDeep } = await vi.importActual('lodash-es')
+
+Vue.use(Vuetify)
+Vue.use(veeValidatePlugin)
+let vuetify
+
+let debounce
+const resolveDebounce = () => debounce()
+
+vi.mock('lodash-es', async (importOriginal) => {
+ const lodash = await importOriginal()
+ return {
+ ...lodash,
+ debounce: (callback) =>
+ function () {
+ return new Promise((resolve) => (debounce = resolve)).then(callback)
+ },
+ set: lodash.set,
+ get: lodash.get,
+ }
+})
+
+let patch
+const resolvePatch = (value) => patch(value)
+
+function resetPromises() {
+ patch = undefined
+}
+
+// config factory
+function createConfig(overrides) {
+ const mocks = {
+ api: {
+ patch: () => new Promise((resolve) => (patch = resolve)),
+ get: () => new Promise(),
+ },
+ }
+
+ const propsData = {
+ value: 'Test Value',
+ path: 'testField',
+ uri: '/testEntity/123',
+ label: 'Test Field',
+ }
+
+ const stubs = {
+ VForm,
+ VBtn,
+ ValidationObserver,
+ }
+
+ const scopedSlots = {
+ default:
+ ' ',
+ }
+
+ const localVue = createLocalVue()
+
+ return cloneDeep(
+ Object.assign({ mocks, propsData, vuetify, stubs, scopedSlots, localVue }, overrides)
+ )
+}
+
+beforeEach(() => {
+ resetPromises()
+ vi.useFakeTimers()
+})
+
+afterEach(() => {
+ vi.useRealTimers()
+})
+
+/**
+ * AutoSave = true
+ * External value
+ */
+describe('Testing ApiWrapper [autoSave=true; manual external value]', () => {
+ let wrapper
+ let vm
+ let config
+ let apiPatch
+ let validateResolveFunction
+ let validateCalled
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+
+ config = createConfig()
+ wrapper = shallowMount(ApiWrapper, config)
+ vm = wrapper.vm
+
+ apiPatch = vi.spyOn(config.mocks.api, 'patch')
+
+ validateCalled = new Promise((resolve) => (validateResolveFunction = resolve))
+
+ // mock validation Promise
+ const validate = vi.spyOn(vm.$refs.validationObserver, 'validate')
+ validate.mockImplementation(() => {
+ validateResolveFunction()
+ return true
+ })
+ })
+
+ afterEach(() => {
+ wrapper?.destroy()
+ vi.resetAllMocks()
+ })
+
+ test('init correctly with default values', () => {
+ expect(vm.value).toBe(config.propsData.value)
+ expect(vm.dirty).toBe(false)
+ expect(vm.isSaving).toBe(false)
+ expect(vm.isLoading).toBe(false)
+ expect(vm.status).toBe('init')
+ expect(vm.autoSave).toBe(true)
+
+ // no buttons expected in AutoSave Mode (which is default)
+ expect(wrapper.findAllComponents({ name: 'VBtn' })).toHaveLength(0)
+ })
+
+ test('calls api.patch after onInput was triggered', async () => {
+ const newValue = 'new value'
+ const newValueFromApi = 'new value'
+
+ await vm.onInput(newValue)
+
+ // value (from outside) is still the same
+ expect(vm.value).toBe(config.propsData.value)
+
+ // local Value has changed and is dirty
+ expect(vm.dirty).toBe(true)
+ expect(vm.localValue).toBe(newValue)
+
+ resolveDebounce()
+ await flushPromises()
+
+ await validateCalled
+
+ // saving started
+ expect(vm.isSaving).toBe(true)
+ expect(vm.dirty).toBe(true)
+ expect(vm.status).toBe('saving')
+
+ // API patch method called
+ expect(apiPatch).toBeCalledTimes(1)
+ expect(apiPatch).toBeCalledWith(config.propsData.uri, {
+ [config.propsData.path]: newValue,
+ })
+
+ resolvePatch({})
+
+ // feedback changed return value from API & make sure it's taken over to localValue
+ await wrapper.setProps({ value: newValueFromApi })
+ await wrapper.vm.$nextTick()
+ expect(vm.localValue).toBe(newValueFromApi)
+ expect(vm.dirty).toBe(false)
+
+ // success state
+ expect(vm.status).toBe('success')
+
+ // wait for success icon timer to finish
+ await vi.advanceTimersByTime(2000)
+ await flushPromises()
+
+ // again in init state
+ expect(vm.status).toBe('init')
+ })
+
+ test('avoid double triggering of save for enter key', async () => {
+ // given
+ const input = wrapper.find('input')
+
+ // when
+ await vm.onInput('new value')
+ await input.trigger('submit') // trigger submit event (simulates enter key)
+
+ resolveDebounce()
+ await flushPromises()
+
+ resolvePatch()
+
+ // then
+ expect(apiPatch).toHaveBeenCalledTimes(1)
+ })
+
+ test('shows server error if api.patch failed', async () => {
+ // given
+ apiPatch.mockRejectedValueOnce(new Error('server error'))
+
+ // when
+ await vm.onInput('new value') // Trigger patch
+
+ resolveDebounce()
+ await flushPromises()
+
+ // then
+ expect(vm.hasServerError).toBe(true)
+ expect(vm.errorMessages).toContain('server error')
+ })
+
+ test('can process server validation error', async () => {
+ const validationMsg = 'The input is less than 10 characters long'
+ apiPatch.mockRejectedValueOnce(new Error(validationMsg))
+
+ // when
+ await vm.onInput('new value') // Trigger patch
+
+ resolveDebounce()
+ await flushPromises()
+
+ // then
+ expect(vm.hasServerError).toBe(true)
+ expect(vm.errorMessages).toContain(validationMsg)
+ })
+
+ /*
+ test('shows error if `required` validation fails', async () => {
+ // given
+ wrapper.setProps({ required: true })
+
+ // when
+ await vm.onInput('')
+
+ // then
+ expect(vm.hasValidationError).toBe(true)
+ expect(vm.errorMessages[0]).toMatch('is required')
+ }) */
+
+ /*
+ test('shows error if arbitrary validation fails & aborts save', async () => {
+ // given
+ wrapper.setProps({ validation: 'min:3|myOwnValidationRule' })
+ validate.mockResolvedValue({ valid: false, errors: ['Validation failed'] })
+
+ // when
+ await vm.onInput('any value')
+
+ // then
+ expect(validate).toHaveBeenCalledWith('any value', 'min:3|myOwnValidationRule', { name: 'Test Field' })
+ expect(vm.hasValidationError).toBe(true)
+ expect(vm.errorMessages[0]).toMatch('Validation failed')
+
+ // when
+ vm.save()
+
+ // then
+ expect(apiPatch).not.toHaveBeenCalled()
+ })
+
+ test('clears error if arbitrary validation succedes', async () => {
+ // given
+ wrapper.setProps({ validation: 'required' })
+ wrapper.vm.hasValidationError = true
+ validate.mockResolvedValue({ valid: true, errors: [] })
+
+ // when
+ await vm.onInput('any value')
+
+ // then
+ expect(vm.hasValidationError).toBe(false)
+ expect(vm.errorMessages).toHaveLength(0)
+ }) */
+})
+
+/**
+ * AutoSave = true
+ * Value from API
+ */
+describe('Testing ApiWrapper [autoSave=true; value from API]', () => {
+ let wrapper
+ let vm
+ let config
+ // let apiPatch
+ let apiGet
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+
+ config = createConfig()
+ delete config.propsData.value
+
+ apiGet = vi.spyOn(config.mocks.api, 'get')
+
+ apiGet.mockReturnValue({
+ [config.propsData.path]: 'api value',
+ _meta: {
+ load: Promise.resolve(),
+ },
+ })
+ })
+
+ afterEach(() => {
+ wrapper?.destroy()
+ })
+
+ test('loads value from API (path = primitive value)', async () => {
+ // given
+ const loadingValue = () => ({})
+ loadingValue.loading = true
+ apiGet.mockReturnValue({
+ [config.propsData.path]: loadingValue,
+ _meta: {
+ loading: true,
+ load: Promise.resolve(),
+ },
+ })
+
+ // when
+ wrapper = shallowMount(ApiWrapper, config)
+ vm = wrapper.vm
+
+ // then
+ expect(vm.isLoading).toBe(true)
+ expect(vm.localValue).toBe(null)
+
+ // given
+ apiGet.mockReturnValue({
+ [config.propsData.path]: 'api value',
+ _meta: {
+ load: Promise.resolve(),
+ },
+ })
+
+ // when
+ await flushPromises() // wait for load promise to resolve
+
+ // then
+ expect(vm.hasFinishedLoading).toBe(true)
+ expect(vm.isLoading).toBe(false)
+ expect(vm.localValue).toBe('api value')
+ })
+
+ test('shows error when loading value from API fails', async () => {
+ // given
+ const loadingValue = () => ({})
+ loadingValue._meta = { loading: true }
+ apiGet.mockReturnValue({
+ [config.propsData.path]: loadingValue,
+ _meta: {
+ load: Promise.reject(new Error('loading error')),
+ loading: true,
+ },
+ })
+ wrapper = shallowMount(ApiWrapper, config)
+ vm = wrapper.vm
+
+ // when
+ await flushPromises() // wait for load promise to resolve
+
+ // then
+ expect(vm.hasFinishedLoading).toBe(false)
+ expect(vm.isLoading).toBe(false)
+ expect(vm.hasLoadingError).toBe(true)
+ expect(vm.errorMessages[0]).toMatch('loading error')
+ })
+
+ test('loads IRI from API (path = embedded entity)', async () => {
+ // given
+ const loadingValue = () => ({})
+ loadingValue._meta = { loading: true }
+ apiGet.mockReturnValue({
+ [config.propsData.path]: loadingValue,
+ _meta: {
+ load: Promise.resolve(),
+ loading: true,
+ },
+ })
+
+ wrapper = shallowMount(ApiWrapper, config)
+ vm = wrapper.vm
+
+ apiGet.mockReturnValue({
+ [config.propsData.path]: () => ({
+ _meta: {
+ self: '/iri/5',
+ },
+ }),
+ _meta: {
+ load: Promise.resolve(),
+ },
+ })
+
+ // when
+ await flushPromises() // wait for load promise to resolve
+
+ // then
+ expect(vm.hasFinishedLoading).toBe(true)
+ expect(vm.isLoading).toBe(false)
+ expect(vm.localValue).toBe('/iri/5')
+ })
+
+ test('loads array of IRIs from API (path = embedded collection)', async () => {
+ // given
+ const loadingValue = () => ({})
+ loadingValue._meta = { loading: true }
+ apiGet.mockReturnValue({
+ [config.propsData.path]: loadingValue,
+ _meta: {
+ load: Promise.resolve(),
+ loading: true,
+ },
+ })
+
+ wrapper = shallowMount(ApiWrapper, config)
+ vm = wrapper.vm
+
+ apiGet.mockReturnValue({
+ [config.propsData.path]: () => ({
+ items: [
+ {
+ _meta: {
+ self: '/iri/5',
+ },
+ },
+ {
+ _meta: {
+ self: '/iri/6',
+ },
+ },
+ ],
+ }),
+ _meta: {
+ load: Promise.resolve(),
+ },
+ })
+
+ // when
+ await flushPromises() // wait for load promise to resolve
+
+ // then
+ expect(vm.hasFinishedLoading).toBe(true)
+ expect(vm.isLoading).toBe(false)
+ expect(vm.localValue).toStrictEqual(['/iri/5', '/iri/6'])
+ })
+})
+
+/**
+ * Manual mode
+ */
+describe('Testing ApiWrapper [autoSave=false]', () => {
+ let wrapper
+ let vm
+ let config
+ let apiPatch
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+
+ config = createConfig()
+ config.propsData.autoSave = false
+
+ wrapper = shallowMount(ApiWrapper, config)
+ vm = wrapper.vm
+
+ apiPatch = vi.spyOn(config.mocks.api, 'patch')
+ })
+
+ afterEach(() => {
+ wrapper?.destroy()
+ })
+
+ test('init correctly with default values', () => {
+ expect(vm.value).toBe(config.propsData.value)
+ expect(vm.dirty).toBe(false)
+ expect(vm.isSaving).toBe(false)
+ expect(vm.status).toBe('init')
+ expect(vm.autoSave).toBe(false)
+ })
+
+ test('clears dirty flag when local value matches external value', async () => {
+ // local change
+ await vm.onInput('new local value')
+ expect(vm.dirty).toBe(true)
+
+ // new value from external --> local value will not be changed
+ await wrapper.setProps({ value: 'new external value #1' })
+ expect(vm.localValue).toBe('new local value')
+
+ // local change to same value as external value
+ await vm.onInput('new external value #1')
+ await vm.$nextTick() // needed for watcher to trigger
+ expect(vm.dirty).toBe(false)
+
+ // new value from external --> local value will be changed
+ await wrapper.setProps({ value: 'new external value #2' })
+ await vm.$nextTick() // needed for watcher to trigger
+ expect(vm.localValue).toBe('new external value #2')
+ })
+
+ test('resets value and errors when `reset` is called', async () => {
+ // when
+ await vm.onInput('new local value')
+ // vm.hasValidationError = true
+
+ // then
+ expect(vm.dirty).toBe(true)
+ expect(vm.localValue).toBe('new local value')
+
+ // when
+ await vm.reset()
+
+ // then
+ expect(vm.dirty).toBe(false)
+ expect(vm.localValue).toBe('Test Value')
+ // expect(vm.hasValidationError).toBe(false)
+ })
+
+ test('trigger save with enter key', async () => {
+ // given
+ const input = wrapper.find('input')
+
+ // when
+ await input.trigger('submit')
+ await vm.$nextTick()
+ await flushPromises() // resolve validation
+
+ // then
+ expect(apiPatch).toHaveBeenCalled()
+ })
+
+ test('abort save in readonly mode', async () => {
+ // given
+ await wrapper.setProps({ readonly: true })
+
+ // when
+ await vm.save()
+
+ // then
+ expect(apiPatch).not.toHaveBeenCalled()
+ })
+
+ test('abort save in disabled mode', async () => {
+ // given
+ await wrapper.setProps({ disabled: true })
+
+ // when
+ await vm.save()
+
+ // then
+ expect(apiPatch).not.toHaveBeenCalled()
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/BaseComponent.vue b/frontend-vue3/src/components/form/base/BaseComponent.vue
new file mode 100644
index 0000000000..f553928038
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/BaseComponent.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/BasePicker.vue b/frontend-vue3/src/components/form/base/BasePicker.vue
new file mode 100644
index 0000000000..81b32a9a49
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/BasePicker.vue
@@ -0,0 +1,239 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ColorPicker/ColorSwatch.vue b/frontend-vue3/src/components/form/base/ColorPicker/ColorSwatch.vue
new file mode 100644
index 0000000000..6959e6245d
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ColorPicker/ColorSwatch.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ECheckbox.vue b/frontend-vue3/src/components/form/base/ECheckbox.vue
new file mode 100644
index 0000000000..ae55480949
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ECheckbox.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/EColorField.vue b/frontend-vue3/src/components/form/base/EColorField.vue
new file mode 100644
index 0000000000..de4d002860
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/EColorField.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/EColorPicker.vue b/frontend-vue3/src/components/form/base/EColorPicker.vue
new file mode 100644
index 0000000000..77028223b9
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/EColorPicker.vue
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/EDatePicker.vue b/frontend-vue3/src/components/form/base/EDatePicker.vue
new file mode 100644
index 0000000000..7f6d2a0b6f
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/EDatePicker.vue
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+ {{ $t('global.button.close') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/EForm.vue b/frontend-vue3/src/components/form/base/EForm.vue
new file mode 100644
index 0000000000..aafabf12a0
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/EForm.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ENumberField.vue b/frontend-vue3/src/components/form/base/ENumberField.vue
new file mode 100644
index 0000000000..076a98507a
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ENumberField.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/EParseField.vue b/frontend-vue3/src/components/form/base/EParseField.vue
new file mode 100644
index 0000000000..cca78d79d8
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/EParseField.vue
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ERichtext.vue b/frontend-vue3/src/components/form/base/ERichtext.vue
new file mode 100644
index 0000000000..5682b9490f
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ERichtext.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ESelect.vue b/frontend-vue3/src/components/form/base/ESelect.vue
new file mode 100644
index 0000000000..7df36bdac3
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ESelect.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ESwitch.vue b/frontend-vue3/src/components/form/base/ESwitch.vue
new file mode 100644
index 0000000000..480bfa8f20
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ESwitch.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ETextField.vue b/frontend-vue3/src/components/form/base/ETextField.vue
new file mode 100644
index 0000000000..b6ccd53bd1
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ETextField.vue
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ETextarea.vue b/frontend-vue3/src/components/form/base/ETextarea.vue
new file mode 100644
index 0000000000..a99d8c67e3
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ETextarea.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ETimeDropdown.vue b/frontend-vue3/src/components/form/base/ETimeDropdown.vue
new file mode 100644
index 0000000000..64ac1e092c
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ETimeDropdown.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+ {{ label }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ETimeField.vue b/frontend-vue3/src/components/form/base/ETimeField.vue
new file mode 100644
index 0000000000..b06c1c64f4
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ETimeField.vue
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/ETimePicker.vue b/frontend-vue3/src/components/form/base/ETimePicker.vue
new file mode 100644
index 0000000000..2c3ab07bbb
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/ETimePicker.vue
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
+
+ {{ $t('global.button.close') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/base/__tests__/ECheckbox.spec.js b/frontend-vue3/src/components/form/base/__tests__/ECheckbox.spec.js
new file mode 100644
index 0000000000..da599827dd
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/ECheckbox.spec.js
@@ -0,0 +1,101 @@
+import { describe, beforeEach, vi, test, expect } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+
+import { mount as mountComponent } from '@vue/test-utils'
+import ECheckbox from '../ECheckbox.vue'
+import { screen } from '@testing-library/vue'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ECheckbox', () => {
+ let vuetify
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ECheckbox },
+ data: function () {
+ return {
+ data: null,
+ }
+ },
+ template: `
+
+
+ ${options?.children}
+
+
+ `,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+ test('looks like a checkbox', async () => {
+ const wrapper = mount()
+ await wrapper.setData({ data: false })
+ expect(wrapper).toMatchSnapshot('unchecked')
+
+ await wrapper.setData({ data: true })
+ expect(wrapper).toMatchSnapshot('checked')
+ })
+
+ test('is checked when initialized checked', () => {
+ const wrapper = mount({
+ data: function () {
+ return {
+ data: true,
+ }
+ },
+ })
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('true')
+ })
+
+ test('updates checkbox when vModel changes', async () => {
+ const wrapper = mount()
+ await wrapper.setData({ data: false })
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('false')
+
+ await wrapper.setData({ data: true })
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('true')
+
+ await wrapper.setData({ data: false })
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('false')
+ })
+
+ test('updates vModel when user clicks on checkbox', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+
+ await input.trigger('click')
+ expect(wrapper.vm.data).toBe(true)
+
+ vi.resetAllMocks()
+ await input.trigger('click')
+ expect(wrapper.vm.data).toBe(false)
+ })
+
+ test('allows to use the append slot', async () => {
+ mount({
+ children: `
+
+ append
+
+ `,
+ })
+
+ expect(await screen.findByText('append')).toBeVisible()
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/EColorField.spec.js b/frontend-vue3/src/components/form/base/__tests__/EColorField.spec.js
new file mode 100644
index 0000000000..0161d8591b
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/EColorField.spec.js
@@ -0,0 +1,90 @@
+import { describe, beforeEach, test, expect } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+
+import EColorField from '@/components/form/base/EColorField.vue'
+import { mount as mountComponent } from '@vue/test-utils'
+import { ColorSpace, sRGB } from 'colorjs.io/fn'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+ColorSpace.register(sRGB)
+
+describe('An EColorField', () => {
+ let vuetify
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { EColorField },
+ data: function () {
+ return {
+ data: null,
+ }
+ },
+ methods: {
+ parse: (value) => {
+ return value === 'true' ? true : value === 'false' ? false : null
+ },
+ format: (value) => {
+ return value === null ? '' : `${value}`
+ },
+ },
+ template: `
`,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+
+ test('looks like a textfield', async () => {
+ const wrapper = mount()
+ expect(wrapper).toMatchSnapshot('empty')
+
+ await wrapper.setData({ data: '#FF0000' })
+ expect(wrapper).toMatchSnapshot('with text')
+ })
+
+ test('updates text when vModel changes', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input').element
+ expect(input.value).toBeDefined()
+
+ const firstValue = '#A1E1E1'
+ await wrapper.setData({ data: firstValue })
+ expect(input.value).toBe(`${firstValue}`)
+
+ const secondValue = '#FF00FF'
+ await wrapper.setData({ data: secondValue })
+ expect(input.value).toBe(`${secondValue}`)
+ })
+
+ test('updates vModel when value of input field changes', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+ const value = '#123456'
+
+ input.element.value = `${value}`
+ await input.trigger('input')
+
+ expect(wrapper.vm.data).toBe(value)
+ })
+
+ test.each([
+ ['#00FF00', '#00FF00'],
+ ['red', '#FF0000'],
+ ['', null],
+ ])('parses "%s" as "%s"', async (string, expected) => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+
+ input.element.value = `${string}`
+ await input.trigger('input')
+
+ expect(wrapper.vm.data).toBe(expected)
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/EColorPicker.spec.js b/frontend-vue3/src/components/form/base/__tests__/EColorPicker.spec.js
new file mode 100644
index 0000000000..d3a4694341
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/EColorPicker.spec.js
@@ -0,0 +1,252 @@
+import { describe, beforeEach, expect, it } from 'vitest'
+import { fireEvent, screen, waitFor } from '@testing-library/vue'
+import { render, setTestLocale, snapshotOf } from '@/test/renderWithVuetify.js'
+import user from '@testing-library/user-event'
+import EColorPicker from '../EColorPicker.vue'
+
+import { regex } from 'vee-validate/dist/rules'
+import { extend } from 'vee-validate'
+import { ColorSpace, sRGB } from 'colorjs.io/fn'
+
+extend('regex', regex)
+
+ColorSpace.register(sRGB)
+describe('An EColorPicker', () => {
+ const COLOR1 = '#FF0000'
+ const COLOR2 = '#FF00FF'
+ const COLOR3 = '#FAFFAF'
+ const INVALID_COLOR = 'some new color'
+ const PICKER_BUTTON_LABEL_TEXT = 'Dialog öffnen, um eine Farbe für test zu wählen'
+ const VALIDATION_MESSAGE = 'Bitte gültige Farbe eingeben.'
+
+ beforeEach(() => {
+ setTestLocale('de')
+ })
+
+ it('renders the component', async () => {
+ // given
+
+ // when
+ render(EColorPicker, {
+ props: {
+ value: COLOR1,
+ label: 'test',
+ },
+ })
+
+ // then
+ await screen.findByDisplayValue(COLOR1)
+ screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT)
+ })
+
+ it('looks like a color picker', async () => {
+ // given
+
+ // when
+ const { container } = render(EColorPicker, {
+ props: { value: COLOR1, label: 'test' },
+ })
+
+ // then
+ expect(snapshotOf(container)).toMatchSnapshot('pickerclosed')
+
+ // when
+ await user.click(screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT))
+
+ // then
+ await screen.findByTestId('colorpicker')
+ expect(snapshotOf(container)).toMatchSnapshot('pickeropen')
+ })
+
+ it('opens the picker when the text field is clicked', async () => {
+ // given
+ render(EColorPicker, {
+ props: { value: COLOR1, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(COLOR1)
+
+ // when
+ await user.click(inputField)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.findByTestId('colorpicker')).toBeVisible()
+ })
+ })
+
+ it('opens the picker when the icon button is clicked', async () => {
+ // given
+ render(EColorPicker, {
+ props: { value: COLOR1, label: 'test' },
+ })
+ const button = await screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT)
+
+ // when
+ await user.click(button)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.findByTestId('colorpicker')).toBeVisible()
+ })
+ })
+
+ it('closes the picker when clicking outside', async () => {
+ // given
+ render(EColorPicker, {
+ props: { value: COLOR1, label: 'test' },
+ })
+ const button = await screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByTestId('colorpicker')).toBeVisible()
+ })
+
+ // when
+ await user.click(document.body)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByTestId('colorpicker')).not.toBeVisible()
+ })
+ })
+
+ it('closes the picker when pressing escape', async () => {
+ // given
+ render(EColorPicker, {
+ props: { value: COLOR1, label: 'test' },
+ })
+ const button = await screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByTestId('colorpicker')).toBeVisible()
+ })
+
+ // when
+ await user.keyboard('{Escape}')
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByTestId('colorpicker')).not.toBeVisible()
+ })
+ })
+
+ it('does not close the picker when selecting a color', async () => {
+ // given
+ const { container } = render(EColorPicker, {
+ props: { value: COLOR1, label: 'test' },
+ })
+ const button = await screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByTestId('colorpicker')).toBeVisible()
+ })
+
+ // when
+ // click inside the color picker canvas to select a different color
+ const canvas = container.querySelector('canvas')
+ await user.click(canvas, { clientX: 10, clientY: 10 })
+
+ // then
+ // close button should stay visible
+ await expect(
+ waitFor(() => {
+ expect(screen.queryByTestId('colorpicker')).not.toBeVisible()
+ })
+ ).rejects.toThrow(/Received element is visible/)
+ })
+
+ it('updates v-model when the value changes', async () => {
+ // given
+ const { emitted } = render(EColorPicker, {
+ props: { value: COLOR1, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(COLOR1)
+
+ // when
+ await user.clear(inputField)
+ await user.keyboard(COLOR2)
+
+ // then
+ await waitFor(async () => {
+ const events = emitted().input
+ // some input events were fired
+ expect(events.length).toBeGreaterThan(0)
+ // the last one included the parsed version of our entered time
+ expect(events[events.length - 1]).toEqual([COLOR2])
+ })
+ // Our entered time should be visible...
+ screen.getByDisplayValue(COLOR2)
+ // ...and stay visible
+ await expect(
+ waitFor(() => {
+ expect(screen.getByDisplayValue(COLOR2)).not.toBeVisible()
+ })
+ ).rejects.toThrow(/Received element is visible/)
+ })
+
+ it('updates v-model when a new color is selected in the picker', async () => {
+ // given
+ const { emitted, container } = render(EColorPicker, {
+ props: { value: COLOR1, label: 'test' },
+ })
+ await screen.findByDisplayValue(COLOR1)
+ const button = await screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT)
+
+ // when
+ // click the button to open the picker
+ await user.click(button)
+ // click inside the color picker canvas to select a different color
+ const canvas = container.querySelector('canvas')
+ await user.click(canvas, { clientX: 10, clientY: 10 })
+ // click the close button
+ await user.click(screen.getByTestId('colorpicker'))
+
+ // then
+ await waitFor(async () => {
+ const events = emitted().input
+ // some input events were fired
+ expect(events.length).toBeGreaterThan(0)
+ // the last one included the parsed version of our entered time
+ expect(events[events.length - 1]).toEqual([COLOR3])
+ })
+ // Our entered time should be visible...
+ screen.getByDisplayValue(COLOR3)
+ // ...and stay visible
+ await expect(
+ waitFor(() => {
+ expect(screen.getByDisplayValue(COLOR3)).not.toBeVisible()
+ })
+ ).rejects.toThrow(/Received element is visible/)
+ })
+
+ it('validates the input', async () => {
+ // given
+ render(EColorPicker, {
+ props: { value: COLOR1, path: 'test', validationLabelOverride: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(COLOR1)
+
+ // when
+ await user.clear(inputField)
+ await user.keyboard(INVALID_COLOR)
+ await fireEvent.blur(inputField)
+
+ // then
+ await screen.findByText(VALIDATION_MESSAGE)
+ })
+
+ it('accepts null', async () => {
+ render(EColorPicker, {
+ props: { value: COLOR2, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(COLOR2)
+ expect(inputField).toHaveValue(COLOR2)
+ const button = await screen.getByLabelText(PICKER_BUTTON_LABEL_TEXT)
+ // click the button to open the picker
+ await user.click(button)
+
+ // when
+ await user.click(screen.getByTestId('colorpicker').querySelector('.reset'))
+ expect(inputField).toHaveValue('')
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/EDatePicker.spec.js b/frontend-vue3/src/components/form/base/__tests__/EDatePicker.spec.js
new file mode 100644
index 0000000000..ce842fc677
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/EDatePicker.spec.js
@@ -0,0 +1,406 @@
+import { describe, beforeEach, expect, it } from 'vitest'
+import { screen, waitFor } from '@testing-library/vue'
+import { render, setTestLocale, snapshotOf } from '@/test/renderWithVuetify.js'
+import user from '@testing-library/user-event'
+import EDatePicker from '../EDatePicker.vue'
+
+describe('An EDatePicker', () => {
+ const DATE1_ISO = '2020-03-01'
+ const DATE2_ISO = '2020-03-19'
+
+ const localeData = {
+ de: {
+ date1: '01.03.2020',
+ date2: '19.03.2020',
+ dateShort: '2.4.2021',
+ dateInWrongLocale: '03/19/2020',
+ labelText: 'Dialog öffnen, um ein Datum für test zu wählen',
+ date1Heading: 'März 2020',
+ date3Heading: 'Januar 2111',
+ date4Heading: 'Januar 1999',
+ closeButton: 'Schliessen',
+ validationMessage:
+ 'Ungültiges Format, bitte gib das Datum im Format DD.MM.YYYY ein',
+ },
+ en: {
+ date1: '03/01/2020',
+ date2: '03/19/2020',
+ dateShort: '4/2/2021',
+ dateInWrongLocale: '19.03.2020',
+ labelText: 'Open dialog to select a date for test',
+ date1Heading: 'March 2020',
+ date3Heading: 'January 2111',
+ date4Heading: 'January 1999',
+ closeButton: 'Close',
+ validationMessage: 'Invalid format, please enter the date in the format MM/DD/YYYY',
+ },
+ }
+
+ describe.each(Object.entries(localeData))('in locale %s', (locale, data) => {
+ beforeEach(() => {
+ setTestLocale(locale)
+ })
+
+ it('renders the component', async () => {
+ // given
+
+ // when
+ render(EDatePicker, { props: { value: DATE1_ISO, label: 'test' } })
+
+ // then
+ await screen.findByDisplayValue(data.date1)
+ screen.getByLabelText(data.labelText)
+ })
+
+ it('looks like a date picker', async () => {
+ // given
+
+ // when
+ const { container } = render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+
+ // then
+ expect(snapshotOf(container)).toMatchSnapshot('pickerclosed')
+
+ // when
+ await user.click(screen.getByLabelText(data.labelText))
+
+ // then
+ await screen.findByText(data.closeButton)
+ await screen.findByText(data.date1Heading)
+ expect(snapshotOf(container)).toMatchSnapshot('pickeropen')
+ })
+
+ it('does not open the picker when the text field is clicked', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(data.date1)
+
+ // when
+ await user.click(inputField)
+
+ // then
+ // menu should not appear
+ await expect(screen.findByText(data.date1Heading)).rejects.toThrow(
+ /Unable to find an element with the text/
+ )
+ })
+
+ it('opens the picker when the icon button is clicked', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ await user.click(button)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date1Heading)).toBeVisible()
+ })
+ })
+
+ it('closes the picker when clicking the close button', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date1Heading)).toBeVisible()
+ })
+ const closeButton = screen.getByText(data.closeButton)
+
+ // when
+ await user.click(closeButton)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByText(data.date1Heading)).not.toBeVisible()
+ })
+ })
+
+ it('closes the picker when clicking outside', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date1Heading)).toBeVisible()
+ })
+
+ // when
+ await user.click(document.body)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByText(data.date1Heading)).not.toBeVisible()
+ })
+ })
+
+ it('closes the picker when pressing escape', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date1Heading)).toBeVisible()
+ })
+
+ // when
+ await user.keyboard('{Escape}')
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByText(data.date1Heading)).not.toBeVisible()
+ })
+ })
+
+ it('closes the picker when selecting a date', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date1Heading)).toBeVisible()
+ })
+
+ // when
+ // click the 19th day of the month
+ await user.click(screen.getByText('19'))
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByText(data.date1Heading)).not.toBeVisible()
+ })
+ })
+
+ it('re-opens the picker when clicking the button again after selecting a date', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date1Heading)).toBeVisible()
+ })
+ // click the 19th day of the month
+ await user.click(screen.getByText('19'))
+ await waitFor(async () => {
+ expect(await screen.queryByText(data.date1Heading)).not.toBeVisible()
+ })
+
+ // when
+ await user.click(button)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date1Heading)).toBeVisible()
+ })
+ })
+
+ it('updates v-model when the input field is changed', async () => {
+ // given
+ const { emitted } = render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(data.date1)
+
+ // when
+ await user.clear(inputField)
+ await user.keyboard(data.date2)
+
+ // then
+ await waitFor(async () => {
+ const events = emitted().input
+ // some input events were fired
+ expect(events.length).toBeGreaterThan(0)
+ // the last one included the parsed version of our entered date
+ expect(events[events.length - 1]).toEqual([DATE2_ISO])
+ })
+ // Our entered date should be visible...
+ screen.getByDisplayValue(data.date2)
+ // ...and stay visible
+ await expect(
+ waitFor(() => {
+ expect(screen.getByDisplayValue(data.date2)).not.toBeVisible()
+ })
+ ).rejects.toThrow(/Received element is visible/)
+ })
+
+ it('updates v-model when a new date is selected in the picker', async () => {
+ // given
+ const { emitted } = render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ await screen.findByDisplayValue(data.date1)
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ // click the button to open the picker
+ await user.click(button)
+ // click the 19th day of the month
+ await user.click(screen.getByText('19'))
+
+ // then
+ await waitFor(async () => {
+ const events = emitted().input
+ // some input events were fired
+ expect(events.length).toBeGreaterThan(0)
+ // the last one included the parsed version of our entered date
+ expect(events[events.length - 1]).toEqual([DATE2_ISO])
+ })
+ // Our selected date should be visible...
+ screen.getByDisplayValue(data.date2)
+ // ...and stay visible
+ await expect(
+ waitFor(() => {
+ expect(screen.getByDisplayValue(data.date2)).not.toBeVisible()
+ })
+ ).rejects.toThrow(/Received element is visible/)
+ })
+
+ it('validates the input', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(data.date1)
+
+ // when
+ await user.clear(inputField)
+ await user.keyboard(data.dateInWrongLocale)
+
+ // then
+ await screen.findByText(data.validationMessage)
+ })
+
+ it('allows inputting a date in short format', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(data.date1)
+
+ // when
+ await user.clear(inputField)
+ await user.keyboard(data.dateShort)
+
+ // then
+ expect(screen.queryByText(data.validationMessage)).not.toBeInTheDocument()
+ // validation message should not appear
+ await expect(screen.findByText(data.validationMessage)).rejects.toThrow(
+ /Unable to find an element with the text/
+ )
+ })
+
+ it('autoscrolls forward to the earliest allowable month based on min', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: '', label: 'test', min: '2111-01-01' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ await user.click(button)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date3Heading)).toBeVisible()
+ })
+ })
+
+ it('does not autoscroll forward if given a value', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test', min: '2111-01-01' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ await user.click(button)
+
+ // then
+ await expect(async () => {
+ await screen.findByText(data.date3Heading)
+ }).rejects.toThrow(/Unable to find an element with the text/)
+ })
+
+ it('does not autoscroll backward based on min', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: '', label: 'test', min: '1999-01-01' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ await user.click(button)
+
+ // then
+ await expect(async () => {
+ await screen.findByText(data.date4Heading)
+ }).rejects.toThrow(/Unable to find an element with the text/)
+ })
+
+ it('autoscrolls back to the latest allowable month based on max', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: '', label: 'test', max: '1999-01-01' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ await user.click(button)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.findByText(data.date4Heading)).toBeVisible()
+ })
+ })
+
+ it('does not autoscroll forward based on max', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: '', label: 'test', max: '2111-01-01' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ await user.click(button)
+
+ // then
+ await expect(async () => {
+ await screen.findByText(data.date3Heading)
+ }).rejects.toThrow(/Unable to find an element with the text/)
+ })
+
+ it('does not autoscroll backward if given a value', async () => {
+ // given
+ render(EDatePicker, {
+ props: { value: DATE1_ISO, label: 'test', max: '1999-01-01' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ await user.click(button)
+
+ // then
+ await expect(async () => {
+ await screen.findByText(data.date4Heading)
+ }).rejects.toThrow(/Unable to find an element with the text/)
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/ENumberField.spec.js b/frontend-vue3/src/components/form/base/__tests__/ENumberField.spec.js
new file mode 100644
index 0000000000..6f2b3c720e
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/ENumberField.spec.js
@@ -0,0 +1,133 @@
+import { describe, beforeEach, test, expect } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+
+import { mount as mountComponent } from '@vue/test-utils'
+import ENumberField from '../ENumberField.vue'
+import { screen } from '@testing-library/vue'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ENumberField', () => {
+ let vuetify
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ENumberField },
+ data: function () {
+ return {
+ data: null,
+ }
+ },
+ template: `
+
+
+ ${options?.children}
+
+
+ `,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+
+ test('looks like a numberfield', async () => {
+ const wrapper = mount()
+ expect(wrapper).toMatchSnapshot('empty')
+
+ await wrapper.setData({ data: 3.14 })
+ expect(wrapper).toMatchSnapshot('with text')
+ })
+
+ test('updates text when vModel changes', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input').element
+ expect(input.value).toBeDefined()
+
+ const firstNumber = 0
+ await wrapper.setData({ data: firstNumber })
+ expect(input.value).toBe(`${firstNumber}`)
+
+ const secondNumber = 3.14
+ await wrapper.setData({ data: secondNumber })
+ expect(input.value).toBe(`${secondNumber}`)
+ })
+
+ test('updates vModel when value of input field changes', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+ const number = 3.14
+
+ input.element.value = `${number}`
+ await input.trigger('input')
+
+ expect(wrapper.vm.data).toBe(number)
+ })
+
+ test('updates vModel with null or valid numbers', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+
+ expect(wrapper.vm.data).toBeNull()
+
+ input.element.value = '.'
+ await input.trigger('input')
+ expect(wrapper.vm.data).toBeNull()
+
+ input.element.value = '.0'
+ await input.trigger('input')
+ expect(wrapper.vm.data).toBeNull()
+
+ input.element.value = '.01'
+ await input.trigger('input')
+ expect(wrapper.vm.data).toBe(0.01)
+ })
+
+ test.each([
+ ['1', 1],
+ ['1.', 1],
+ ['1..2', 1.2],
+ ['39.5.', 39.5],
+ ["2'000", 2000],
+ ['8.000.000,20', 8000000.2],
+ ['10e3', 103],
+ ['2kg', 2],
+ ['8,000.20', 8000.2],
+ ['abc123', 123],
+ ['Hello, World?', null],
+ ['eCamp. Super!', null],
+ ['+123..456..789', 123.456789],
+ ['-10', -10],
+ ['2-4 Stück', 24],
+ ['-0', -0],
+ ['.', null],
+ ['.a', null],
+ ['.a02', 0.02],
+ ])('parses "%s" as "%s"', async (string, expected) => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+
+ input.element.value = string
+ await input.trigger('input')
+
+ expect(wrapper.vm.data).toBe(expected)
+ })
+
+ test('allows to use the append slot', async () => {
+ mount({
+ children: `
+
+ append
+
+ `,
+ })
+
+ expect(await screen.findByText('append')).toBeVisible()
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/EParseField.spec.js b/frontend-vue3/src/components/form/base/__tests__/EParseField.spec.js
new file mode 100644
index 0000000000..34f09ba6c6
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/EParseField.spec.js
@@ -0,0 +1,109 @@
+import { describe, beforeEach, test, expect } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+
+import EParseField from '@/components/form/base/EParseField.vue'
+import { mount as mountComponent } from '@vue/test-utils'
+import { screen } from '@testing-library/vue'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An EParseField', () => {
+ let vuetify
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { EParseField },
+ data: function () {
+ return {
+ data: null,
+ }
+ },
+ methods: {
+ parse: (value) => {
+ return value === 'true' ? true : value === 'false' ? false : null
+ },
+ format: (value) => {
+ return value === null ? '' : `${value}`
+ },
+ },
+ template: `
+
+
+ ${options?.children}
+
+
+ `,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+
+ test('looks like a textfield', async () => {
+ const wrapper = mount()
+ expect(wrapper).toMatchSnapshot('empty')
+
+ await wrapper.setData({ data: true })
+ expect(wrapper).toMatchSnapshot('with text')
+ })
+
+ test('updates text when vModel changes', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input').element
+ expect(input.value).toBeDefined()
+
+ const firstValue = true
+ await wrapper.setData({ data: firstValue })
+ expect(input.value).toBe(`${firstValue}`)
+
+ const secondValue = false
+ await wrapper.setData({ data: secondValue })
+ expect(input.value).toBe(`${secondValue}`)
+ })
+
+ test('updates vModel when value of input field changes', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+ const value = true
+
+ input.element.value = `${value}`
+ await input.trigger('input')
+
+ expect(wrapper.vm.data).toBe(value)
+ })
+
+ test.each([
+ ['true', true],
+ ['false', false],
+ ['', null],
+ ['s', null],
+ ['0', null],
+ ['1', null],
+ ])('parses "%s" as "%s"', async (string, expected) => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+
+ input.element.value = `${string}`
+ await input.trigger('input')
+
+ expect(wrapper.vm.data).toBe(expected)
+ })
+
+ test('allows to use the append slot', async () => {
+ mount({
+ children: `
+
+ append
+
+ `,
+ })
+
+ expect(await screen.findByText('append')).toBeVisible()
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/ESelect.spec.js b/frontend-vue3/src/components/form/base/__tests__/ESelect.spec.js
new file mode 100644
index 0000000000..d44dd7375b
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/ESelect.spec.js
@@ -0,0 +1,140 @@
+import { describe, beforeEach, test, expect } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import { formBaseComponents } from '@/plugins'
+
+import { mount as mountComponent } from '@vue/test-utils'
+import ESelect from '../ESelect.vue'
+import { screen } from '@testing-library/vue'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ESelect', () => {
+ let vuetify
+
+ const FIRST_OPTION = {
+ value: 1,
+ text: 'firstOption',
+ }
+ const SECOND_OPTION = {
+ value: '2',
+ text: 'secondOption',
+ }
+ const THIRD_OPTION = {
+ value: { key: 'value', array: [1, 2, 3], nestedObject: { key: 'value' } },
+ text: 'thirdOption',
+ }
+ const selectValues = [FIRST_OPTION, SECOND_OPTION, THIRD_OPTION]
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ESelect },
+ data: function () {
+ return {
+ selectValues: selectValues,
+ data: null,
+ }
+ },
+ template: `
+
+
+ ${options?.children}
+
+
+ `,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+ test('looks like a dropdown', async () => {
+ const wrapper = mount()
+ expect(wrapper).toMatchSnapshot('no item selected')
+
+ await wrapper.find('.v-input__slot').trigger('click')
+ expect(wrapper).toMatchSnapshot('dropdown open')
+
+ await wrapper.findAll('[role="option"]').at(0).trigger('click')
+ expect(wrapper).toMatchSnapshot('dropdown closed with selected value')
+
+ await wrapper.find('.v-input__slot').trigger('click')
+ expect(wrapper).toMatchSnapshot('dropdown open with selected value')
+ })
+
+ test('update viewmodel with selected value', async () => {
+ const wrapper = mount()
+ expect(wrapper.vm.data).toBeNull()
+
+ await wrapper.find('.v-input__slot').trigger('click')
+ await wrapper.findAll('[role="option"]').at(0).trigger('click')
+ expect(wrapper.vm.data).toBe(FIRST_OPTION.value)
+
+ await wrapper.find('.v-input__slot').trigger('click')
+ await wrapper.findAll('[role="option"]').at(2).trigger('click')
+ expect(wrapper.vm.data).toBe(THIRD_OPTION.value)
+ })
+
+ test('update selected value with viewmodel', async () => {
+ const wrapper = mount()
+
+ await wrapper.setData({ data: SECOND_OPTION.value })
+ expect(wrapper.html()).toContain(SECOND_OPTION.text)
+ expect(wrapper.html()).not.toContain(FIRST_OPTION.text)
+
+ await wrapper.setData({ data: FIRST_OPTION.value })
+ expect(wrapper.html()).toContain(FIRST_OPTION.text)
+ expect(wrapper.html()).not.toContain(SECOND_OPTION.text)
+ })
+
+ test('update selected value after it was open', async () => {
+ const wrapper = mount()
+
+ await wrapper.find('.v-input__slot').trigger('click')
+ await wrapper.findAll('[role="option"]').at(0).trigger('click')
+ expect(wrapper.vm.data).toBe(FIRST_OPTION.value)
+
+ await wrapper.setData({ data: SECOND_OPTION.value })
+ expect(
+ wrapper.findAll('[role="option"]').at(1).element.getAttribute('aria-selected')
+ ).toBe('true')
+ expect(
+ wrapper.findAll('[role="option"]').at(0).element.getAttribute('aria-selected')
+ ).not.toBe('true')
+ })
+
+ test('allows to use the append slot', async () => {
+ mount({
+ children: `
+
+ append
+
+ `,
+ })
+
+ expect(await screen.findByText('append')).toBeVisible()
+ })
+
+ test('allows to use the append slot with scope', async () => {
+ const textText = 'myTestText'
+ const wrapper = mount({
+ children: `
+
+
+ {{ item }}
+
+
+ ${textText}
+
+
+ `,
+ })
+
+ await wrapper.find('.v-input__slot').trigger('click')
+
+ expect(await screen.findAllByText(textText)).toHaveLength(3)
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/ESwitch.spec.js b/frontend-vue3/src/components/form/base/__tests__/ESwitch.spec.js
new file mode 100644
index 0000000000..7ce1b90d9d
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/ESwitch.spec.js
@@ -0,0 +1,126 @@
+import { describe, beforeEach, vi, test, expect } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+
+import { mount as mountComponent } from '@vue/test-utils'
+import ESwitch from '@/components/form/base/ESwitch.vue'
+import { touch } from '@/test/util'
+import { screen } from '@testing-library/vue'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ESwitch', () => {
+ let vuetify
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ESwitch },
+ data: function () {
+ return {
+ data: null,
+ }
+ },
+ template: `
+
+
+ ${options?.children}
+
+
+ `,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+ test('looks like a switch', async () => {
+ const wrapper = mount()
+ await wrapper.setData({ data: false })
+ expect(wrapper).toMatchSnapshot('unchecked')
+
+ await wrapper.setData({ data: true })
+ expect(wrapper).toMatchSnapshot('checked')
+ })
+
+ test('is checked when initialized checked', () => {
+ const wrapper = mount({
+ data: function () {
+ return {
+ data: true,
+ }
+ },
+ })
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('true')
+ })
+
+ test('updates switch when vModel changes', async () => {
+ const wrapper = mount()
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('false')
+
+ await wrapper.setData({ data: true })
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('true')
+
+ await wrapper.setData({ data: false })
+ expect(
+ wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')
+ ).toBe('false')
+ })
+
+ test('updates vModel when user toggles with click', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+
+ await input.trigger('click')
+ expect(wrapper.vm.data).toBe(true)
+
+ await input.trigger('click')
+ expect(wrapper.vm.data).toBe(false)
+ })
+
+ test('updates vModel when user toggles with touch swipe', async () => {
+ const wrapper = mount()
+
+ touch(wrapper.find('.v-input--selection-controls__ripple')).start(0, 0).end(20, 0)
+ expect(wrapper.vm.data).toBe(true)
+
+ vi.resetAllMocks()
+ touch(wrapper.find('.v-input--selection-controls__ripple')).start(0, 0).end(-20, 0)
+ expect(wrapper.vm.data).toBe(false)
+ })
+
+ test('updates vModel when user toggles with keys', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+
+ input.trigger('keydown.right')
+ expect(wrapper.vm.data).toBe(true)
+
+ input.trigger('keydown.right')
+ expect(wrapper.vm.data).toBe(true)
+
+ vi.resetAllMocks()
+ input.trigger('keydown.left')
+ expect(wrapper.vm.data).toBe(false)
+ })
+
+ test('allows to use the append slot', async () => {
+ mount({
+ children: `
+
+ append
+
+ `,
+ })
+
+ expect(await screen.findByText('append')).toBeVisible()
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/ETextArea.spec.js b/frontend-vue3/src/components/form/base/__tests__/ETextArea.spec.js
new file mode 100644
index 0000000000..2f1944903a
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/ETextArea.spec.js
@@ -0,0 +1,93 @@
+import { describe, beforeEach, test, expect } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+
+import { mount as mountComponent } from '@vue/test-utils'
+import ETextarea from '../ETextarea.vue'
+import { mockEventClass } from '@/test/mockEventClass'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+mockEventClass('ClipboardEvent')
+mockEventClass('DragEvent')
+
+describe('An ETextArea', () => {
+ let vuetify
+
+ const multiLineText = `
+ Here comes a text
+ with new lines
+ and new lines with \n in them
+ and tags a
+ `
+
+ const mount = (
+ options,
+ template = `
+
+
+
+ `
+ ) => {
+ const app = Vue.component('App', {
+ components: { ETextarea },
+ data: () => ({ data: null }),
+ template: template,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+ test('looks like a textarea', async () => {
+ const wrapper = mount()
+ expect(wrapper).toMatchSnapshot('notext')
+
+ await wrapper.setData({ data: multiLineText })
+ expect(wrapper).toMatchSnapshot('withtext')
+
+ const mountWithMultiLine = mount(
+ { data: () => ({ data: multiLineText }) },
+ `
+
+
+
+ `
+ )
+ expect(mountWithMultiLine).toMatchSnapshot('multiline')
+
+ const mountAsinControls = mount(
+ { data: () => ({ data: multiLineText }) },
+ `
+
+
+
+ `
+ )
+ expect(mountAsinControls).toMatchSnapshot('mountAsInControls')
+ })
+
+ test('updates the text with the viewmodel', async () => {
+ const wrapper = mount()
+ await wrapper.setData({ data: multiLineText })
+ const textWithoutMultiLine = multiLineText
+ .replace(/\n\s*/g, ' ')
+ .replace(' ', ' ')
+ .replace('', '')
+ .replace(' ', '')
+ .trim()
+ expect(wrapper.find('.editor__content').text()).toBe(textWithoutMultiLine)
+ expect(wrapper.find('.e-form-container').element.getAttribute('value')).toBe(
+ multiLineText
+ )
+ expect(wrapper.vm.data).toBe(multiLineText)
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/ETextField.spec.js b/frontend-vue3/src/components/form/base/__tests__/ETextField.spec.js
new file mode 100644
index 0000000000..0e3c1e17bd
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/ETextField.spec.js
@@ -0,0 +1,86 @@
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+
+import { mount as mountComponent } from '@vue/test-utils'
+import ETextField from '../ETextField.vue'
+import { screen } from '@testing-library/vue'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+
+describe('An ETextField', () => {
+ let vuetify
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ETextField },
+ data: function () {
+ return {
+ data: null,
+ }
+ },
+ template: `
+
+
+ ${options?.children}
+
+
+ `,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+
+ test('looks like a textfield', async () => {
+ const wrapper = mount()
+ expect(wrapper).toMatchSnapshot('empty')
+
+ await wrapper.setData({ data: 'MyText' })
+ expect(wrapper).toMatchSnapshot('with text')
+ })
+
+ test('updates text when vModel changes', async () => {
+ const wrapper = mount()
+ expect(wrapper.find('.e-form-container').element.getAttribute('value')).toBeNull()
+
+ const firstText = 'myText'
+ await wrapper.setData({ data: firstText })
+ expect(wrapper.find('.e-form-container').element.getAttribute('value')).toBe(
+ firstText
+ )
+
+ const secondText = 'myText2'
+ await wrapper.setData({ data: secondText })
+ expect(wrapper.find('.e-form-container').element.getAttribute('value')).toBe(
+ secondText
+ )
+ })
+
+ test('updates vModel when value of input field changes', async () => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+ const text = 'bla'
+
+ input.element.value = text
+ await input.trigger('input')
+
+ expect(wrapper.vm.data).toBe(text)
+ })
+
+ test('allows to use the append slot', async () => {
+ mount({
+ children: `
+
+ append
+
+ `,
+ })
+
+ expect(await screen.findByText('append')).toBeVisible()
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/ETimeField.spec.js b/frontend-vue3/src/components/form/base/__tests__/ETimeField.spec.js
new file mode 100644
index 0000000000..59c579dc7b
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/ETimeField.spec.js
@@ -0,0 +1,51 @@
+import { describe, beforeEach, expect, test } from 'vitest'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+
+import formBaseComponents from '@/plugins/formBaseComponents'
+import dayjs from '@/plugins/dayjs.js'
+
+import ETimeField from '@/components/form/base/ETimeField.vue'
+import { mount as mountComponent } from '@vue/test-utils'
+
+Vue.use(Vuetify)
+Vue.use(dayjs)
+Vue.use(formBaseComponents)
+
+describe('An ETimeField', () => {
+ let vuetify
+
+ const mount = (options) => {
+ const app = Vue.component('App', {
+ components: { ETimeField },
+ data: function () {
+ return {
+ data: null,
+ }
+ },
+ template: `
`,
+ })
+ return mountComponent(app, { vuetify, attachTo: document.body, ...options })
+ }
+
+ beforeEach(() => {
+ vuetify = new Vuetify()
+ })
+
+ test.each([
+ ['8', '08:00'],
+ [' 9 ', '09:00'],
+ ['2400', null],
+ ['19,34', '19:34'],
+ ['19h34', '19:34'],
+ ['', null],
+ ])('parses "%s" as "%s"', async (string, expected) => {
+ const wrapper = mount()
+ const input = wrapper.find('input')
+
+ input.element.value = `${string}`
+ await input.trigger('input')
+
+ expect(wrapper.vm.data).toBe(expected)
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/ETimePicker.spec.js b/frontend-vue3/src/components/form/base/__tests__/ETimePicker.spec.js
new file mode 100644
index 0000000000..a33decab01
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/ETimePicker.spec.js
@@ -0,0 +1,406 @@
+import { screen, waitFor } from '@testing-library/vue'
+import { render, setTestLocale, snapshotOf } from '@/test/renderWithVuetify.js'
+import user from '@testing-library/user-event'
+import ETimePicker from '../ETimePicker.vue'
+
+describe('An ETimePicker', () => {
+ const TIME1_ISO = '2037-07-18T09:52:00+00:00'
+ const TIME1_HHMM = '09:52'
+ const TIME2_ISO = '2037-07-18T18:33:00+00:00'
+ const TIME3_ISO = '2037-07-18T00:52:00+00:00'
+
+ const localeData = {
+ de: {
+ time1: '09:52',
+ time2: '18:33',
+ time3: '00:52',
+ firstHour: '0',
+ labelText: 'Dialog öffnen, um eine Zeit für test zu wählen',
+ closeButton: 'Schliessen',
+ timeInWrongLocale: '9:52 AM',
+ validationMessage: 'Ungültiges Format, bitte gib die Zeit im Format HH:MM ein',
+ },
+ en: {
+ time1: '9:52 AM',
+ time2: '6:33 PM',
+ time3: '12:52 AM',
+ firstHour: '12',
+ labelText: 'Open dialog to select a time for test',
+ closeButton: 'Close',
+ timeInWrongLocale: '09:52',
+ validationMessage:
+ 'Invalid format, please enter the time in the format HH:MM AM/PM',
+ },
+ }
+
+ describe.each(Object.entries(localeData))('in locale %s', (locale, data) => {
+ beforeEach(() => {
+ setTestLocale(locale)
+ })
+
+ it('renders the component', async () => {
+ // given
+
+ // when
+ render(ETimePicker, {
+ props: {
+ value: TIME1_ISO,
+ label: 'test',
+ },
+ })
+
+ // then
+ await screen.findByDisplayValue(data.time1)
+ screen.getByLabelText(data.labelText)
+ })
+
+ it('looks like a time picker', async () => {
+ // given
+
+ // when
+ const { container } = render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+
+ // then
+ expect(snapshotOf(container)).toMatchSnapshot('pickerclosed')
+
+ // when
+ await user.click(screen.getByLabelText(data.labelText))
+
+ // then
+ await screen.findByText(data.closeButton)
+ expect(snapshotOf(container)).toMatchSnapshot('pickeropen')
+ })
+
+ it('allows setting a different valueFormat', async () => {
+ // given
+
+ // when
+ render(ETimePicker, {
+ props: {
+ value: TIME1_HHMM,
+ label: 'test',
+ valueFormat: 'HH:mm',
+ },
+ })
+
+ // then
+ await screen.findByDisplayValue(data.time1)
+ screen.getByLabelText(data.labelText)
+ })
+
+ it('does not open the picker when the text field is clicked', async () => {
+ // given
+ render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(data.time1)
+
+ // when
+ await user.click(inputField)
+
+ // then
+ // menu should not appear
+ await expect(screen.findByText(data.closeButton)).rejects.toThrow(
+ /Unable to find an element with the text/
+ )
+ })
+
+ it('opens the picker when the icon button is clicked', async () => {
+ // given
+ render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ await user.click(button)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.findByText(data.closeButton)).toBeVisible()
+ })
+ })
+
+ it('closes the picker when clicking the close button', async () => {
+ // given
+ render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.closeButton)).toBeVisible()
+ })
+ const closeButton = screen.getByText(data.closeButton)
+
+ // when
+ await user.click(closeButton)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByText(data.closeButton)).not.toBeVisible()
+ })
+ })
+
+ it('closes the picker when clicking outside', async () => {
+ // given
+ render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.closeButton)).toBeVisible()
+ })
+
+ // when
+ await user.click(document.body)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByText(data.closeButton)).not.toBeVisible()
+ })
+ })
+
+ it('closes the picker when pressing escape', async () => {
+ // given
+ render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.closeButton)).toBeVisible()
+ })
+
+ // when
+ await user.click(document.body)
+
+ // then
+ await waitFor(async () => {
+ expect(await screen.queryByText(data.closeButton)).not.toBeVisible()
+ })
+ })
+
+ it('does not close the picker when selecting a time', async () => {
+ // given
+ render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+ const button = await screen.getByLabelText(data.labelText)
+ await user.click(button)
+ await waitFor(async () => {
+ expect(await screen.findByText(data.closeButton)).toBeVisible()
+ })
+
+ // when
+ // Click the 0th hour
+ await user.click(await screen.findByText(data.firstHour))
+ // Click the 45th minute
+ await user.click(await screen.findByText('45'))
+
+ // then
+ // close button should stay visible
+ await expect(
+ waitFor(() => {
+ expect(screen.queryByText(data.closeButton)).not.toBeVisible()
+ })
+ ).rejects.toThrow(/Received element is visible/)
+ })
+
+ describe('updates v-model when the input field is changed', async () => {
+ const timeConfig1 = {
+ iso: TIME1_ISO,
+ localizedTime: data.time1,
+ textInput: data.time1,
+ }
+ const timeConfig2 = {
+ iso: TIME2_ISO,
+ localizedTime: data.time2,
+ textInput: data.time2,
+ }
+ const timeConfig3 = {
+ iso: TIME3_ISO,
+ localizedTime: data.time3,
+ textInput: data.time3,
+ }
+ it.each([
+ {
+ from: timeConfig1,
+ to: timeConfig2,
+ },
+ {
+ from: timeConfig2,
+ to: timeConfig1,
+ },
+ {
+ from: timeConfig1,
+ to: timeConfig3,
+ },
+ //with leading zero
+ {
+ from: timeConfig1,
+ to: {
+ ...timeConfig2,
+ textInput: '0' + timeConfig2.localizedTime,
+ },
+ },
+ {
+ from: timeConfig1,
+ to: {
+ ...timeConfig2,
+ textInput: '0000' + timeConfig2.localizedTime,
+ },
+ },
+ {
+ from: timeConfig2,
+ to: {
+ ...timeConfig1,
+ textInput: '0' + timeConfig1.localizedTime,
+ },
+ },
+ {
+ from: timeConfig2,
+ to: {
+ ...timeConfig1,
+ textInput: '00000' + timeConfig1.localizedTime,
+ },
+ },
+ {
+ from: timeConfig1,
+ to: {
+ ...timeConfig3,
+ textInput: '0' + timeConfig3.localizedTime,
+ },
+ },
+ {
+ from: timeConfig1,
+ to: {
+ ...timeConfig3,
+ textInput: '00000' + timeConfig3.localizedTime,
+ },
+ },
+ ])(
+ `from $from.localizedTime to $to.textInput`,
+ async ({
+ from: { iso: fromIso, localizedTime: fromLocalizedTime },
+ to: { iso: toIso, localizedTime: toLocalizedTime, textInput },
+ }) => {
+ // given
+ const { emitted } = render(ETimePicker, {
+ props: { value: fromIso, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(fromLocalizedTime)
+
+ // when
+ await user.clear(inputField)
+ await user.keyboard(textInput)
+
+ // then
+ await waitFor(async () => {
+ const events = emitted().input
+ // some input events were fired
+ expect(events.length).toBeGreaterThan(0)
+ // the last one included the parsed version of our entered time
+ expect(events[events.length - 1]).toEqual([toIso])
+ })
+ // Our entered time should be visible...
+ screen.getByDisplayValue(toLocalizedTime)
+ // ...and stay visible
+ await expect(
+ waitFor(() => {
+ expect(screen.getByDisplayValue(toLocalizedTime)).not.toBeVisible()
+ })
+ ).rejects.toThrow(/Received element is visible/)
+ }
+ )
+ })
+
+ it('updates v-model when a new time is selected in the picker', async () => {
+ // given
+ const { emitted } = render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+ await screen.findByDisplayValue(data.time1)
+ const button = await screen.getByLabelText(data.labelText)
+
+ // when
+ // click the button to open the picker
+ await user.click(button)
+ // Click the 0th hour. We can only click this one, because
+ // testing library is missing the vuetify styles, and all the
+ // number elements overlap
+ await user.click(await screen.findByText(data.firstHour))
+ // click the close button
+ await user.click(screen.getByText(data.closeButton))
+
+ // then
+ await waitFor(() => {
+ expect(screen.queryByText(data.closeButton)).not.toBeVisible()
+ })
+ await waitFor(async () => {
+ const events = emitted().input
+ // some input events were fired
+ expect(events.length).toBeGreaterThan(0)
+ // the last one included the parsed version of our entered time
+ expect(events[events.length - 1]).toEqual([TIME3_ISO])
+ })
+ // Our entered time should be visible...
+ screen.getByDisplayValue(data.time3)
+ // ...and stay visible
+ await expect(
+ waitFor(() => {
+ expect(screen.getByDisplayValue(data.time3)).not.toBeVisible()
+ })
+ ).rejects.toThrow(/Received element is visible/)
+ })
+
+ describe('validates the input', async () => {
+ it.each([
+ data.timeInWrongLocale,
+ 'a' + data.time1,
+ data.time2 + 'a',
+ '0000:a' + data.time3,
+ ])('%s', async (textInput) => {
+ // given
+ render(ETimePicker, {
+ props: { value: TIME1_ISO, label: 'test' },
+ })
+ const inputField = await screen.findByDisplayValue(data.time1)
+
+ // when
+ await user.clear(inputField)
+ await user.keyboard(textInput)
+
+ // then
+ await screen.findByText(data.validationMessage)
+ })
+ })
+
+ it('works with invalid initialization', async () => {
+ // given
+
+ // when
+ render(ETimePicker, {
+ props: {
+ value: 'abc',
+ label: 'test',
+ },
+ })
+
+ // then
+ const inputField = await screen.findByDisplayValue('Invalid Date')
+
+ // when
+ await user.clear(inputField)
+ await user.keyboard(data.time2)
+
+ // then
+ waitFor(() => {
+ expect(screen.queryByText('Invalid Date')).not.toBeInTheDocument()
+ })
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ECheckbox.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ECheckbox.spec.js.snap
new file mode 100644
index 0000000000..033ec7e16c
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ECheckbox.spec.js.snap
@@ -0,0 +1,53 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An ECheckbox > looks like a checkbox > checked 1`] = `
+
+`;
+
+exports[`An ECheckbox > looks like a checkbox > unchecked 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EColorField.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EColorField.spec.js.snap
new file mode 100644
index 0000000000..12dfeb4f69
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EColorField.spec.js.snap
@@ -0,0 +1,58 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An EColorField > looks like a textfield > empty 1`] = `
+
+`;
+
+exports[`An EColorField > looks like a textfield > with text 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EColorPicker.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EColorPicker.spec.js.snap
new file mode 100644
index 0000000000..641d2e0aee
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EColorPicker.spec.js.snap
@@ -0,0 +1,246 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An EColorPicker > looks like a color picker > pickerclosed 1`] = `
+
+`;
+
+exports[`An EColorPicker > looks like a color picker > pickeropen 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EDatePicker.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EDatePicker.spec.js.snap
new file mode 100644
index 0000000000..cf6641369a
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EDatePicker.spec.js.snap
@@ -0,0 +1,815 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An EDatePicker > in locale de > looks like a date picker > pickerclosed 1`] = `
+
+`;
+
+exports[`An EDatePicker > in locale de > looks like a date picker > pickeropen 1`] = `
+
+`;
+
+exports[`An EDatePicker > in locale en > looks like a date picker > pickerclosed 1`] = `
+
+`;
+
+exports[`An EDatePicker > in locale en > looks like a date picker > pickeropen 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ENumberField.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ENumberField.spec.js.snap
new file mode 100644
index 0000000000..8edadfeef6
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ENumberField.spec.js.snap
@@ -0,0 +1,43 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An ENumberField > looks like a numberfield > empty 1`] = `
+
+`;
+
+exports[`An ENumberField > looks like a numberfield > with text 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EParseField.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EParseField.spec.js.snap
new file mode 100644
index 0000000000..cb85b99c7d
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/EParseField.spec.js.snap
@@ -0,0 +1,41 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An EParseField > looks like a textfield > empty 1`] = `
+
+`;
+
+exports[`An EParseField > looks like a textfield > with text 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ESelect.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ESelect.spec.js.snap
new file mode 100644
index 0000000000..31d24d86bb
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ESelect.spec.js.snap
@@ -0,0 +1,272 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An ESelect > looks like a dropdown > dropdown closed with selected value 1`] = `
+
+`;
+
+exports[`An ESelect > looks like a dropdown > dropdown open 1`] = `
+
+`;
+
+exports[`An ESelect > looks like a dropdown > dropdown open with selected value 1`] = `
+
+`;
+
+exports[`An ESelect > looks like a dropdown > no item selected 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ESwitch.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ESwitch.spec.js.snap
new file mode 100644
index 0000000000..14d8c48196
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ESwitch.spec.js.snap
@@ -0,0 +1,57 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An ESwitch > looks like a switch > checked 1`] = `
+
+`;
+
+exports[`An ESwitch > looks like a switch > unchecked 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETextArea.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETextArea.spec.js.snap
new file mode 100644
index 0000000000..9a08f89911
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETextArea.spec.js.snap
@@ -0,0 +1,128 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An ETextArea > looks like a textarea > mountAsInControls 1`] = `
+
+`;
+
+exports[`An ETextArea > looks like a textarea > multiline 1`] = `
+
+`;
+
+exports[`An ETextArea > looks like a textarea > notext 1`] = `
+
+`;
+
+exports[`An ETextArea > looks like a textarea > withtext 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETextField.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETextField.spec.js.snap
new file mode 100644
index 0000000000..e4d2333125
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETextField.spec.js.snap
@@ -0,0 +1,42 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An ETextField > looks like a textfield > empty 1`] = `
+
+`;
+
+exports[`An ETextField > looks like a textfield > with text 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETimePicker.spec.js.snap b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETimePicker.spec.js.snap
new file mode 100644
index 0000000000..d1fd281416
--- /dev/null
+++ b/frontend-vue3/src/components/form/base/__tests__/__snapshots__/ETimePicker.spec.js.snap
@@ -0,0 +1,358 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`An ETimePicker > in locale de > looks like a time picker > pickerclosed 1`] = `
+
+`;
+
+exports[`An ETimePicker > in locale de > looks like a time picker > pickeropen 1`] = `
+
+`;
+
+exports[`An ETimePicker > in locale en > looks like a time picker > pickerclosed 1`] = `
+
+`;
+
+exports[`An ETimePicker > in locale en > looks like a time picker > pickeropen 1`] = `
+
+`;
diff --git a/frontend-vue3/src/components/form/tiptap/AutoLinkDecoration.js b/frontend-vue3/src/components/form/tiptap/AutoLinkDecoration.js
new file mode 100644
index 0000000000..162016a06e
--- /dev/null
+++ b/frontend-vue3/src/components/form/tiptap/AutoLinkDecoration.js
@@ -0,0 +1,77 @@
+import { Extension } from '@tiptap/vue-3'
+import { Plugin, PluginKey } from '@tiptap/pm/state'
+import { Decoration, DecorationSet } from '@tiptap/pm/view'
+import LinkifyIt from 'linkify-it'
+
+export const AutoLinkKey = new PluginKey('autoLinkDecoration')
+
+export const AutoLinkDecoration = Extension.create({
+ name: 'autoLinkDecoration',
+ addProseMirrorPlugins() {
+ const linkify = new LinkifyIt()
+ /**
+ * @param {import('prosemirror-model').Node} doc
+ */
+ const urlDecoration = (doc) => {
+ const decorations = []
+ doc.descendants((node, pos) => {
+ if (node.isText && linkify.pretest(node.text)) {
+ const matches = linkify.match(node.text)
+ matches?.forEach(({ index, lastIndex, url }) => {
+ if (url.charAt(0) === '/') {
+ return
+ }
+ let link
+ try {
+ link = new URL(url)
+ } catch (_) {
+ /* It can't be parsed as an url */
+ }
+ if (!link.host.includes('.') && !link.port) {
+ return
+ }
+ if (!['http:', 'https:'].includes(link.protocol)) {
+ return
+ }
+ const attrs = {
+ nodeName: 'a',
+ href: url,
+ class: 'autolink',
+ target: '_blank',
+ rel: 'noopener noreferrer',
+ }
+ if (this.editor.isEditable) {
+ attrs.onclick = `(event.metaKey || event.ctrlKey || event.detail > 1) && window.open("${link}", "_blank");`
+ }
+ decorations.push(
+ Decoration.inline(pos + index, pos + lastIndex, attrs, {
+ start: pos + index,
+ end: pos + lastIndex,
+ })
+ )
+ })
+ }
+ })
+ return DecorationSet.create(doc, decorations)
+ }
+
+ return [
+ new Plugin({
+ key: AutoLinkKey,
+ state: {
+ init: (_, { doc }) => {
+ return urlDecoration(doc)
+ },
+ apply: (tr, oldState) => {
+ return tr.docChanged ? urlDecoration(tr.doc) : oldState
+ },
+ },
+ props: {
+ decorations(state) {
+ return this.getState(state)
+ },
+ },
+ }),
+ ]
+ },
+})
diff --git a/frontend-vue3/src/components/form/tiptap/TiptapEditor.vue b/frontend-vue3/src/components/form/tiptap/TiptapEditor.vue
new file mode 100644
index 0000000000..4a6b5c303a
--- /dev/null
+++ b/frontend-vue3/src/components/form/tiptap/TiptapEditor.vue
@@ -0,0 +1,398 @@
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/form/tiptap/TiptapToolbarButton.vue b/frontend-vue3/src/components/form/tiptap/TiptapToolbarButton.vue
new file mode 100644
index 0000000000..8d22690a42
--- /dev/null
+++ b/frontend-vue3/src/components/form/tiptap/TiptapToolbarButton.vue
@@ -0,0 +1,13 @@
+
+
+ {{ icon }}
+
+
+
diff --git a/frontend-vue3/src/components/form/tiptap/VTiptapEditor.vue b/frontend-vue3/src/components/form/tiptap/VTiptapEditor.vue
new file mode 100644
index 0000000000..7fd712c2bb
--- /dev/null
+++ b/frontend-vue3/src/components/form/tiptap/VTiptapEditor.vue
@@ -0,0 +1,87 @@
+
+
+
diff --git a/frontend-vue3/src/components/generic/AvatarRow.vue b/frontend-vue3/src/components/generic/AvatarRow.vue
new file mode 100644
index 0000000000..b52b2a758b
--- /dev/null
+++ b/frontend-vue3/src/components/generic/AvatarRow.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/CategoryChip.vue b/frontend-vue3/src/components/generic/CategoryChip.vue
new file mode 100644
index 0000000000..42f57213a5
--- /dev/null
+++ b/frontend-vue3/src/components/generic/CategoryChip.vue
@@ -0,0 +1,66 @@
+
+
+
+
+ {{ cat.name }}
+
+
+ {{ cat.short }}
+
+
+
+
+ {{ $t('global.loading') }} · · ·
+
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/ClipboardInfoDialog.vue b/frontend-vue3/src/components/generic/ClipboardInfoDialog.vue
new file mode 100644
index 0000000000..046c202c04
--- /dev/null
+++ b/frontend-vue3/src/components/generic/ClipboardInfoDialog.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+ {{ description }}
+
+
+ {{ allow }}
+
+
+ {{ granted }}
+ {{ denied }}
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/DetailPane.vue b/frontend-vue3/src/components/generic/DetailPane.vue
new file mode 100644
index 0000000000..c055c441c0
--- /dev/null
+++ b/frontend-vue3/src/components/generic/DetailPane.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/GenericChip.vue b/frontend-vue3/src/components/generic/GenericChip.vue
new file mode 100644
index 0000000000..d1be5adc09
--- /dev/null
+++ b/frontend-vue3/src/components/generic/GenericChip.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/GenericPage.vue b/frontend-vue3/src/components/generic/GenericPage.vue
new file mode 100644
index 0000000000..3faea56de5
--- /dev/null
+++ b/frontend-vue3/src/components/generic/GenericPage.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/IconWithTooltip.vue b/frontend-vue3/src/components/generic/IconWithTooltip.vue
new file mode 100644
index 0000000000..35b3e499ed
--- /dev/null
+++ b/frontend-vue3/src/components/generic/IconWithTooltip.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+ {{ icon }}
+
+
+
+ {{ text }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/LockButton.vue b/frontend-vue3/src/components/generic/LockButton.vue
new file mode 100644
index 0000000000..899e84d463
--- /dev/null
+++ b/frontend-vue3/src/components/generic/LockButton.vue
@@ -0,0 +1,95 @@
+
+
+
+
+ mdi-lock-open-variant
+ mdi-lock
+
+
+ {{ tooltip }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/LockUnlockListItem.vue b/frontend-vue3/src/components/generic/LockUnlockListItem.vue
new file mode 100644
index 0000000000..f00872d349
--- /dev/null
+++ b/frontend-vue3/src/components/generic/LockUnlockListItem.vue
@@ -0,0 +1,27 @@
+
+
+
+ mdi-lock
+ mdi-lock-open-variant
+
+
+ {{ value ? $t('global.button.lock') : $t('global.button.unlock') }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/generic/useClipboardEntity.js b/frontend-vue3/src/components/generic/useClipboardEntity.js
new file mode 100644
index 0000000000..2ca7e74604
--- /dev/null
+++ b/frontend-vue3/src/components/generic/useClipboardEntity.js
@@ -0,0 +1,89 @@
+import { computed, ref } from 'vue'
+
+export function useClipboardEntity({
+ fetchClipboardEntity,
+ onEntityLoaded,
+ onEntityLoadFailed,
+}) {
+ const clipboardPermission = ref('unknown')
+ const clipboardEntity = ref(null)
+ const _clipoardEntityUrl = ref(null)
+ const loading = ref(false)
+
+ const clipboardEntityUrl = computed({
+ get() {
+ return _clipoardEntityUrl.value
+ },
+ set: setClipboardEntityUrl,
+ })
+
+ async function setClipboardEntityUrl(url) {
+ loading.value = true
+ _clipoardEntityUrl.value = url
+
+ return fetchClipboardEntity(url)
+ .then((entityProxy) => {
+ if (entityProxy == null) return Promise.reject('not found')
+ return entityProxy?._meta.load
+ })
+ .then((entity) => {
+ clipboardEntity.value = entity
+ onEntityLoaded(entity)
+ loading.value = false
+ })
+ .catch(() => {
+ clipboardEntity.value = null
+ onEntityLoadFailed(url)
+ loading.value = false
+ })
+ }
+
+ const clipboardAccessDenied = computed(() => {
+ return (
+ clipboardPermission.value === 'unaccessible' ||
+ clipboardPermission.value === 'denied'
+ )
+ })
+
+ const showClipboardPrompt = computed(() => clipboardPermission.value === 'prompt')
+
+ const hasClipboardEntity = computed(() => {
+ return clipboardEntity.value != null && clipboardEntity.value._meta.self != null
+ })
+
+ const attemptLoadingEntityFromClipboard = async () => {
+ clipboardEntity.value = null
+ return navigator.permissions
+ .query({ name: 'clipboard-read' })
+ .then(async (p) => {
+ clipboardPermission.value = p.state
+ if (p.state === 'granted') {
+ const url = await navigator.clipboard.readText()
+ if (url) return setClipboardEntityUrl(url)
+ }
+ // If we get here, we have failed to get the url from the clipboard
+ onEntityLoadFailed(null)
+ })
+ .catch(() => {
+ clipboardPermission.value = 'unaccessible'
+ console.warn('clipboard permission not requestable')
+ })
+ }
+
+ const clearClipboard = async () => {
+ await navigator.clipboard.writeText('')
+ attemptLoadingEntityFromClipboard()
+ }
+
+ return {
+ clipboardAccessDenied,
+ showClipboardPrompt,
+ hasClipboardEntity,
+ clipboardEntity,
+ clipboardEntityUrl,
+ clipboardEntityLoading: loading,
+ attemptLoadingEntityFromClipboard,
+ setClipboardEntityUrl,
+ clearClipboard,
+ }
+}
diff --git a/frontend-vue3/src/components/layout/AuthContainer.vue b/frontend-vue3/src/components/layout/AuthContainer.vue
new file mode 100644
index 0000000000..2928b0a068
--- /dev/null
+++ b/frontend-vue3/src/components/layout/AuthContainer.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+ {{ $t('components.layout.authContainer.photoCredits') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/layout/ContentActions.vue b/frontend-vue3/src/components/layout/ContentActions.vue
new file mode 100644
index 0000000000..628f58f75e
--- /dev/null
+++ b/frontend-vue3/src/components/layout/ContentActions.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/layout/ContentCard.vue b/frontend-vue3/src/components/layout/ContentCard.vue
new file mode 100644
index 0000000000..34b316701d
--- /dev/null
+++ b/frontend-vue3/src/components/layout/ContentCard.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/layout/ContentGroup.vue b/frontend-vue3/src/components/layout/ContentGroup.vue
new file mode 100644
index 0000000000..ed43fc339b
--- /dev/null
+++ b/frontend-vue3/src/components/layout/ContentGroup.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+ {{ icon }}
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/layout/HorizontalRule.vue b/frontend-vue3/src/components/layout/HorizontalRule.vue
new file mode 100644
index 0000000000..268ff4541a
--- /dev/null
+++ b/frontend-vue3/src/components/layout/HorizontalRule.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/layout/IconSpacer.vue b/frontend-vue3/src/components/layout/IconSpacer.vue
new file mode 100644
index 0000000000..6340c82a7e
--- /dev/null
+++ b/frontend-vue3/src/components/layout/IconSpacer.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/layout/LanguageSwitcher.vue b/frontend-vue3/src/components/layout/LanguageSwitcher.vue
new file mode 100644
index 0000000000..03d890868b
--- /dev/null
+++ b/frontend-vue3/src/components/layout/LanguageSwitcher.vue
@@ -0,0 +1,41 @@
+
+
+
+
+ mdi-translate
+ {{ $t('global.language') }}
+
+
+
+
+ {{ $t('global.language', 1, item) }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/layout/SidebarListItem.vue b/frontend-vue3/src/components/layout/SidebarListItem.vue
new file mode 100644
index 0000000000..5bb60d52c2
--- /dev/null
+++ b/frontend-vue3/src/components/layout/SidebarListItem.vue
@@ -0,0 +1,33 @@
+
+
+
+
+ {{ icon }}
+
+
+
+ {{ title }}
+ {{ subtitle }}
+
+
+ mdi-chevron-right
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/layout/TextAlignBaseline.vue b/frontend-vue3/src/components/layout/TextAlignBaseline.vue
new file mode 100644
index 0000000000..d28a2c7c3b
--- /dev/null
+++ b/frontend-vue3/src/components/layout/TextAlignBaseline.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/DialogMaterialItemCreate.vue b/frontend-vue3/src/components/material/DialogMaterialItemCreate.vue
new file mode 100644
index 0000000000..c6a9bf89b7
--- /dev/null
+++ b/frontend-vue3/src/components/material/DialogMaterialItemCreate.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/DialogMaterialItemEdit.vue b/frontend-vue3/src/components/material/DialogMaterialItemEdit.vue
new file mode 100644
index 0000000000..28a89d6031
--- /dev/null
+++ b/frontend-vue3/src/components/material/DialogMaterialItemEdit.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/DialogMaterialItemForm.vue b/frontend-vue3/src/components/material/DialogMaterialItemForm.vue
new file mode 100644
index 0000000000..edc632d4d0
--- /dev/null
+++ b/frontend-vue3/src/components/material/DialogMaterialItemForm.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/MaterialCreateItem.vue b/frontend-vue3/src/components/material/MaterialCreateItem.vue
new file mode 100644
index 0000000000..01b8a41531
--- /dev/null
+++ b/frontend-vue3/src/components/material/MaterialCreateItem.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/MaterialLists.vue b/frontend-vue3/src/components/material/MaterialLists.vue
new file mode 100644
index 0000000000..8e8490a6f7
--- /dev/null
+++ b/frontend-vue3/src/components/material/MaterialLists.vue
@@ -0,0 +1,59 @@
+
+
+
+
+ {{ $t('components.material.materialLists.overview') }}
+
+
+ mdi-chevron-right
+
+
+
+
+
+ {{ materialList.name }}
+ {{
+ $t(
+ 'components.material.materialLists.materialsCount',
+ materialList.itemCount,
+ {
+ count: materialList.itemCount,
+ }
+ )
+ }}
+
+
+
+ mdi-chevron-right
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/MaterialListsEdit.vue b/frontend-vue3/src/components/material/MaterialListsEdit.vue
new file mode 100644
index 0000000000..3ba7a2e4ab
--- /dev/null
+++ b/frontend-vue3/src/components/material/MaterialListsEdit.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+ {{ materialList.name }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/MaterialTable.vue b/frontend-vue3/src/components/material/MaterialTable.vue
new file mode 100644
index 0000000000..8e8ba61704
--- /dev/null
+++ b/frontend-vue3/src/components/material/MaterialTable.vue
@@ -0,0 +1,508 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.quantity }}
+
+
+
+
+ {{ item.unit }}
+
+
+
+
+
+ {{ item.article }}
+
+
+
+ {{ item.combinedQuantity }} {{ item.article }}
+
+ {{ item.listName }}
+
+
+
+
+
+ {{ item.listName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ $t('global.serverError.short')
+ }}
+
+
+
+
+
+
+ {{ $t('global.button.discard') }}
+
+
+
+
+
+
+
+
+ {{
+ $t('global.button.filter')
+ }}
+ {{
+ periodOnly
+ ? $t('components.material.materialTable.periodOnly')
+ : $t('components.material.materialTable.reference')
+ }}
+
+
+ {{ periodOnly ? 'mdi-filter' : 'mdi-filter-outline' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('components.material.materialTable.addNewItem') }}
+
+
+
+
+
+ {{ $t('components.material.materialTable.noItems') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/PeriodMaterialLists.vue b/frontend-vue3/src/components/material/PeriodMaterialLists.vue
new file mode 100644
index 0000000000..fea2a29a43
--- /dev/null
+++ b/frontend-vue3/src/components/material/PeriodMaterialLists.vue
@@ -0,0 +1,40 @@
+
+
+
+
+ {{ period.description }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/ScheduleEntryLinks.vue b/frontend-vue3/src/components/material/ScheduleEntryLinks.vue
new file mode 100644
index 0000000000..7895b50b8c
--- /dev/null
+++ b/frontend-vue3/src/components/material/ScheduleEntryLinks.vue
@@ -0,0 +1,84 @@
+
+
+
+ {{
+ $vuetify.display.smAndUp ? fullDescription(items[0]) : shortDescription(items[0])
+ }}
+
+
+
+ {{ $vuetify.display.smAndUp ? `\u2009${activity.title}:` : '' }}
+
+ {{
+ index < items.length - 1
+ ? `${shortDescription(scheduleEntry)},`
+ : shortDescription(scheduleEntry)
+ }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/material/__tests__/shortScheduleEntryDescription.spec.js b/frontend-vue3/src/components/material/__tests__/shortScheduleEntryDescription.spec.js
new file mode 100644
index 0000000000..f9c9812519
--- /dev/null
+++ b/frontend-vue3/src/components/material/__tests__/shortScheduleEntryDescription.spec.js
@@ -0,0 +1,39 @@
+import shortScheduleEntryDescription from '../shortScheduleEntryDescription.js'
+import createI18n from '@/components/print/print-client/i18n.js'
+import { i18n } from '@/plugins/i18n'
+
+describe('shortScheduleEntryDescription', () => {
+ const { translate } = createI18n(i18n.messages, 'en')
+ const tc = (key, _count, params) => translate(key, params)
+
+ it.each([
+ [{ _meta: { loading: true } }, ''],
+ [null, ''],
+ [undefined, ''],
+ [
+ {
+ _meta: { loading: false },
+ number: '1.2',
+ activity: () => ({
+ title: 'foo',
+ }),
+ dayNumber: '3',
+ },
+ '1.2',
+ ],
+ [
+ {
+ _meta: { loading: false },
+ number: '',
+ activity: () => ({
+ title: 'foo',
+ }),
+ dayNumber: '3',
+ start: '2024-01-01T10:00:00+00:00',
+ },
+ 'day 3 10:00',
+ ],
+ ])('maps %o to "%s"', (input, expected) => {
+ expect(shortScheduleEntryDescription(input, tc)).toEqual(expected)
+ })
+})
diff --git a/frontend-vue3/src/components/material/shortScheduleEntryDescription.js b/frontend-vue3/src/components/material/shortScheduleEntryDescription.js
new file mode 100644
index 0000000000..7eedb20b9b
--- /dev/null
+++ b/frontend-vue3/src/components/material/shortScheduleEntryDescription.js
@@ -0,0 +1,13 @@
+import { hourShort } from '@/common/helpers/dateHelperUTCFormatted.js'
+
+export default function shortScheduleEntryDescription(scheduleEntry, tc) {
+ if (!scheduleEntry || scheduleEntry._meta.loading) return ''
+ return (
+ scheduleEntry?.number ||
+ // For numbering style "none", display the activity title and day number instead
+ tc('global.shortScheduleEntryDescription', 1, {
+ dayNumber: scheduleEntry.dayNumber,
+ startTime: hourShort(scheduleEntry.start, tc),
+ })
+ )
+}
diff --git a/frontend-vue3/src/components/material/useMaterialViewHelper.js b/frontend-vue3/src/components/material/useMaterialViewHelper.js
new file mode 100644
index 0000000000..9f686b2e97
--- /dev/null
+++ b/frontend-vue3/src/components/material/useMaterialViewHelper.js
@@ -0,0 +1,134 @@
+import { computed, onMounted, ref } from 'vue'
+import { useRoute } from 'vue-router'
+import * as XLSX from 'xlsx'
+import { slugify } from '@/plugins/slugify.js'
+import i18n from '@/plugins/i18n/index.js'
+import dayjs from '@/common/helpers/dayjs.js'
+import { apiStore } from '@/plugins/store/index.js'
+import { materialListFromRoute } from '@/router.js'
+import shortScheduleEntryDescription from './shortScheduleEntryDescription.js'
+
+function generateFilename(camp, materialList) {
+ const description = materialList
+ ? [i18n.t('components.material.useMaterialViewHelper.detail'), materialList]
+ : [i18n.t('components.material.useMaterialViewHelper.overview')]
+ const filename = [camp.name, ...description].map(slugify)
+ return [...filename, dayjs().format('YYMMDDHHmmss')].join('_') + '.xlsx'
+}
+
+async function getActivity(camp, materialItem) {
+ if (!materialItem.materialNode) {
+ return null
+ }
+ const root = await materialItem.materialNode().$href('root')
+ return camp
+ .activities()
+ .items.find((activity) => activity.rootContentNode()._meta.self === root)
+}
+
+async function getSheets(camp, collection, materialList) {
+ return await Promise.all(
+ collection.map(async ({ period, materialItems }) => {
+ const data = [
+ [
+ `${
+ materialList ?? i18n.t('components.material.useMaterialViewHelper.overview')
+ }: ${period.description}`,
+ ],
+ [
+ i18n.t('entity.materialItem.fields.quantity'),
+ i18n.t('entity.materialItem.fields.unit'),
+ i18n.t('entity.materialItem.fields.article'),
+ ...(!materialList ? [i18n.t('entity.materialItem.fields.list')] : []),
+ i18n.t('entity.materialItem.fields.reference'),
+ ],
+ ]
+ await Promise.all(
+ materialItems.items.map(async (materialItem) => {
+ const activity = await getActivity(camp, materialItem)
+ const scheduleEntries = activity
+ ?.scheduleEntries()
+ .items.map((item) => shortScheduleEntryDescription(item, i18n.tc.bind(i18n)))
+ .join(', ')
+ data.push([
+ materialItem.quantity,
+ materialItem.unit,
+ materialItem.article,
+ ...(!materialList ? [materialItem.materialList().name] : []),
+ activity?.title
+ ? `${activity.category().short} ${activity?.title}: ${scheduleEntries}`
+ : period.description,
+ ])
+ })
+ )
+ return { sheetName: period.description, data }
+ })
+ )
+}
+
+/**
+ * @param {object} camp
+ * @param {{value: {period: object, materialItems: {items: array}}[]}} collection
+ * @param {string} materialList materialList name if set
+ */
+function downloadMaterialList(camp, collection, materialList) {
+ return async () => {
+ await camp.activities().$loadItems()
+
+ const workbook = XLSX.utils.book_new()
+ const sheets = await getSheets(camp, collection.value, materialList)
+ sheets.forEach(({ sheetName, data }) => {
+ const worksheet = XLSX.utils.aoa_to_sheet(data)
+ const validSheetName = sheetName.replaceAll(/[?*[\]/\\:]/g, '')
+ workbook.SheetNames.push(validSheetName)
+ workbook.Sheets[validSheetName] = worksheet
+ })
+ XLSX.writeFile(workbook, generateFilename(camp, materialList))
+ }
+}
+
+function loadPeriods(camp) {
+ const openPeriods = ref([])
+
+ camp.periods()._meta.load.then((period) =>
+ period.items.forEach((period, index) => {
+ if (Date.parse(period.end) >= Date.now()) {
+ openPeriods.value.push(index)
+ }
+ })
+ )
+
+ return openPeriods
+}
+
+/**
+ * @param {Object} camp
+ * @param {boolean} [list]
+ */
+export function useMaterialViewHelper(camp, list) {
+ const computedList = computed(() => (list ? materialListFromRoute(useRoute()) : null))
+
+ const collection = computed(() => {
+ const materialList = computedList.value?._meta.self
+ return camp.periods().items.map((period) => ({
+ period,
+ materialItems: apiStore.get().materialItems({
+ period: period._meta.self,
+ materialList,
+ }),
+ }))
+ })
+
+ const downloadXlsx = downloadMaterialList(camp, collection, computedList.value?.name)
+ const openPeriods = loadPeriods(camp)
+
+ onMounted(() => {
+ collection.value.map(({ materialItems }) => materialItems.$reload())
+ })
+
+ return {
+ collection,
+ downloadXlsx,
+ openPeriods,
+ }
+}
diff --git a/frontend-vue3/src/components/navigation/Logo.vue b/frontend-vue3/src/components/navigation/Logo.vue
new file mode 100644
index 0000000000..eabeb9f704
--- /dev/null
+++ b/frontend-vue3/src/components/navigation/Logo.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+ eCamp
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/navigation/SideBar.vue b/frontend-vue3/src/components/navigation/SideBar.vue
new file mode 100644
index 0000000000..9ae24df8f3
--- /dev/null
+++ b/frontend-vue3/src/components/navigation/SideBar.vue
@@ -0,0 +1,55 @@
+
+
+
+
+ {{ icon }}
+
+
+
+ {{ title }}
+
+
+ mdi-chevron-left
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/navigation/TopNavigationItem.vue b/frontend-vue3/src/components/navigation/TopNavigationItem.vue
new file mode 100644
index 0000000000..bca9198507
--- /dev/null
+++ b/frontend-vue3/src/components/navigation/TopNavigationItem.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+ {{ text }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/navigation/UserMeta.vue b/frontend-vue3/src/components/navigation/UserMeta.vue
new file mode 100644
index 0000000000..f876ee438a
--- /dev/null
+++ b/frontend-vue3/src/components/navigation/UserMeta.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ authUser.displayName }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ authUser.displayName }}
+
+
+
+
+
+ mdi-account
+ {{ $t('components.navigation.userMeta.profile') }}
+
+
+ mdi-format-list-bulleted-triangle
+ {{ $t('components.navigation.userMeta.myCamps') }}
+
+
+ mdi-email
+ {{ $t('components.navigation.userMeta.invitations') }}
+
+
+
+
+
+ mdi-help-circle
+ {{ $t('global.navigation.help') }}
+
+ mdi-open-in-new
+
+
+ mdi-script-text-outline
+ {{ $t('global.navigation.news') }}
+
+ mdi-open-in-new
+
+
+
+
+ mdi-logout
+
+ {{ $t('components.navigation.userMeta.logOut') }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/personal_invitations/DialogPersonalInvitationReject.vue b/frontend-vue3/src/components/personal_invitations/DialogPersonalInvitationReject.vue
new file mode 100644
index 0000000000..237da519ad
--- /dev/null
+++ b/frontend-vue3/src/components/personal_invitations/DialogPersonalInvitationReject.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+ {{
+ $t(
+ 'components.personalInvitations.dialogPersonalInvitationReject.warningText',
+ 0,
+ { campTitle: campTitle }
+ )
+ }}
+
+
+
+ {{ error }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/personal_invitations/PersonalInvitations.vue b/frontend-vue3/src/components/personal_invitations/PersonalInvitations.vue
new file mode 100644
index 0000000000..6964e6c354
--- /dev/null
+++ b/frontend-vue3/src/components/personal_invitations/PersonalInvitations.vue
@@ -0,0 +1,137 @@
+
+
+
+
+ {{
+ $t('components.personalInvitations.personalInvitations.noOpenInvitations', 0, {
+ email: authUser.profile().email,
+ })
+ }}
+
+
+
+
+
+ {{ invitation.campTitle }}
+
+
+
+
+
+ {{ $t('components.personalInvitations.personalInvitations.reject') }}
+
+
+
+
+
+
+ {{ $t('components.personalInvitations.personalInvitations.accept') }}
+
+
+
+
+
+
+
+
+ {{ invitation.campTitle }}
+
+
+
+
+
+
+
+ {{ $t('components.personalInvitations.personalInvitations.reject') }}
+
+
+
+
+
+
+
+ {{ $t('components.personalInvitations.personalInvitations.accept') }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/PrintConfigurator.vue b/frontend-vue3/src/components/print/PrintConfigurator.vue
new file mode 100644
index 0000000000..1bf92db25e
--- /dev/null
+++ b/frontend-vue3/src/components/print/PrintConfigurator.vue
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('components.print.printConfigurator.config.' + idx) }}
+
+
+
+
+
+
+
+
+ View Print-Config
+
+
+ {{ cnf }}
+
+
+
+
+
+
+
+
+
+
+
+
+ Nuxt preview
+ Client print preview
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/__tests__/repairPrintConfig.spec.js b/frontend-vue3/src/components/print/__tests__/repairPrintConfig.spec.js
new file mode 100644
index 0000000000..54c598658b
--- /dev/null
+++ b/frontend-vue3/src/components/print/__tests__/repairPrintConfig.spec.js
@@ -0,0 +1,948 @@
+import repairConfig from '../repairPrintConfig.js'
+import PicassoConfig from '../config/PicassoConfig.vue'
+import ActivityConfig from '../config/ActivityConfig.vue'
+import CoverConfig from '../config/CoverConfig.vue'
+import ProgramConfig from '../config/ProgramConfig.vue'
+import StoryConfig from '../config/StoryConfig.vue'
+import TocConfig from '../config/TocConfig.vue'
+
+describe('repairConfig', () => {
+ const camp = {
+ _meta: { self: '/camps/1a2b3c4d' },
+ name: 'test camp',
+ periods: () => ({
+ items: [
+ {
+ _meta: { self: '/periods/1a2b3c4d' },
+ },
+ ],
+ }),
+ }
+ const availableLocales = ['en-GB', 'de-CH', 'de-CH-scout']
+ const componentRepairers = Object.fromEntries(
+ [
+ ActivityConfig,
+ CoverConfig,
+ PicassoConfig,
+ ProgramConfig,
+ StoryConfig,
+ TocConfig,
+ ].map((component) => [component.name.replace(/Config$/, ''), component.repairConfig])
+ )
+ const defaultContents = [
+ { type: 'Picasso', options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' } },
+ ]
+ const args = [camp, availableLocales, 'en', componentRepairers, defaultContents]
+
+ test('fills empty config with default data', async () => {
+ // given
+ const config = {}
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('leaves valid config alone', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('allows valid language', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'de-CH-scout',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'de-CH-scout',
+ })
+ })
+
+ test('replaces invalid language with fallback language', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'definitely-not-a-supported-language',
+ }
+
+ // when
+ const result = repairConfig(
+ config,
+ camp,
+ availableLocales,
+ 'de-CH-scout',
+ componentRepairers,
+ defaultContents
+ )
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'de-CH-scout',
+ })
+ })
+
+ test('replaces invalid language with any valid language if fallback language is also invalid', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'definitely-not-a-supported-language',
+ }
+
+ // when
+ const result = repairConfig(
+ config,
+ camp,
+ availableLocales,
+ 'definitely-not-a-valid-language',
+ componentRepairers,
+ defaultContents
+ )
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('leaves custom documentName alone', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'foobar',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'foobar',
+ language: 'en-GB',
+ })
+ })
+
+ test('fills in missing documentName', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: '',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('overwrites camp URI', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d?something',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('overwrites invalid contents with default', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: {},
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('overwrites null contents with default', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: null,
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('leaves empty content alone', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('filters out unknown content', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'SomethingUnsupported',
+ options: {},
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ describe('activity', () => {
+ test('leaves config alone', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Activity',
+ foo: 'bar',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Activity',
+ foo: 'bar',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+ })
+
+ describe('cover', () => {
+ test('leaves config alone', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Cover',
+ foo: 'bar',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Cover',
+ foo: 'bar',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+ })
+
+ describe('picasso', () => {
+ test('adds missing options', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: [], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('allows landscape mode', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('allows portrait mode', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'P' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'P' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('allows empty periods', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: [], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: [], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('overwrites invalid orientation', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'hello' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('filters out unknown periods', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: {
+ periods: ['/periods/11112222', '/periods/1a2b3c4d'],
+ orientation: 'L',
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Picasso',
+ options: { periods: ['/periods/1a2b3c4d'], orientation: 'L' },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+ })
+
+ describe('program', () => {
+ test('adds missing options', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: {
+ periods: [],
+ dayOverview: true,
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('adds missing dayOverview flag', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: {
+ periods: ['/periods/1a2b3c4d'],
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: {
+ periods: ['/periods/1a2b3c4d'],
+ dayOverview: true,
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('allows dayOverview false', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: {
+ periods: ['/periods/1a2b3c4d'],
+ dayOverview: false,
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: {
+ periods: ['/periods/1a2b3c4d'],
+ dayOverview: false,
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('allows empty periods', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: { periods: [], dayOverview: true },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: { periods: [], dayOverview: true },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('filters out unknown periods', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: {
+ periods: ['/periods/11112222', '/periods/1a2b3c4d'],
+ dayOverview: true,
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Program',
+ options: {
+ periods: ['/periods/1a2b3c4d'],
+ dayOverview: true,
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+ })
+
+ describe('story', () => {
+ test('adds missing options', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Story',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Story',
+ options: { periods: [] },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('allows empty periods', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Story',
+ options: { periods: [] },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Story',
+ options: { periods: [] },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+
+ test('filters out unknown periods', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Story',
+ options: {
+ periods: ['/periods/11112222', '/periods/1a2b3c4d'],
+ },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Story',
+ options: { periods: ['/periods/1a2b3c4d'] },
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+ })
+
+ describe('toc', () => {
+ test('leaves config alone', async () => {
+ // given
+ const config = {
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Toc',
+ foo: 'bar',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ }
+
+ // when
+ const result = repairConfig(config, ...args)
+
+ // then
+ expect(result).toEqual({
+ camp: '/camps/1a2b3c4d',
+ contents: [
+ {
+ type: 'Toc',
+ foo: 'bar',
+ },
+ ],
+ documentName: 'test camp',
+ language: 'en-GB',
+ })
+ })
+ })
+})
diff --git a/frontend-vue3/src/components/print/config/ActivityConfig.vue b/frontend-vue3/src/components/print/config/ActivityConfig.vue
new file mode 100644
index 0000000000..2f3f3af0e3
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/ActivityConfig.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/config/ActivityListConfig.vue b/frontend-vue3/src/components/print/config/ActivityListConfig.vue
new file mode 100644
index 0000000000..4d5fb833dc
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/ActivityListConfig.vue
@@ -0,0 +1,92 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/config/CoverConfig.vue b/frontend-vue3/src/components/print/config/CoverConfig.vue
new file mode 100644
index 0000000000..53070670be
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/CoverConfig.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/config/DialogScheduleEntryFilter.vue b/frontend-vue3/src/components/print/config/DialogScheduleEntryFilter.vue
new file mode 100644
index 0000000000..ad0168920c
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/DialogScheduleEntryFilter.vue
@@ -0,0 +1,114 @@
+
+
+
+
+ mdi-filter
+ {{ activatorLabel }}
+
+
+
+
+ {{ resultCountLabel }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/config/PicassoConfig.vue b/frontend-vue3/src/components/print/config/PicassoConfig.vue
new file mode 100644
index 0000000000..da6b1499d2
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/PicassoConfig.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/config/ProgramConfig.vue b/frontend-vue3/src/components/print/config/ProgramConfig.vue
new file mode 100644
index 0000000000..14d4b8d312
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/ProgramConfig.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/config/SafetyConsiderationsConfig.vue b/frontend-vue3/src/components/print/config/SafetyConsiderationsConfig.vue
new file mode 100644
index 0000000000..5811134237
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/SafetyConsiderationsConfig.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/config/StoryConfig.vue b/frontend-vue3/src/components/print/config/StoryConfig.vue
new file mode 100644
index 0000000000..4613843083
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/StoryConfig.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/config/SummaryConfig.vue b/frontend-vue3/src/components/print/config/SummaryConfig.vue
new file mode 100644
index 0000000000..af20659458
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/SummaryConfig.vue
@@ -0,0 +1,52 @@
+
diff --git a/frontend-vue3/src/components/print/config/TocConfig.vue b/frontend-vue3/src/components/print/config/TocConfig.vue
new file mode 100644
index 0000000000..8f23f06f4a
--- /dev/null
+++ b/frontend-vue3/src/components/print/config/TocConfig.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/configurator/PagesConfig.vue b/frontend-vue3/src/components/print/configurator/PagesConfig.vue
new file mode 100644
index 0000000000..842685d5a6
--- /dev/null
+++ b/frontend-vue3/src/components/print/configurator/PagesConfig.vue
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+
mdi-plus
+
+ mdi-drag
+ {{ title }}
+ mdi-drag
+
+
+
+
+
+
+
+
+
+
+
+ mdi-plus
+
+
+ {{ title }}
+
+
+
+
+
+ mdi-drag
+
+
+ {{ title }}
+
+
+
+ mdi-delete
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/configurator/PagesOverview.vue b/frontend-vue3/src/components/print/configurator/PagesOverview.vue
new file mode 100644
index 0000000000..a066424753
--- /dev/null
+++ b/frontend-vue3/src/components/print/configurator/PagesOverview.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/print-client/DownloadClientPdfButton.vue b/frontend-vue3/src/components/print/print-client/DownloadClientPdfButton.vue
new file mode 100644
index 0000000000..3094e3b0f7
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/DownloadClientPdfButton.vue
@@ -0,0 +1,19 @@
+
+
+
+ mdi-printer
+
+ {{ $t('components.print.printClient.downloadClientPdfButton.label') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/print-client/DownloadClientPdfListItem.vue b/frontend-vue3/src/components/print/print-client/DownloadClientPdfListItem.vue
new file mode 100644
index 0000000000..600edaaaf4
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/DownloadClientPdfListItem.vue
@@ -0,0 +1,22 @@
+
+
+
+ mdi-loading
+ mdi-printer
+
+
+ {{ $t('components.print.printClient.downloadClientPdfListItem.label') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/print-client/PrintPreviewClient.vue b/frontend-vue3/src/components/print/print-client/PrintPreviewClient.vue
new file mode 100644
index 0000000000..255f032ca3
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/PrintPreviewClient.vue
@@ -0,0 +1,109 @@
+
+
+
+
+
+ {{ $t('components.print.printClient.printPreviewClient.previewError') }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/print-client/generatePdf.js b/frontend-vue3/src/components/print/print-client/generatePdf.js
new file mode 100644
index 0000000000..c74aeb69c5
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/generatePdf.js
@@ -0,0 +1,45 @@
+import { prepareInMainThread } from '@/pdf/prepareInMainThread.js'
+import cloneDeep from 'lodash-es/cloneDeep.js'
+
+export const generatePdf = async (data) => {
+ await prepareInMainThread(data.config)
+
+ const serializableData = prepareDataForSerialization(data)
+
+ if (data.renderInWorker) {
+ // ComlinkWorker is provided by vite-plugin-comlink
+ // eslint-disable-next-line no-undef
+ const instance = new ComlinkWorker(new URL('./renderPdf.worker.js', import.meta.url))
+ return await instance.renderPdfInWorker(serializableData)
+ } else {
+ return await (await import('./renderPdf.js')).renderPdf(serializableData)
+ }
+}
+
+function prepareDataForSerialization(data) {
+ return {
+ config: JSON.parse(
+ JSON.stringify(replaceEntitiesWithRelativeUris(cloneDeep(data.config)))
+ ),
+ storeData: JSON.parse(JSON.stringify(data.storeData)),
+ translationData: JSON.parse(JSON.stringify(data.translationData)),
+ }
+}
+
+function replaceEntitiesWithRelativeUris(map) {
+ Object.keys(map).forEach((key) => {
+ const value = map[key]
+ const relativeUri = relativeUriFor(value)
+ if (relativeUri) {
+ map[key] = relativeUri
+ }
+ })
+ return map
+}
+
+function relativeUriFor(entity) {
+ if (typeof entity !== 'function') {
+ return entity
+ }
+ return entity()?._meta?.self
+}
diff --git a/frontend-vue3/src/components/print/print-client/generatePdfMixin.js b/frontend-vue3/src/components/print/print-client/generatePdfMixin.js
new file mode 100644
index 0000000000..2eb4be550e
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/generatePdfMixin.js
@@ -0,0 +1,52 @@
+import { saveAs } from 'file-saver'
+import slugify from 'slugify'
+import * as Sentry from '@sentry/browser'
+import { generatePdf } from './generatePdf.js'
+
+const RENDER_IN_WORKER = true
+
+export const generatePdfMixin = {
+ props: {
+ config: {
+ type: Object,
+ default: () => {},
+ },
+ },
+ data() {
+ return {
+ loading: false,
+ }
+ },
+ methods: {
+ async generatePdf() {
+ if (this.loading) {
+ return
+ }
+
+ this.loading = true
+
+ const { blob, error } = await generatePdf({
+ config: { ...this.config, apiGet: this.api.get.bind(this) },
+ storeData: this.$store.state,
+ translationData: this.$i18n.messages,
+ renderInWorker: RENDER_IN_WORKER,
+ })
+
+ if (error) {
+ this.$toast.error(this.$t('components.print.printClient.generatePdfMixin.error'))
+ Sentry.captureException(new Error(error))
+ this.loading = false
+ return
+ }
+
+ saveAs(
+ blob,
+ slugify(this.config.documentName, {
+ locale: this.$store.state.lang.language.substring(0, 2),
+ }) + '.pdf'
+ )
+
+ this.loading = false
+ },
+ },
+}
diff --git a/frontend-vue3/src/components/print/print-client/i18n.js b/frontend-vue3/src/components/print/print-client/i18n.js
new file mode 100644
index 0000000000..ac5a678a43
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/i18n.js
@@ -0,0 +1,31 @@
+import {
+ compile,
+ createCoreContext,
+ fallbackWithLocaleChain,
+ registerLocaleFallbacker,
+ registerMessageCompiler,
+ resolveValue,
+ translate,
+} from '@intlify/core'
+
+const createI18n = (translationData, language) => {
+ registerMessageCompiler(compile)
+ registerLocaleFallbacker(fallbackWithLocaleChain)
+
+ const context = createCoreContext({
+ locale: language,
+ fallbackLocale: 'en',
+ messages: translationData,
+ missingWarn: false,
+ fallbackWarn: false,
+ messageResolver: resolveValue,
+ })
+
+ return {
+ translate: (...args) => {
+ return translate(context, ...args)
+ },
+ }
+}
+
+export default createI18n
diff --git a/frontend-vue3/src/components/print/print-client/minimalHalJsonVuex.js b/frontend-vue3/src/components/print/print-client/minimalHalJsonVuex.js
new file mode 100644
index 0000000000..ef7392f57c
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/minimalHalJsonVuex.js
@@ -0,0 +1,136 @@
+import { parseTemplate } from 'url-template'
+
+function isEqualIgnoringOrder(array, other) {
+ return array.length === other.length && array.every((elem) => other.includes(elem))
+}
+
+function isCollection(object) {
+ return !!(object && Array.isArray(object.items))
+}
+
+function isEntityReference(object) {
+ if (!object) return false
+ return isEqualIgnoringOrder(Object.keys(object), ['href']) || isVirtualLink(object)
+}
+
+function isTemplatedLink(object) {
+ if (!object) return false
+ return (
+ isEqualIgnoringOrder(Object.keys(object), ['href', 'templated']) &&
+ object.templated === true
+ )
+}
+
+function isVirtualLink(object) {
+ if (!object) return false
+ return (
+ isEqualIgnoringOrder(Object.keys(object), ['href', 'virtual']) &&
+ object.virtual === true
+ )
+}
+
+function normalizeEntityUri(uriOrEntity) {
+ if (typeof uriOrEntity === 'function') {
+ uriOrEntity = uriOrEntity()
+ }
+ if (typeof uriOrEntity === 'object') {
+ uriOrEntity = uriOrEntity._meta?.self || ''
+ }
+
+ return uriOrEntity
+}
+
+const wrap = (storeData) => {
+ const actions = {
+ get: (uriOrEntity) => {
+ const uri = normalizeEntityUri(uriOrEntity)
+
+ const data = storeData[uri]
+ const meta = data?._meta || { loading: true }
+
+ if (meta.loading) {
+ throw new Error(
+ `The uri ${uri} is missing in the pre-loaded store data. Please make sure it is loaded before trying to access it using minimalHalJsonVuex`
+ )
+ }
+
+ if (isCollection(data)) {
+ return new Collection(data, actions)
+ } else {
+ return new StoreValue(data, actions)
+ }
+ },
+ href: (uriOrEntity, relation) => {
+ return actions.get(uriOrEntity).$href(relation)
+ },
+ }
+
+ return actions
+}
+
+class StoreValue {
+ constructor(storeData, actions) {
+ this._storeData = storeData
+ this._actions = actions
+
+ Object.keys(storeData)
+ .filter((key) => key !== 'items') // exclude reserved properties
+ .forEach((key) => {
+ const value = storeData[key]
+
+ // storeData[key] is an embedded collection (need min. 1 item to detect an embedded collection)
+ if (Array.isArray(value) && value.length > 0 && isEntityReference(value[0])) {
+ this[key] = () => new EmbeddedCollection(value, actions)
+
+ // storeData[key] is a reference only (contains only href; no data)
+ } else if (isEntityReference(value)) {
+ this[key] = () => actions.get(value.href)
+
+ // storeData[key] is a templated link
+ } else if (isTemplatedLink(value)) {
+ this[key] = (templateParams) =>
+ actions.get(parseTemplate(value.href).expand(templateParams || {}))
+
+ // storeData[key] is a primitive (normal entity property)
+ } else {
+ this[key] = value
+ }
+ })
+ }
+
+ $href(relation, templateParams = {}) {
+ const rel = this._storeData[relation]
+ if (rel?.templated) {
+ return parseTemplate(rel?.href || '').expand(templateParams)
+ }
+ return rel?.href
+ }
+}
+
+class Collection extends StoreValue {
+ _filterDeleting(array) {
+ return array.filter((entry) => !entry._meta.deleting)
+ }
+
+ _replaceEntityReferences(array) {
+ return array
+ .filter((entry) => isEntityReference(entry))
+ .map((entry) => this._actions.get(entry.href))
+ }
+
+ get items() {
+ return this._filterDeleting(this._replaceEntityReferences(this._storeData.items))
+ }
+
+ get allItems() {
+ return this._replaceEntityReferences(this._storeData.items)
+ }
+}
+
+class EmbeddedCollection extends Collection {
+ constructor(data, actions) {
+ super({ items: data, _meta: { loading: false } }, actions)
+ }
+}
+
+export default wrap
diff --git a/frontend-vue3/src/components/print/print-client/renderPdf.js b/frontend-vue3/src/components/print/print-client/renderPdf.js
new file mode 100644
index 0000000000..b9ee20d80a
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/renderPdf.js
@@ -0,0 +1,30 @@
+import wrap from './minimalHalJsonVuex.js'
+import createI18n from './i18n.js'
+import { render, prepare } from '@/pdf/pdf.js'
+
+export const renderPdf = async ({ config, storeData, translationData }) => {
+ const result = {
+ filename: null,
+ blob: null,
+ error: null,
+ }
+
+ try {
+ const { translate } = createI18n(translationData, storeData.lang.language)
+ const store = wrap(storeData.api)
+
+ if (typeof prepare === 'function') {
+ await prepare(config)
+ }
+
+ config.camp = store.get(config.camp)
+ const props = { config, store, $tc: translate, locale: storeData.lang.language }
+
+ result.filename = config.documentName
+ result.blob = await render(props).toBlob()
+ } catch (error) {
+ result.error = error
+ }
+
+ return result
+}
diff --git a/frontend-vue3/src/components/print/print-client/renderPdf.worker.js b/frontend-vue3/src/components/print/print-client/renderPdf.worker.js
new file mode 100644
index 0000000000..81b11f3df7
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-client/renderPdf.worker.js
@@ -0,0 +1,43 @@
+import * as Sentry from '@sentry/browser'
+import { renderPdf } from './renderPdf.js'
+import dayjs, { dayjsLocaleMap } from '@/common/helpers/dayjs.js'
+
+// Work around an incompatibility between comlink, vite and react-pdf...
+// Comlink works with a globally defined function 'start'. And apparently the way we import
+// react-pdf in our worker registers some of its functions in the global scope, including
+// a 'start' function which @react-pdf/textkit uses internally for processing text strings.
+// When comlink finds this global 'start' function, it calls it without arguments.
+// But the function in react-pdf expects some arguments and will produce the error
+// 'TypeError: attributedString is undefined'
+// So if we detect a call without arguments, we simply ignore that call.
+const originalStart = self.start
+self.start = (...args) => {
+ if (args.length === 0) return
+ return originalStart(...args)
+}
+
+export const renderPdfInWorker = async (data) => {
+ const lang = data?.config?.language
+ if (!lang) {
+ const error = 'language was undefined in react print config'
+ Sentry.captureException(new Error(error))
+ return { error }
+ }
+
+ // We need to set the locale again here. Otherwise dayjs falls back to the default
+ // on production deployments
+ dayjs.locale(Object.keys(dayjsLocaleMap).includes(lang) ? dayjsLocaleMap[lang] : lang)
+
+ const result = { ...(await renderPdf(data)) }
+ if (result.error) {
+ Sentry.captureException(result.error)
+ result.error = `Error in PDF worker code. To get the full stack trace, set RENDER_IN_WORKER to false. Error message was: ${result.error.message}`
+ }
+ return result
+}
+
+if (import.meta.hot) {
+ // Since no file directly imports this file (only via a Worker constructor), we need to tell
+ // vite that it does not have to reload the full page when something changes in the worker.
+ import.meta.hot.accept(() => {})
+}
diff --git a/frontend-vue3/src/components/print/print-nuxt/DownloadNuxtPdfButton.vue b/frontend-vue3/src/components/print/print-nuxt/DownloadNuxtPdfButton.vue
new file mode 100644
index 0000000000..4ea042b9f6
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-nuxt/DownloadNuxtPdfButton.vue
@@ -0,0 +1,19 @@
+
+
+
+ mdi-printer
+
+ {{ $t('components.print.printNuxt.downloadNuxtPdfButton.label') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/print-nuxt/DownloadNuxtPdfListItem.vue b/frontend-vue3/src/components/print/print-nuxt/DownloadNuxtPdfListItem.vue
new file mode 100644
index 0000000000..1b1d39e2e8
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-nuxt/DownloadNuxtPdfListItem.vue
@@ -0,0 +1,20 @@
+
+
+
+ mdi-loading
+ mdi-printer
+
+
+ {{ $t('components.print.printNuxt.downloadNuxtPdfListItem.label') }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/print-nuxt/PrintPreviewNuxt.vue b/frontend-vue3/src/components/print/print-nuxt/PrintPreviewNuxt.vue
new file mode 100644
index 0000000000..779cf0904d
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-nuxt/PrintPreviewNuxt.vue
@@ -0,0 +1,60 @@
+
+
+
+ mdi-open-in-new
+ {{ $t('components.print.printNuxt.printPreviewNuxt.openPreview') }}
+
+
+
+
+
+
+ {{ $t('components.print.printNuxt.printPreviewNuxt.previewError') }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/print/print-nuxt/generatePdfMixin.js b/frontend-vue3/src/components/print/print-nuxt/generatePdfMixin.js
new file mode 100644
index 0000000000..655d02a519
--- /dev/null
+++ b/frontend-vue3/src/components/print/print-nuxt/generatePdfMixin.js
@@ -0,0 +1,68 @@
+import { saveAs } from 'file-saver'
+import slugify from 'slugify'
+import { cloneDeep } from 'lodash'
+import axios from 'axios'
+import { getEnv } from '@/environment.js'
+import * as Sentry from '@sentry/browser'
+
+const PRINT_URL = getEnv().PRINT_URL
+
+export const generatePdfMixin = {
+ props: {
+ config: {
+ type: Object,
+ default: () => {},
+ },
+ },
+ data() {
+ return {
+ loading: false,
+ }
+ },
+ methods: {
+ async generatePdf() {
+ if (this.loading) {
+ return
+ }
+
+ const config = cloneDeep(this.config)
+ config.documentName = slugify(config.documentName, {
+ locale: this.$store.state.lang.language.substring(0, 2),
+ })
+
+ this.loading = true
+
+ try {
+ const response = await axios({
+ baseURL: null,
+ method: 'get',
+ url: `${PRINT_URL}/api/pdf?config=${encodeURIComponent(
+ JSON.stringify(config)
+ )}`,
+ responseType: 'arraybuffer',
+ withCredentials: true,
+ headers: {
+ common: {
+ 'Cache-Control': 'no-cache',
+ Pragma: 'no-cache',
+ Expires: '0',
+ },
+ },
+ })
+
+ saveAs(new Blob([response.data]), config.documentName + '.pdf')
+ } catch (error) {
+ if (error?.response?.status === 503) {
+ this.$toast.error(
+ this.$t('components.print.printNuxt.generatePdfMixin.queueFull')
+ )
+ } else {
+ this.$toast.error(this.$t('components.print.printNuxt.generatePdfMixin.error'))
+ }
+ Sentry.captureException(new Error(error))
+ } finally {
+ this.loading = false
+ }
+ },
+ },
+}
diff --git a/frontend-vue3/src/components/print/repairPrintConfig.js b/frontend-vue3/src/components/print/repairPrintConfig.js
new file mode 100644
index 0000000000..3b90b8fca4
--- /dev/null
+++ b/frontend-vue3/src/components/print/repairPrintConfig.js
@@ -0,0 +1,34 @@
+import cloneDeep from 'lodash/cloneDeep'
+
+export default function repairConfig(
+ config,
+ camp,
+ availableLocales,
+ fallbackLocale,
+ componentRepairers,
+ defaultContents
+) {
+ const configClone = config ? cloneDeep(config) : {}
+ if (!availableLocales.includes(configClone.language)) {
+ configClone.language = availableLocales.includes(fallbackLocale)
+ ? fallbackLocale
+ : availableLocales.length > 0
+ ? availableLocales[0]
+ : 'en'
+ }
+ if (!configClone.documentName) configClone.documentName = camp.name
+ if (configClone.camp !== camp._meta.self) configClone.camp = camp._meta.self
+ if (typeof configClone.contents?.map !== 'function') {
+ configClone.contents = defaultContents
+ }
+ configClone.contents = configClone.contents
+ .map((content) => {
+ if (!content.type || !(content.type in componentRepairers)) return null
+ const componentRepairer = componentRepairers[content.type]
+ if (typeof componentRepairer !== 'function') return content
+ return componentRepairer(content, camp)
+ })
+ .filter((component) => component)
+
+ return configClone
+}
diff --git a/frontend-vue3/src/components/program/DialogActivityCreate.vue b/frontend-vue3/src/components/program/DialogActivityCreate.vue
new file mode 100644
index 0000000000..d6d54edafe
--- /dev/null
+++ b/frontend-vue3/src/components/program/DialogActivityCreate.vue
@@ -0,0 +1,285 @@
+
+
+
+
+
+
+
+
+
+
+ mdi-information-outline
+ {{ $t('components.program.dialogActivityCreate.copyPasteActivity') }}
+
+
+
+
+
+
+
+
+ {{ $t('components.program.dialogActivityCreate.clipboard') }}
+
+
+
+
+ mdi-clipboard-check-outline
+
+
+
+
+ {{ clipboardEntity.title }}
+
+
+ {{ clipboardEntity.camp().title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-content-paste
+
+
+ {{ $t('components.program.dialogActivityCreate.copySourceInfo') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/program/PeriodSwitcher.vue b/frontend-vue3/src/components/program/PeriodSwitcher.vue
new file mode 100644
index 0000000000..09870f90ec
--- /dev/null
+++ b/frontend-vue3/src/components/program/PeriodSwitcher.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+ {{ period.description }}
+
+ mdi-menu-up
+ mdi-menu-down
+
+
+
+ {{ $t('components.program.periodSwitcher.title') }}
+
+
+ {{ item.description }}
+
+ {{ dateRange(item.start, item.end) }}
+
+
+
+
+
+
+
+
+ {{ period.description }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/program/ScheduleEntries.vue b/frontend-vue3/src/components/program/ScheduleEntries.vue
new file mode 100644
index 0000000000..18b2470828
--- /dev/null
+++ b/frontend-vue3/src/components/program/ScheduleEntries.vue
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+ mdi-plus
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/program/ScheduleEntryFilters.vue b/frontend-vue3/src/components/program/ScheduleEntryFilters.vue
new file mode 100644
index 0000000000..3f8af08a5a
--- /dev/null
+++ b/frontend-vue3/src/components/program/ScheduleEntryFilters.vue
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+ {{ categories[item.value].name }}
+
+
+
+
+
+ {{ progressLabels[item.value].title }}
+
+
+
+
+ ​
+ mdi-close
+ {{ $t('components.program.scheduleEntryFilters.clearFilters') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/program/picasso/DayResponsibles.vue b/frontend-vue3/src/components/program/picasso/DayResponsibles.vue
new file mode 100644
index 0000000000..aff1dcab92
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/DayResponsibles.vue
@@ -0,0 +1,206 @@
+
+
+
+
+ {{ $t('entity.day.fields.dayResponsibles') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/program/picasso/Picasso.vue b/frontend-vue3/src/components/program/picasso/Picasso.vue
new file mode 100644
index 0000000000..a36a580269
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/Picasso.vue
@@ -0,0 +1,550 @@
+
+
+
+
+
+
+
+
+
+ {{
+ entryWidth > 140
+ ? $date
+ .utc(date)
+ .format($t('components.program.picasso.picasso.datetime.fullDate'))
+ : $date
+ .utc(date)
+ .format(
+ $t(
+ 'components.program.picasso.picasso.datetime.smallDate',
+ widthPluralization
+ )
+ )
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-loading
+ {{ $t('global.button.saving') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/program/picasso/PicassoEntry.vue b/frontend-vue3/src/components/program/picasso/PicassoEntry.vue
new file mode 100644
index 0000000000..e57736d77e
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/PicassoEntry.vue
@@ -0,0 +1,504 @@
+
+
+
+
+
+ mdi-content-copy
+
+
+
+
+
+
+
+
+ mdi-pencil
+
+
+
+
+
+ {{ activityName }}
+
+
+
+
+
+ {{
+ $t('components.program.picasso.picassoEntry.location')
+ }}
+ {{ location }}
+
+
+
+
+ ·
+
+
+ {{
+ $t('components.program.picasso.picassoEntry.responsible')
+ }} {{ campCollaborationText }}
+
+
+
+
+
+
+
+
+
+ {{ durationText }}
+
+
+
+
+
+
+ {{ activityName }}
+
+
+
+ {{
+ $t('components.program.picasso.picassoEntry.location')
+ }}
+ {{ location }}
+
+
+
+
+ ·
+
+
+ {{
+ $t('components.program.picasso.picassoEntry.responsible')
+ }} {{ campCollaborationText }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/program/picasso/dateHelperVCalendar.js b/frontend-vue3/src/components/program/picasso/dateHelperVCalendar.js
new file mode 100644
index 0000000000..9c478d0b4d
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/dateHelperVCalendar.js
@@ -0,0 +1,13 @@
+import dayjs from '@/common/helpers/dayjs.js'
+
+// converts a timestamp (local timezone) into ISO String format (UTC timezone)
+function timestampToUtcString(timestamp) {
+ return dayjs.utc(dayjs(timestamp).format('YYYY-MM-DD HH:mm')).format()
+}
+
+// converts ISO String format (UTC timezone) into a timestamp (local timezone)
+function utcStringToTimestamp(string) {
+ return dayjs(dayjs.utc(string).format('YYYY-MM-DD HH:mm')).valueOf()
+}
+
+export { timestampToUtcString, utcStringToTimestamp }
diff --git a/frontend-vue3/src/components/program/picasso/useClickDetector.js b/frontend-vue3/src/components/program/picasso/useClickDetector.js
new file mode 100644
index 0000000000..ec25a21f00
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/useClickDetector.js
@@ -0,0 +1,93 @@
+/**
+ *
+ * @param enabled {Ref} false disables click detection
+ * @param threshold {number} max. mouse movement to still detect as a click
+ * @param onClick {() => void} run function on click
+ * @returns
+ */
+export function useClickDetector(enabled, threshold = 5, onClick = null) {
+ /**
+ * internal data (not exposed)
+ */
+
+ // coordinates of mouse down event
+ let startX = null
+ let startY = null
+
+ /**
+ * internal methods
+ */
+ function cancelClick() {
+ startX = null
+ startY = null
+ }
+
+ // returns true if still within defined threshold
+ function withinThreshold(nativeEvent) {
+ return (
+ Math.abs(nativeEvent.x - startX) < threshold &&
+ Math.abs(nativeEvent.y - startY) < threshold
+ )
+ }
+
+ /**
+ * exposed methods
+ */
+ const entryMouseDown = (nativeEvent) => {
+ if (!enabled.value) {
+ return
+ }
+
+ startX = nativeEvent.x
+ startY = nativeEvent.y
+ }
+
+ const entryMouseMove = (nativeEvent) => {
+ if (startX === null) {
+ return
+ }
+
+ if (!withinThreshold(nativeEvent)) {
+ // abort click if movement is larger than threshold
+ cancelClick()
+ }
+ }
+
+ const entryMouseUp = (nativeEvent) => {
+ if (startX === null) {
+ return
+ }
+
+ if (!withinThreshold(nativeEvent)) {
+ cancelClick()
+ return
+ }
+
+ // Click middle button opens new tab
+ if (nativeEvent.button === 1) {
+ // emit('openEntry', event, true)
+ } else if (nativeEvent.button === 0) {
+ // Left click while holding cmd/ctrl opens new tab
+ if (nativeEvent.metaKey || nativeEvent.ctrlKey) {
+ // emit('openEntry', event, true)
+ } else {
+ // emit('openEntry', event, false)
+ }
+
+ // onClick callback
+ if (onClick !== null) {
+ onClick()
+ }
+ }
+
+ cancelClick()
+ }
+
+ return {
+ listeners: {
+ mousedown: entryMouseDown,
+ mousemove: entryMouseMove,
+ mouseup: entryMouseUp,
+ },
+ }
+}
diff --git a/frontend-vue3/src/components/program/picasso/useDragAndDropMove.js b/frontend-vue3/src/components/program/picasso/useDragAndDropMove.js
new file mode 100644
index 0000000000..e81df0ee5c
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/useDragAndDropMove.js
@@ -0,0 +1,170 @@
+import { toTime, roundTimeToNearestQuarterHour } from '@/helpers/vCalendarDragAndDrop.js'
+
+/**
+ * @param enabled {Ref} drag & drop is disabled if enabled=false
+ * @param threshold {number} min. mouse movement needed to detect drag & drop
+ * @param update {(scheduleEntry: object, startTime: number, endTime: number) => void} callback for update actions
+ * @param minTimestamp {Ref} minimum allowed start timestamp (calendar start)
+ * @param maxTimestamp {Ref} maximum allowed end timestamp (calendar end)
+ * @returns
+ */
+export function useDragAndDropMove(
+ enabled,
+ threshold,
+ update,
+ minTimestamp,
+ maxTimestamp
+) {
+ /**
+ * internal data (not exposed)
+ */
+
+ // reference to dragged scheduleEntry (null = no drag & drop ongoing)
+ let draggedEntry = null
+
+ // time offset between (dragged) entry startTimestamp and mouse location
+ let mouseOffset = null
+
+ // coordinates of mouse down event
+ let startX = null
+ let startY = null
+
+ // true while drag & drop action is ongoing (after mouse has moved more than threshold)
+ let dragging = false
+
+ /**
+ * internal methods
+ */
+
+ // returns true if still within defined threshold
+ function withinThreshold(nativeEvent) {
+ return (
+ Math.abs(nativeEvent.x - startX) < threshold &&
+ Math.abs(nativeEvent.y - startY) < threshold
+ )
+ }
+
+ // move an existing entry
+ const moveEntry = (mouse) => {
+ const start = draggedEntry.startTimestamp
+ const end = draggedEntry.endTimestamp
+ const duration = end - start
+
+ const newStart = roundTimeToNearestQuarterHour(mouse - mouseOffset)
+ const newEnd = newStart + duration
+
+ const isWithinBounds = newStart >= minTimestamp.value && newEnd <= maxTimestamp.value
+ if (isWithinBounds) {
+ draggedEntry.startTimestamp = newStart
+ draggedEntry.endTimestamp = newEnd
+ }
+ draggedEntry.isMoving = true
+ }
+
+ const clear = () => {
+ if (draggedEntry) {
+ draggedEntry.isMoving = false
+ }
+
+ mouseOffset = null
+ draggedEntry = null
+ startX = null
+ startY = null
+ dragging = false
+ }
+
+ /**
+ * exposed methods
+ */
+
+ // triggered with MouseDown event on a calendar entry
+ const entryMouseDown = ({ event: entry, timed, nativeEvent }) => {
+ if (!enabled.value) {
+ return
+ }
+
+ // cancel drag & drop if button is not left button
+ if (nativeEvent.button !== 0) {
+ return
+ }
+
+ // only move timed events and non-filtered entries
+ if (!entry || !timed || !entry.filterMatch) {
+ return
+ }
+
+ // start Drag & Drop
+ startX = nativeEvent.x
+ startY = nativeEvent.y
+ draggedEntry = entry
+ mouseOffset = null // not know yet: will be populated by timeMouseDown event
+ }
+
+ // triggered with MouseDown event anywhere on the calendar (independent of clicking on entry or not)
+ const timeMouseDown = (tms, nativeEvent) => {
+ if (!enabled.value) {
+ return
+ }
+
+ // cancel drag & drop if button is not left button
+ if (nativeEvent.button !== 0) {
+ return
+ }
+
+ // Drag has just started on an entry ('mousedown:event' was detected before)
+ if (draggedEntry) {
+ const mouseTime = toTime(tms)
+ const startTimestamp = draggedEntry.startTimestamp
+ mouseOffset = mouseTime - startTimestamp
+ }
+ }
+
+ // triggered when mouse is being moved in calendar (independent whether drag & drop is ongoing or not)
+ const timeMouseMove = (tms, nativeEvent) => {
+ if (!enabled.value) {
+ return
+ }
+
+ const mouse = toTime(tms)
+
+ if (draggedEntry) {
+ // don't move if still within threshold
+ if (withinThreshold(nativeEvent)) {
+ return
+ }
+
+ // move existing
+ dragging = true
+ moveEntry(mouse)
+ }
+ }
+
+ // triggered with MouseUp Event anywhere in the calendar
+ const timeMouseUp = () => {
+ if (!enabled.value) {
+ return
+ }
+
+ // trigger update callback
+ if (dragging) {
+ update(draggedEntry, draggedEntry.startTimestamp, draggedEntry.endTimestamp)
+ }
+
+ clear()
+ }
+
+ // treat mouseleave as a mouseUp event (finish operation and save last known status)
+ const nativeMouseLeave = () => {
+ timeMouseUp()
+ }
+
+ return {
+ vCalendarListeners: {
+ 'mousedown:event': entryMouseDown,
+ 'mousedown:time': timeMouseDown,
+ 'mousemove:time': timeMouseMove,
+ 'mouseup:time': timeMouseUp,
+ },
+ nativeMouseLeave,
+ }
+}
diff --git a/frontend-vue3/src/components/program/picasso/useDragAndDropNew.js b/frontend-vue3/src/components/program/picasso/useDragAndDropNew.js
new file mode 100644
index 0000000000..8b1ce7b3d0
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/useDragAndDropNew.js
@@ -0,0 +1,141 @@
+import { toTime, roundTimeToNearestQuarterHour } from '@/helpers/vCalendarDragAndDrop.js'
+
+/**
+ *
+ * @param enabled {Ref} drag & drop is disabled if enabled=false
+ * @param updatePlaceholder {(startTime:number, endTime:number) => void}
+ * @param createEntry {(startTime:number, endTime:number) => void}
+ * @returns
+ */
+export function useDragAndDropNew(enabled, updatePlaceholder, createEntry) {
+ /**
+ * internal data (not exposed)
+ */
+
+ // timestamp of mouse location when drag & drop event started
+ let mouseStartTimestamp = null
+
+ // temporary placeholder for new schedule entry, when created via drag & drop
+ let newEntry = null
+
+ // true if mousedown event was detected on an entry/event
+ let entryWasClicked = false
+
+ /**
+ * internal methods
+ */
+
+ const clear = () => {
+ newEntry = null
+ mouseStartTimestamp = null
+ entryWasClicked = false
+ updatePlaceholder(0, 0)
+ }
+
+ // this creates a placeholder for a new schedule entry and make it resizable
+ const startDragOperation = (time) => {
+ newEntry = {
+ startTimestamp: time,
+ endTimestamp: time,
+ }
+ }
+
+ // resize placeholder entry
+ const resizeEntry = (entry, mouse) => {
+ const dragStart = mouseStartTimestamp
+ const dragEnd = roundTimeToNearestQuarterHour(mouse)
+
+ const minTimestamp = Math.min(dragStart, dragEnd)
+ const maxTimestamp = Math.max(dragStart, dragEnd)
+
+ if (minTimestamp !== maxTimestamp) {
+ entry.startTimestamp = minTimestamp
+ entry.endTimestamp = maxTimestamp
+ }
+ }
+
+ /**
+ * exposed methods
+ */
+
+ // triggered with MouseDown event on a calendar entry
+ const entryMouseDown = ({ event: entry, timed, nativeEvent }) => {
+ if (!enabled.value) {
+ return
+ }
+
+ // cancel drag & drop if button is not left button
+ if (nativeEvent.button !== 0) {
+ return
+ }
+
+ if (entry && timed) {
+ entryWasClicked = true
+ }
+ }
+
+ // triggered with MouseDown event anywhere on the calendar (independent of clicking on entry or not)
+ const timeMouseDown = (tms, nativeEvent) => {
+ if (!enabled.value) {
+ return
+ }
+
+ // cancel drag & drop if button is not left button
+ if (nativeEvent.button !== 0) {
+ return
+ }
+
+ if (!entryWasClicked) {
+ // No entry is being dragged --> create a placeholder for a new schedule entry
+ const mouseTime = toTime(tms)
+ mouseStartTimestamp = roundTimeToNearestQuarterHour(mouseTime)
+ startDragOperation(mouseStartTimestamp)
+ }
+ }
+
+ // triggered when mouse is being moved in calendar (independent whether drag & drop is ongoing or not)
+ const timeMouseMove = (tms) => {
+ if (!enabled.value) {
+ return
+ }
+
+ if (newEntry) {
+ // resize placeholder
+ const mouseTime = toTime(tms)
+ resizeEntry(newEntry, mouseTime)
+
+ if (newEntry.endTimestamp - newEntry.startTimestamp > 0) {
+ updatePlaceholder(newEntry.startTimestamp, newEntry.endTimestamp)
+ }
+ }
+ }
+
+ // triggered with MouseUp Event anywhere in the calendar
+ const timeMouseUp = () => {
+ if (!enabled.value) {
+ return
+ }
+
+ if (newEntry && newEntry.endTimestamp - newEntry.startTimestamp > 0) {
+ // placeholder for new schedule entry was created --> open dialog to create new activity
+ createEntry(newEntry.startTimestamp, newEntry.endTimestamp)
+ }
+
+ clear()
+ }
+
+ // treat mouseleave as a mouseUp event (finish operation and save last known status)
+ const nativeMouseLeave = () => {
+ timeMouseUp()
+ }
+
+ return {
+ vCalendarListeners: {
+ 'mousedown:event': entryMouseDown,
+ 'mousedown:time': timeMouseDown,
+ 'mousemove:time': timeMouseMove,
+ 'mouseup:time': timeMouseUp,
+ },
+ nativeMouseLeave,
+ }
+}
diff --git a/frontend-vue3/src/components/program/picasso/useDragAndDropReminder.js b/frontend-vue3/src/components/program/picasso/useDragAndDropReminder.js
new file mode 100644
index 0000000000..afe3a6c270
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/useDragAndDropReminder.js
@@ -0,0 +1,94 @@
+import { toTime, ONE_HOUR_IN_MILLISECONDS } from '@/helpers/vCalendarDragAndDrop.js'
+
+/**
+ *
+ * @param enabled {Ref} drag & drop is disabled if enabled=false
+ * @param showReminder {(move?: boolean) => void} function to show the reminder
+ * @returns
+ */
+export function useDragAndDropReminder(enabled, showReminder) {
+ /**
+ * internal data (not exposed)
+ */
+
+ // temporary placeholder for new schedule entry, when created via drag & drop
+ let mouseStartTimestamp = null
+
+ // true if mousedown event was detected on an entry/event
+ let entryWasClicked = false
+
+ /**
+ * internal methods
+ */
+
+ const clear = () => {
+ mouseStartTimestamp = null
+ entryWasClicked = false
+ }
+
+ /**
+ * exposed methods
+ */
+
+ // triggered with MouseDown event on a calendar entry
+ const entryMouseDown = ({ event: entry, timed, nativeEvent }) => {
+ if (enabled.value) {
+ return
+ }
+
+ // cancel drag & drop if button is not left button
+ if (nativeEvent.button !== 0) {
+ return
+ }
+
+ if (entry && timed) {
+ entryWasClicked = true
+ }
+ }
+
+ // triggered with MouseDown event anywhere on the calendar (independent of clicking on entry or not)
+ const timeMouseDown = (tms, nativeEvent) => {
+ if (enabled.value) {
+ return
+ }
+
+ // cancel drag & drop if button is not left button
+ if (nativeEvent.button !== 0) {
+ return
+ }
+
+ mouseStartTimestamp = toTime(tms)
+ }
+
+ // triggered when mouse is being moved in calendar (independent whether drag & drop is ongoing or not)
+ const timeMouseMove = (tms) => {
+ if (enabled.value || mouseStartTimestamp == null) {
+ return
+ }
+
+ const mouseMoveDistance = Math.abs(toTime(tms) - mouseStartTimestamp)
+
+ if (mouseMoveDistance >= ONE_HOUR_IN_MILLISECONDS) {
+ showReminder(entryWasClicked)
+ }
+ }
+
+ // triggered with MouseUp Event anywhere in the calendar
+ const timeMouseUp = () => {
+ if (enabled.value) {
+ return
+ }
+
+ clear()
+ }
+
+ return {
+ vCalendarListeners: {
+ 'mousedown:event': entryMouseDown,
+ 'mousedown:time': timeMouseDown,
+ 'mousemove:time': timeMouseMove,
+ 'mouseup:time': timeMouseUp,
+ },
+ nativeMouseLeave: clear,
+ }
+}
diff --git a/frontend-vue3/src/components/program/picasso/useDragAndDropResize.js b/frontend-vue3/src/components/program/picasso/useDragAndDropResize.js
new file mode 100644
index 0000000000..b7a8edba73
--- /dev/null
+++ b/frontend-vue3/src/components/program/picasso/useDragAndDropResize.js
@@ -0,0 +1,100 @@
+import { toTime, roundTimeUpToNextQuarterHour } from '@/helpers/vCalendarDragAndDrop.js'
+
+/**
+ *
+ * @param enabled {Ref} drag & drop is disabled if enabled=false
+ * @param update {(scheduleEntry: object, startTime: number, endTime: number) => void} callback for update actions
+ * @param maxTimestamp {Ref} maximum allowed end timestamp (calendar end)
+ * @returns
+ */
+export function useDragAndDropResize(enabled, update, maxTimestamp) {
+ /**
+ * internal data (not exposed)
+ */
+
+ // existing entry that is being resized
+ let resizedEntry = null
+
+ // original end time of entry which is being resized
+ let originalEndTimestamp = null
+
+ /**
+ * internal methods
+ */
+
+ // resize an entry (existing or new placeholder)
+ const resizeEntry = (entry, mouse) => {
+ const newEndTimestamp = roundTimeUpToNextQuarterHour(mouse)
+
+ if (
+ newEndTimestamp <= maxTimestamp.value &&
+ newEndTimestamp - entry.startTimestamp > 0
+ ) {
+ // TODO review: Here we're changing the store value directly.
+ entry.endTimestamp = newEndTimestamp
+ }
+
+ entry.isResizing = true
+ }
+
+ const clear = () => {
+ if (resizedEntry) {
+ resizedEntry.isResizing = false
+ }
+
+ resizedEntry = null
+ originalEndTimestamp = null
+ }
+
+ /**
+ * exposed methods
+ */
+
+ // triggered when mouse is being moved in calendar (independent whether drag & drop is ongoing or not)
+ const timeMouseMove = (tms) => {
+ if (!enabled.value) {
+ return
+ }
+
+ if (resizedEntry) {
+ const mouseTime = toTime(tms)
+ resizeEntry(resizedEntry, mouseTime)
+ }
+ }
+
+ // triggered with MouseUp Event anywhere in the calendar
+ const timeMouseUp = () => {
+ if (!enabled.value) {
+ return
+ }
+
+ if (resizedEntry && resizedEntry.endTimestamp !== originalEndTimestamp) {
+ // existing entry was resized --> save to API
+ update(resizedEntry, resizedEntry.startTimestamp, resizedEntry.endTimestamp)
+ }
+
+ clear()
+ }
+
+ // treat mouseleave as a mouseUp event (finish operation and save last known status)
+ const nativeMouseLeave = () => {
+ timeMouseUp()
+ }
+
+ // start resize operation (needs to be called manually from resize handle)
+ const startResize = (event) => {
+ if (!event.filterMatch) return
+
+ resizedEntry = event
+ originalEndTimestamp = event.endTimestamp
+ }
+
+ return {
+ vCalendarListeners: {
+ 'mousemove:time': timeMouseMove,
+ 'mouseup:time': timeMouseUp,
+ },
+ nativeMouseLeave,
+ startResize,
+ }
+}
diff --git a/frontend-vue3/src/components/prompt/PopoverPrompt.vue b/frontend-vue3/src/components/prompt/PopoverPrompt.vue
new file mode 100644
index 0000000000..8b13ec1d0a
--- /dev/null
+++ b/frontend-vue3/src/components/prompt/PopoverPrompt.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ cancelLabel }}
+
+
+
+ {{ submitIcon }}
+
+ {{ submitLabel }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/prompt/PromptEntityDelete.vue b/frontend-vue3/src/components/prompt/PromptEntityDelete.vue
new file mode 100644
index 0000000000..ff752c2d65
--- /dev/null
+++ b/frontend-vue3/src/components/prompt/PromptEntityDelete.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+ {{
+ $t('global.warning.delete', warningTextEntity ? 2 : 0, {
+ entity: warningTextEntity,
+ })
+ }}
+
+
+
+
+ {{ error }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/story/StoryDay.vue b/frontend-vue3/src/components/story/StoryDay.vue
new file mode 100644
index 0000000000..13d0d56dad
--- /dev/null
+++ b/frontend-vue3/src/components/story/StoryDay.vue
@@ -0,0 +1,136 @@
+
+
+
+ {{ dateLong(day.start) }}
+
+
+
+
+
+
+
+ {{
+ scheduleEntry.number
+ }}
+
+
+
+ {{ scheduleEntry.activity().title }}
+
+ - {{ chapter.instanceName }}
+
+
+
+
+
+
+
+
+
+
+ {{ $t('components.story.storyDay.noStory') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/story/StoryPeriod.vue b/frontend-vue3/src/components/story/StoryPeriod.vue
new file mode 100644
index 0000000000..b900bf11ce
--- /dev/null
+++ b/frontend-vue3/src/components/story/StoryPeriod.vue
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/toast/MultiLineToast.vue b/frontend-vue3/src/components/toast/MultiLineToast.vue
new file mode 100644
index 0000000000..63e708206a
--- /dev/null
+++ b/frontend-vue3/src/components/toast/MultiLineToast.vue
@@ -0,0 +1,35 @@
+
+
+ {{ generalErrorText }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/components/toast/toasts.js b/frontend-vue3/src/components/toast/toasts.js
new file mode 100644
index 0000000000..e4a79b6db6
--- /dev/null
+++ b/frontend-vue3/src/components/toast/toasts.js
@@ -0,0 +1,19 @@
+import MultiLineToast from '@/components/toast/MultiLineToast.vue'
+import i18n from '@/plugins/i18n'
+import { violationsToFlatArray } from '@/helpers/serverError'
+
+function multiLineToast(lines) {
+ return {
+ component: MultiLineToast,
+ props: {
+ lines,
+ generalErrorText: i18n.t('components.toast.toasts.multiLineToast.generalError'),
+ },
+ }
+}
+
+function errorToMultiLineToast(error) {
+ return multiLineToast(violationsToFlatArray(error, i18n))
+}
+
+export { errorToMultiLineToast, multiLineToast }
diff --git a/frontend-vue3/src/components/user/DialogChangeMail.vue b/frontend-vue3/src/components/user/DialogChangeMail.vue
new file mode 100644
index 0000000000..d580d35257
--- /dev/null
+++ b/frontend-vue3/src/components/user/DialogChangeMail.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+ {{ $t('components.user.dialogChangeMail.message') }}
+
+
+
+ {{ $t('components.user.dialogChangeMail.success') }}
+
+
+ {{ $t('components.user.dialogChangeMail.error') }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/user/DialogChangeMailRunning.vue b/frontend-vue3/src/components/user/DialogChangeMailRunning.vue
new file mode 100644
index 0000000000..68f0463ffd
--- /dev/null
+++ b/frontend-vue3/src/components/user/DialogChangeMailRunning.vue
@@ -0,0 +1,66 @@
+
+
+
+
+ {{ $t('components.user.dialogChangeMailRunning.message') }}
+
+
+ mdi mdi-check
+ {{ $t('components.user.dialogChangeMailRunning.success') }}
+
+
+ {{ $t('components.user.dialogChangeMailRunning.error') }}
+
+
+
+
+
diff --git a/frontend-vue3/src/components/user/UserAvatar.vue b/frontend-vue3/src/components/user/UserAvatar.vue
new file mode 100644
index 0000000000..8ef6af9037
--- /dev/null
+++ b/frontend-vue3/src/components/user/UserAvatar.vue
@@ -0,0 +1,75 @@
+
+
+ {{ initials }}
+ {{ displayName }}
+
+
+
diff --git a/frontend-vue3/src/environment.js b/frontend-vue3/src/environment.js
new file mode 100644
index 0000000000..9a41917e2b
--- /dev/null
+++ b/frontend-vue3/src/environment.js
@@ -0,0 +1,27 @@
+export function getEnv() {
+ if (window.environment) {
+ return window.environment
+ }
+ // you can overwrite the env variables locally in frontend/env.local
+ // @see https://vitejs.dev/guide/env-and-mode.html
+ const env = import.meta.env
+ return {
+ API_ROOT_URL: env.VITE_API_ROOT_URL ?? '/api',
+ COOKIE_PREFIX: env.VITE_COOKIE_PREFIX ?? 'localhost_',
+ PRINT_URL: env.VITE_PRINT_URL ?? '/print',
+ SENTRY_FRONTEND_DSN: env.VITE_SENTRY_FRONTEND_DSN,
+ SENTRY_ENVIRONMENT: env.VITE_SENTRY_ENVIRONMENT ?? 'local',
+ DEPLOYMENT_TIME: env.VITE_DEPLOYMENT_TIME ?? '',
+ VERSION: env.VITE_VERSION ?? '',
+ VERSION_LINK_TEMPLATE:
+ env.VITE_VERSION_LINK_TEMPLATE ??
+ 'https://github.com/ecamp/ecamp3/commit/{version}',
+ TERMS_OF_SERVICE_LINK_TEMPLATE:
+ env.TERMS_OF_SERVICE_LINK_TEMPLATE ?? 'https://ecamp3.ch/{lang}/tos',
+ NEWS_LINK: env.NEWS_LINK ?? 'https://ecamp3.ch/blog',
+ HELP_LINK: env.HELP_LINK ?? 'https://ecamp3.ch/faq',
+ FEATURE_DEVELOPER: (env.VITE_FEATURE_DEVELOPER ?? 'true') === 'true',
+ FEATURE_CHECKLIST: (env.VITE_FEATURE_CHECKLIST ?? 'true') === 'true',
+ LOGIN_INFO_TEXT_KEY: env.VITE_LOGIN_INFO_TEXT_KEY ?? 'dev',
+ }
+}
diff --git a/frontend-vue3/src/helpers/__tests__/querySyncHelper.spec.js b/frontend-vue3/src/helpers/__tests__/querySyncHelper.spec.js
new file mode 100644
index 0000000000..8157cb23be
--- /dev/null
+++ b/frontend-vue3/src/helpers/__tests__/querySyncHelper.spec.js
@@ -0,0 +1,230 @@
+import { describe, expect, it } from 'vitest'
+import {
+ halUriToId,
+ idToHalUri,
+ processRouteQuery,
+ transformQueryParam,
+ transformValuesToHalId,
+} from '@/helpers/querySyncHelper'
+
+describe('querySyncHelper', () => {
+ describe('halUriToId', () => {
+ it.each([
+ ['/camp_collaborations/73558f9c6483', '73558f9c6483'],
+ ['/camp_collaborations/fe6557a4b89f', 'fe6557a4b89f'],
+ ['/categories/3a54634a4', '3a54634a4'],
+ ['/activity_progress_labels/456sfs56sus', '456sfs56sus'],
+ ['/periods/45sz56sz5z6', '45sz56sz5z6'],
+ ['/categories/56sf5654t', '56sf5654t'],
+ ['/periods/65klsdfg59', '65klsdfg59'],
+ ['/categories/se456sfs6df6', 'se456sfs6df6'],
+ ['/camp_collaborations/sd6fh45z5', 'sd6fh45z5'],
+ ['/categories/6s567t7k7i9k', '6s567t7k7i9k'],
+ ['/periods/d453atz67', 'd453atz67'],
+ ['/camp_collaborations/9234hn45asd850345', '9234hn45asd850345'],
+ ['/activity_progress_labels/54s6sdf6f', '54s6sdf6f'],
+ ['/periods/548dt6456', '548dt6456'],
+ ['/activity_progress_labels/345fgbthsdt4', '345fgbthsdt4'],
+ ])('should transform %p to %p', (input, expected) => {
+ const result = halUriToId(input)
+
+ expect(result).toEqual(expected)
+ })
+ })
+ describe('idToHalUri', () => {
+ it.each([
+ [['camp_collaborations', '73558f9c6483'], '/camp_collaborations/73558f9c6483'],
+ [['camp_collaborations', 'fe6557a4b89f'], '/camp_collaborations/fe6557a4b89f'],
+ [['categories', '3a54634a4'], '/categories/3a54634a4'],
+ [
+ ['activity_progress_labels', '456sfs56sus'],
+ '/activity_progress_labels/456sfs56sus',
+ ],
+ [['periods', '45sz56sz5z6'], '/periods/45sz56sz5z6'],
+ [['categories', '56sf5654t'], '/categories/56sf5654t'],
+ ])('should transform %p to %p', (input, expected) => {
+ const result = idToHalUri(...input)
+
+ expect(result).toEqual(expected)
+ })
+ })
+ describe('transformQueryParam', () => {
+ it.each([
+ [
+ ['responsible', ['73558f9c6483', 'fe6557a4b89f'], 'camp_collaborations'],
+ [
+ 'responsible',
+ ['/camp_collaborations/73558f9c6483', '/camp_collaborations/fe6557a4b89f'],
+ ],
+ ],
+ [
+ ['period', '73558f9c6483', 'periods'],
+ ['period', '/periods/73558f9c6483'],
+ ],
+ [
+ ['category', ['73558f9c6483', 'fe6557a4b89f'], 'categories'],
+ ['category', ['/categories/73558f9c6483', '/categories/fe6557a4b89f']],
+ ],
+ [
+ ['progressLabels', ['73558f9c6483', 'fe6557a4b89f'], 'activity_progress_labels'],
+ [
+ 'progressLabels',
+ [
+ '/activity_progress_labels/73558f9c6483',
+ '/activity_progress_labels/fe6557a4b89f',
+ ],
+ ],
+ ],
+ [
+ ['responsible', ['73558f9c6483', 'fe6557a4b89f'], 'camp_collaborations'],
+ [
+ 'responsible',
+ ['/camp_collaborations/73558f9c6483', '/camp_collaborations/fe6557a4b89f'],
+ ],
+ ],
+ [
+ ['category', ['73558f9c6483', 'fe6557a4b89f'], 'categories'],
+ ['category', ['/categories/73558f9c6483', '/categories/fe6557a4b89f']],
+ ],
+ [
+ ['progressLabels', ['73558f9c6483', 'fe6557a4b89f'], 'activity_progress_labels'],
+ [
+ 'progressLabels',
+ [
+ '/activity_progress_labels/73558f9c6483',
+ '/activity_progress_labels/fe6557a4b89f',
+ ],
+ ],
+ ],
+ [
+ ['responsible', ['73558f9c6483', 'fe6557a4b89f'], 'camp_collaborations'],
+ [
+ 'responsible',
+ ['/camp_collaborations/73558f9c6483', '/camp_collaborations/fe6557a4b89f'],
+ ],
+ ],
+ [
+ ['period', 'fe6557a4b89f', 'periods'],
+ ['period', '/periods/fe6557a4b89f'],
+ ],
+ [
+ ['responsible', null, 'camp_collaborations'],
+ ['responsible', null],
+ ],
+ ])('should transform %p to %p', (input, expected) => {
+ const result = transformQueryParam(...input)
+
+ expect(result).toEqual(expected)
+ })
+ })
+ describe('processRouteQuery', () => {
+ it.each([
+ [
+ {
+ category: ['505e3fdf9e90', 'a47a60594096'],
+ },
+ {
+ category: ['/categories/505e3fdf9e90', '/categories/a47a60594096'],
+ },
+ ],
+ [
+ {
+ category: ['34az4a5a'],
+ },
+ {
+ category: ['/categories/34az4a5a'],
+ },
+ ],
+ [
+ {
+ progressLabel: ['34az4a5a'],
+ },
+ {
+ progressLabel: ['/activity_progress_labels/34az4a5a'],
+ },
+ ],
+ [
+ {
+ period: '34az4a5a',
+ },
+ {
+ period: '/periods/34az4a5a',
+ },
+ ],
+ [
+ {
+ category: ['505e3fdf9e90', 'a47a60594096'],
+ responsible: ['3a5azag84', 'a5aaf4a5', '5asd5as5', 'ad45a45ag'],
+ },
+ {
+ category: ['/categories/505e3fdf9e90', '/categories/a47a60594096'],
+ responsible: [
+ '/camp_collaborations/3a5azag84',
+ '/camp_collaborations/a5aaf4a5',
+ '/camp_collaborations/5asd5as5',
+ '/camp_collaborations/ad45a45ag',
+ ],
+ },
+ ],
+ ])('should transform %p to %p', (input, expected) => {
+ const result = processRouteQuery(input)
+
+ expect(result).toEqual(expected)
+ })
+ })
+ describe('transformValuesToHalId', () => {
+ it.each([
+ [
+ {
+ category: ['/categories/505e3fdf9e90', '/categories/a47a60594096'],
+ },
+ {
+ category: ['505e3fdf9e90', 'a47a60594096'],
+ },
+ ],
+ [
+ {
+ category: ['/categories/34az4a5a'],
+ },
+ {
+ category: ['34az4a5a'],
+ },
+ ],
+ [
+ {
+ progressLabel: ['/activity_progress_labels/34az4a5a'],
+ },
+ {
+ progressLabel: ['34az4a5a'],
+ },
+ ],
+ [
+ {
+ period: '/periods/34az4a5a',
+ },
+ {
+ period: '34az4a5a',
+ },
+ ],
+ [
+ {
+ category: ['/categories/505e3fdf9e90', '/categories/a47a60594096'],
+ responsible: [
+ '/camp_collaborations/3a5azag84',
+ '/camp_collaborations/a5aaf4a5',
+ '/camp_collaborations/5asd5as5',
+ '/camp_collaborations/ad45a45ag',
+ ],
+ },
+ {
+ category: ['505e3fdf9e90', 'a47a60594096'],
+ responsible: ['3a5azag84', 'a5aaf4a5', '5asd5as5', 'ad45a45ag'],
+ },
+ ],
+ ])('should transform %p to %p', (input, expected) => {
+ const result = transformValuesToHalId(input)
+
+ expect(result).toEqual(expected)
+ })
+ })
+})
diff --git a/frontend-vue3/src/helpers/__tests__/serverError.spec.js b/frontend-vue3/src/helpers/__tests__/serverError.spec.js
new file mode 100644
index 0000000000..3eb35dc6d5
--- /dev/null
+++ b/frontend-vue3/src/helpers/__tests__/serverError.spec.js
@@ -0,0 +1,225 @@
+import { describe, beforeEach, vi, expect, it } from 'vitest'
+import { transformViolations } from '@/helpers/serverError'
+import cloneDeep from 'lodash-es/cloneDeep'
+import { fallbackLocales } from '@/plugins/i18n'
+
+const fallbackLocale = fallbackLocales.default
+
+describe('transformViolations', () => {
+ describe('without i18n', () => {
+ it('returns server errors as 0 property of object', () => {
+ expect(transformViolations(unauthorizedError)).toEqual({ 0: 'Unauthorized' })
+ })
+
+ it('returns a map of propertyPath => violations[]', () => {
+ const validationError = createValidationError()
+ .withViolation({
+ message: 'first message',
+ propertyPath: 'parent.property',
+ })
+ .withViolation({
+ message: 'second message',
+ propertyPath: 'parent.property',
+ })
+ .withViolation({
+ message: 'third message',
+ propertyPath: 'property2',
+ })
+ .build()
+ expect(transformViolations(validationError)).toEqual({
+ 'parent.property': ['first message', 'second message'],
+ property2: ['third message'],
+ })
+ })
+ })
+
+ describe('with i18n', () => {
+ const te = vi.fn()
+ const tc = vi.fn()
+ const i18n = { te, tc }
+
+ beforeEach(() => {
+ delete i18n.locale
+ te.mockReset()
+ tc.mockReset()
+ })
+
+ describe('still uses the message property of violations', () => {
+ it('if the locale is null and translation does not exist', () => {
+ const validationError = createValidationError()
+ .withViolation({
+ message: 'first message',
+ propertyPath: 'property',
+ i18n: {
+ key: 'not.exists',
+ },
+ })
+ .build()
+ expect(transformViolations(validationError, i18n)).toEqual({
+ property: ['first message'],
+ })
+ })
+
+ it('if the translation for the locale is not in the response and translation does not exist', () => {
+ i18n.locale = 'it'
+ const validationError = createValidationError()
+ .withViolation({
+ message: 'first message',
+ propertyPath: 'property',
+ i18n: {
+ key: 'not.exists',
+ translations: {
+ fr: 'will not be used',
+ },
+ },
+ })
+ .build()
+ expect(transformViolations(validationError, i18n)).toEqual({
+ property: ['first message'],
+ })
+ })
+ })
+
+ describe('uses the frontend translation', () => {
+ it('if the key is available in the translations', () => {
+ const validationError = createValidationError()
+ .withViolation({
+ message: 'first message',
+ propertyPath: 'property',
+ i18n: {
+ key: 'key.exists',
+ translations: {
+ fr: 'will not be used',
+ },
+ },
+ })
+ .build()
+ te.mockReturnValue(true)
+ const translation = 'a translation'
+ tc.mockReturnValue(translation)
+
+ expect(transformViolations(validationError, i18n)).toEqual({
+ property: [translation],
+ })
+ })
+
+ it('even if there are translations in the response', () => {
+ const validationError = createValidationError()
+ .withViolation({
+ message: 'first message',
+ propertyPath: 'property',
+ i18n: {
+ key: 'key.exists',
+ translations: {
+ en: 'will not be used',
+ },
+ },
+ })
+ .build()
+ te.mockReturnValue(true)
+ const translation = 'a translation'
+ tc.mockReturnValue(translation)
+ i18n.locale = 'en'
+
+ expect(transformViolations(validationError, i18n)).toEqual({
+ property: [translation],
+ })
+ })
+ })
+
+ describe('uses the translations in the response', () => {
+ it(' if the keys are not known in the frontend', () => {
+ const validationError = createValidationError()
+ .withViolation({
+ message: 'first message',
+ propertyPath: 'property',
+ i18n: {
+ key: 'not.exists',
+ translations: {
+ fr_CH_scout: 'fr_CH_scout',
+ },
+ },
+ })
+ .build()
+ te.mockReturnValue(false)
+ i18n.locale = 'fr-CH-scout'
+
+ expect(transformViolations(validationError, i18n)).toEqual({
+ property: ['fr_CH_scout'],
+ })
+ })
+
+ it('uses the direct fallback', () => {
+ const validationError = createValidationError()
+ .withViolation({
+ message: 'first message',
+ propertyPath: 'property',
+ i18n: {
+ translations: {
+ de_CH: 'de_CH',
+ },
+ },
+ })
+ .build()
+ te.mockReturnValue(false)
+ i18n.locale = 'de-CH-scout'
+
+ expect(transformViolations(validationError, i18n)).toEqual({
+ property: ['de_CH'],
+ })
+ })
+
+ it('uses fallbackLocale', () => {
+ const validationError = createValidationError()
+ .withViolation({
+ message: 'first message',
+ propertyPath: 'property',
+ i18n: {
+ translations: {
+ [fallbackLocale]: fallbackLocale,
+ de: 'de',
+ },
+ },
+ })
+ .build()
+ te.mockReturnValue(false)
+ i18n.locale = 'it'
+
+ expect(transformViolations(validationError, i18n)).toEqual({
+ property: [fallbackLocale],
+ })
+ })
+ })
+ })
+})
+
+const unauthorizedError = {
+ name: 'ServerException',
+ response: {
+ status: 401,
+ data: {
+ message: 'Unauthorized',
+ detail: 'Unauthorized',
+ },
+ },
+}
+
+function createValidationError() {
+ const validationError = {
+ name: 'ServerException',
+ response: {
+ status: 422,
+ data: {
+ violations: [],
+ },
+ },
+ }
+
+ return {
+ withViolation: function (violation) {
+ validationError.response.data.violations.push(violation)
+ return this
+ },
+ build: () => cloneDeep(validationError),
+ }
+}
diff --git a/frontend-vue3/src/helpers/__tests__/vCalendarDragAndDrop.spec.js b/frontend-vue3/src/helpers/__tests__/vCalendarDragAndDrop.spec.js
new file mode 100644
index 0000000000..9c9ed9a248
--- /dev/null
+++ b/frontend-vue3/src/helpers/__tests__/vCalendarDragAndDrop.spec.js
@@ -0,0 +1,85 @@
+import { describe, expect, it } from 'vitest'
+import {
+ toTime,
+ roundTimeToNearestQuarterHour,
+ roundTimeUpToNextQuarterHour,
+} from '@/helpers/vCalendarDragAndDrop.js'
+import dayjs from '@/common/helpers/dayjs.js'
+import { parseDate } from 'vuetify/src/components/VCalendar/util/timestamp'
+
+describe('toTime', () => {
+ const dateTimesToTest = [
+ dayjs('2023-05-08T14:13'),
+ dayjs('2023-05-07T10:20'),
+ dayjs('2023-04-05T22:22'),
+ dayjs.utc('2023-03-26T01:30'), //daylight saving time change
+ dayjs.utc('2023-10-29T01:30'), //daylight saving time change
+ ]
+
+ const parametersToTest = dateTimesToTest.map((dateTime) => ({
+ calendarTimestamp: {
+ ...parseDate(dateTime.toDate()),
+ json: JSON.stringify(parseDate(dateTime.toDate())),
+ },
+ epochMillis: dateTime.valueOf(),
+ }))
+
+ it.each(parametersToTest)(
+ 'maps $calendarTimestamp.json to $epochMillis',
+ ({ calendarTimestamp, _, epochMillis }) => {
+ expect(toTime(calendarTimestamp)).toEqual(epochMillis)
+ }
+ )
+})
+
+describe('roundTimeToNearestQuarterHour', () => {
+ it.each([
+ ['22:22:00', '22:15'],
+ ['22:22:31', '22:30'],
+ ['10:20:00', '10:15'],
+ ['13:00:20', '13:00'],
+ ['14:13:00', '14:15'],
+ ['23:52:31', '00:00'],
+ ])('maps %s to %s', (input, expected) => {
+ const epochMillis = asEpochMillis(input)
+ const roundedEpoch = roundTimeToNearestQuarterHour(epochMillis)
+ expect(fromEpochMillis(roundedEpoch)).toEqual(expected)
+ })
+})
+
+describe('roundTimeUpToNextQuarterHour', () => {
+ it.each([
+ ['22:22:00', '22:30'],
+ ['10:20:00', '10:30'],
+ ['13:00:20', '13:15'],
+ ['14:13:00', '14:15'],
+ ])('maps %s to %s', (input, expected) => {
+ const epochMillis = asEpochMillis(input)
+ const roundedEpoch = roundTimeUpToNextQuarterHour(epochMillis)
+ expect(fromEpochMillis(roundedEpoch)).toEqual(expected)
+ })
+})
+
+/**
+ * Converts a time string (HH:mm:ss) in local timezone into epoch millis
+ *
+ * @param timeStr {string} HH:mm:ss
+ * @returns {number} epoch millis
+ */
+function asEpochMillis(timeStr) {
+ return dayjs('2023-12-24')
+ .hour(Number(timeStr.slice(0, 2)))
+ .minute(Number(timeStr.slice(3, 5)))
+ .second(Number(timeStr.slice(6, 8)))
+ .valueOf()
+}
+
+/**
+ * Converts a given epoch millisecond value to a formatted time string in the format 'HH:mm'.
+ *
+ * @param {number} epochMillis - The epoch millisecond value to be converted.
+ * @return {string} The formatted time string in the format 'HH:mm'.
+ */
+function fromEpochMillis(epochMillis) {
+ return dayjs(epochMillis).year(2023).month(12).date(24).format('HH:mm')
+}
diff --git a/frontend-vue3/src/helpers/mergeListeners.js b/frontend-vue3/src/helpers/mergeListeners.js
new file mode 100644
index 0000000000..664476d36a
--- /dev/null
+++ b/frontend-vue3/src/helpers/mergeListeners.js
@@ -0,0 +1,41 @@
+/**
+ * merges multiple listeners objects into a single one that is properly interpreted by Vue
+ * valuable to merge listeners from multiple composables
+ *
+ * Example Input:
+ * [
+ * {
+ * 'click': clickCallback1,
+ * 'mousedown': mousedownCallback1,
+ * },
+ * {
+ * 'click': clickCallback2
+ * }
+ * ]
+ *
+ * Example Output:
+ * {
+ * 'click':[
+ * clickCallback1,
+ * clickCallback2
+ * ],
+ * 'mousedown': [
+ * mousedownCallback1
+ * ]
+ * }
+ */
+export default function (listenersList) {
+ const mergedListeners = {}
+
+ listenersList.forEach((listeners) => {
+ for (const [eventName, callback] of Object.entries(listeners)) {
+ if (mergedListeners[eventName] === undefined) {
+ mergedListeners[eventName] = []
+ }
+
+ mergedListeners[eventName].push(callback)
+ }
+ })
+
+ return mergedListeners
+}
diff --git a/frontend-vue3/src/helpers/querySyncHelper.js b/frontend-vue3/src/helpers/querySyncHelper.js
new file mode 100644
index 0000000000..6d78dd9641
--- /dev/null
+++ b/frontend-vue3/src/helpers/querySyncHelper.js
@@ -0,0 +1,155 @@
+/**
+ * Allowed filter values that are not HalUris
+ * @typedef {'none'} SpecialValues
+ */
+/**
+ * The Type of Object in qualified hal format for api
+ * @typedef {'categories'|'camp_collaborations'|'periods'|'activity_progress_labels'} HalType
+ */
+/**
+ * Format of the Hal Uri
+ * @typedef {`/${HalType}/${string}` | SpecialValues} HalUri
+ */
+/**
+ * Formats the Hal-Object-URI to the id
+ * @param uri {HalUri} the ID (from the hal object)
+ * @return {string} the ID of the uri
+ */
+export const halUriToId = (uri) => {
+ if (uri === 'none') return uri
+ return uri.substring(uri.lastIndexOf('/') + 1)
+}
+/**
+ * Formats an id and a Datatype to a hal-object-id
+ * @param dataType {HalType} the datatype of the object
+ * @param id {string} the id of the object
+ * @return {HalUri}
+ */
+export const idToHalUri = (dataType, id) => {
+ if (id === 'none') return id
+ return `/${dataType}/${id}`
+}
+
+/**
+ * Transforms an object with halUriValues to an object with corresponding hal IDs.
+ * @param {Record} uriObj - Object with halUriValues
+ * @returns {Record} - Object with hal IDs
+ */
+export const transformValuesToHalId = (uriObj) => {
+ const transformedEntries = Object.entries(uriObj)
+ .filter(([_, value]) => !!value)
+ .filter(
+ ([_, value]) =>
+ typeof value === 'string' || (Array.isArray(value) && value.length !== 0)
+ )
+ .map(([key, value]) => [
+ key,
+ Array.isArray(value) ? value.map(halUriToId) : halUriToId(value),
+ ])
+ return Object.fromEntries(transformedEntries)
+}
+
+/**
+ * Transforms a query parameter based on its type and value.
+ * @internal
+ * @param {UrlParamKey} key - The query parameter key.
+ * @param {string|string[]} value - The query parameter value.
+ * @param {HalType} type - The datatype of the object.
+ * @returns {[string, HalUri|HalUri[]|null]} - The transformed query parameter entry.
+ */
+export function transformQueryParam(key, value, type) {
+ if (typeof value === 'string') {
+ const halUriValue =
+ key === 'period' ? idToHalUri(type, value) : [idToHalUri(type, value)]
+ return [key, halUriValue]
+ } else if (Array.isArray(value)) {
+ const uriValues = value
+ .filter((entry) => !!entry)
+ .map((entry) => idToHalUri(type, entry))
+ return [key, uriValues]
+ } else {
+ return [key, null]
+ }
+}
+
+/**
+ * @typedef {Record} ActivityFilter
+ */
+/**
+ * Allowed Url param keys
+ * @typedef {'period'|'responsible'|'category'|'progressLabels'} UrlParamKey
+ */
+/**
+ * The Allowed Url parameter keys
+ * @type {UrlParamKey[]} UrlParamKeys
+ * @readonly
+ */
+const urlParamKeys = ['period', 'responsible', 'category', 'progressLabel']
+/**
+ * Map for url param keys to hal types
+ * @type {Record}
+ */
+const URL_PARAM_TO_HAL_TYPE = {
+ category: 'categories',
+ responsible: 'camp_collaborations',
+ period: 'periods',
+ progressLabel: 'activity_progress_labels',
+}
+
+/**
+ * Processes the route query and returns a filtered and transformed object.
+ * @param {Dictionary} query - The route query object.
+ * @returns {Record} - The processed filter object.
+ */
+export function processRouteQuery(query) {
+ return Object.fromEntries(
+ Object.entries(query)
+ .filter((value) => isValidParamEntry(value))
+ .map(([key, value]) => [key, value, URL_PARAM_TO_HAL_TYPE[key]])
+ .map(([key, value, type]) => transformQueryParam(key, value, type))
+ .filter(([_, value]) => !!value)
+ )
+}
+
+/**
+ * @param {[string, (string | null)[]]} entry
+ * @returns {entry is ({([UrlParamKey,string|string[]])})}
+ */
+function isValidParamEntry(entry) {
+ const [key, value] = entry
+ const keyIsValid = urlParamKeys.includes(key)
+ const valueIsValid = Array.isArray(value) ? value.length !== 0 : !!value
+ return keyIsValid && valueIsValid
+}
+
+/**
+ * Checks if the filter contains updated values
+ * @param {Record} filter
+ * @param {Dictionary} query
+ * @return {boolean}
+ */
+export function filterAndQueryAreEqual(filter, query) {
+ if (JSON.stringify(filter) === JSON.stringify(query)) return true
+ const arrayFiltersAreEqual = ['category', 'responsible', 'progressLabel']
+ .map((key) => ({
+ a: getValueAsArrayForKey(query, key),
+ b: getValueAsArrayForKey(filter, key),
+ }))
+ .map(({ a, b }) => JSON.stringify(a) === JSON.stringify(b))
+ .reduce((accum, curr) => accum && curr, true)
+ return arrayFiltersAreEqual && filter.period === query.period
+}
+
+/**
+ * @internal
+ * @template T
+ * @param {T} obj
+ * @param {keyof T} key
+ * @return {string[] | undefined}
+ */
+function getValueAsArrayForKey(obj, key) {
+ const val = obj[key]
+ if (Array.isArray(val)) return val.filter((v) => !!v && typeof v === 'string').sort()
+ if (typeof val === 'string') return [val]
+ return undefined
+}
diff --git a/frontend-vue3/src/helpers/scheduleEntryRouteChange.js b/frontend-vue3/src/helpers/scheduleEntryRouteChange.js
new file mode 100644
index 0000000000..b3eb932feb
--- /dev/null
+++ b/frontend-vue3/src/helpers/scheduleEntryRouteChange.js
@@ -0,0 +1,37 @@
+import { firstActivityScheduleEntry } from '@/router.js'
+import { apiStore } from '@/plugins/store'
+
+/**
+ * Loads first valid schedule entry for activity if current one is missing
+ * @param activity
+ * @param to
+ * @param from
+ * @param next
+ * @return {Promise<*>}
+ */
+export default async function scheduleEntryRouteChange(activity, to, from, next) {
+ if (
+ to.params.scheduleEntryId !== from.params.scheduleEntryId ||
+ to.params.activityId !== from.params.activityId
+ ) {
+ apiStore.get().activities({ id: to.params.activityId }).$reload()
+ // activity reload doesn't need to be awaited, but for scheduleEntry we want to
+ // ensure it exists and otherwise reroute
+ return await apiStore
+ .get()
+ .scheduleEntries({ id: to.params.scheduleEntryId })
+ .$reload()
+ .then(() => next())
+ .catch(async () => {
+ return next({
+ name: 'camp/activity',
+ params: {
+ ...to.params,
+ scheduleEntryId: (await firstActivityScheduleEntry(to.params.activityId)).id,
+ },
+ })
+ })
+ } else {
+ return next()
+ }
+}
diff --git a/frontend-vue3/src/helpers/serverError.js b/frontend-vue3/src/helpers/serverError.js
new file mode 100644
index 0000000000..c58b18cb8b
--- /dev/null
+++ b/frontend-vue3/src/helpers/serverError.js
@@ -0,0 +1,93 @@
+/**
+ * Parses an error object returned by hal-json-vuex and returns as message string
+ */
+import fallbackLocalesFor from '@/plugins/i18n/apiFallbackLocalesFor'
+
+const serverErrorToString = (error) => {
+ // API error
+ // error.response is in API Problem Details format: https://www.rfc-editor.org/rfc/rfc7807
+ if (error.name === 'ServerException' && error.response) {
+ if (
+ error.response?.headers?.['content-type']?.startsWith('application/problem+json')
+ ) {
+ return error.response.data.detail
+ }
+
+ return error.response?.data?.message || error.toString()
+ }
+
+ // other error thrown directly by Javascript (e.g. connection error)
+ return error.message
+}
+
+function getApiTranslation(locale, violation) {
+ if (!locale) {
+ return null
+ }
+ const matchingTranslation = [locale, ...fallbackLocalesFor(locale)]
+ .map((locale) => violation?.i18n?.translations?.[locale])
+ .find((value) => value !== undefined)
+ return matchingTranslation ?? null
+}
+
+/**
+ * Parses an error object returned by hal-json-vuex and returns an object of propertypath => violationMessages[]
+ * i18n is nullable if someone wants to use it without initialized localisation
+ */
+const transformViolations = (error, i18n = null) => {
+ const serverErrorMessages = {}
+
+ if (error.name === 'ServerException' && error.response?.status !== 422) {
+ serverErrorMessages[0] = serverErrorToString(error)
+ return serverErrorMessages
+ }
+
+ const violations = error.response?.data?.violations ?? []
+
+ for (const i in violations) {
+ const violation = violations[i]
+ const propertyPath = violation.propertyPath
+ if (!serverErrorMessages[propertyPath]) {
+ serverErrorMessages[propertyPath] = []
+ }
+ const i18nKey = `api.${violation.i18n?.key}`
+ const locale = i18n?.locale?.replaceAll('-', '_')
+ const apiTranslation = getApiTranslation(locale, violation)
+
+ if (i18n?.te(i18nKey)) {
+ const parameters = violation.i18n?.parameters ?? {}
+ serverErrorMessages[propertyPath].push(i18n.t(i18nKey, parameters))
+ } else if (apiTranslation) {
+ serverErrorMessages[propertyPath].push(apiTranslation)
+ } else {
+ serverErrorMessages[propertyPath].push(violation.message)
+ }
+ }
+ return serverErrorMessages
+}
+
+function violationsToFlatArray(e, i18n) {
+ const violationsObject = transformViolations(e, i18n)
+ const violations = Object.entries(violationsObject)
+ if (violations.length === 0) {
+ return []
+ }
+ if (violations.length === 1 && violationsObject[0]) {
+ return [violationsObject[0]]
+ }
+ const toArray = (element) => {
+ if (Array.isArray(element)) {
+ return element
+ }
+ return [element]
+ }
+ const result = []
+ for (const [key, value] of Object.entries(violationsObject)) {
+ for (const message of toArray(value)) {
+ result.push(`${key}: ${message}`)
+ }
+ }
+ return result
+}
+
+export { serverErrorToString, transformViolations, violationsToFlatArray }
diff --git a/frontend-vue3/src/helpers/vCalendarDragAndDrop.js b/frontend-vue3/src/helpers/vCalendarDragAndDrop.js
new file mode 100644
index 0000000000..7d5ffae3c7
--- /dev/null
+++ b/frontend-vue3/src/helpers/vCalendarDragAndDrop.js
@@ -0,0 +1,30 @@
+/**
+ * helpers for VCalendar DragAndDrop composables
+ */
+
+const ONE_MINUTE_IN_MILLISECONDS = 60 * 1000
+const ONE_HOUR_IN_MILLISECONDS = 60 * ONE_MINUTE_IN_MILLISECONDS
+const ONE_DAY_IN_MILLISECONDS = 24 * ONE_HOUR_IN_MILLISECONDS
+const QUARTER_HOUR_IN_MILLISECONDS = 15 * ONE_MINUTE_IN_MILLISECONDS
+
+// helper function to convert Vuetify day & time object into timestamp
+const toTime = (tms) => {
+ return new Date(tms.year, tms.month - 1, tms.day, tms.hour, tms.minute).getTime()
+}
+
+const roundTimeToNearestQuarterHour = (time) => {
+ return Math.round(time / QUARTER_HOUR_IN_MILLISECONDS) * QUARTER_HOUR_IN_MILLISECONDS
+}
+
+const roundTimeUpToNextQuarterHour = (time) => {
+ return Math.ceil(time / QUARTER_HOUR_IN_MILLISECONDS) * QUARTER_HOUR_IN_MILLISECONDS
+}
+
+export {
+ toTime,
+ roundTimeToNearestQuarterHour,
+ roundTimeUpToNextQuarterHour,
+ ONE_MINUTE_IN_MILLISECONDS,
+ ONE_HOUR_IN_MILLISECONDS,
+ ONE_DAY_IN_MILLISECONDS,
+}
diff --git a/frontend-vue3/src/locales/de-CH-scout.json b/frontend-vue3/src/locales/de-CH-scout.json
new file mode 100644
index 0000000000..d808ffcec3
--- /dev/null
+++ b/frontend-vue3/src/locales/de-CH-scout.json
@@ -0,0 +1,31 @@
+{
+ "components": {
+ "campCreate": {
+ "campCreateStep1": {
+ "titlePlaceholder": "Sommerlager 2024 Pfadistufe"
+ }
+ }
+ },
+ "contentNode": {
+ "storycontext": {
+ "name": "Roter Faden"
+ }
+ },
+ "entity": {
+ "user": {
+ "fields": {
+ "nickname": "Pfadiname"
+ }
+ }
+ },
+ "global": {
+ "language": "Deutsch (Pfadi)"
+ },
+ "views": {
+ "camp": {
+ "story": {
+ "title": "Roter Faden"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/locales/de.json b/frontend-vue3/src/locales/de.json
new file mode 100644
index 0000000000..a4970d5652
--- /dev/null
+++ b/frontend-vue3/src/locales/de.json
@@ -0,0 +1,821 @@
+{
+ "components": {
+ "activity": {
+ "content": {
+ "checklist": {
+ "title": "Checkliste bearbeiten"
+ },
+ "columnLayout": {
+ "columnOperations": {
+ "addColumn": "Spalte hinzufügen",
+ "removeColumn": "Leere Spalte entfernen"
+ }
+ },
+ "lAThematicArea": {
+ "placeholder": "Themenbereich auswählen"
+ },
+ "storyboard": {
+ "controls": "Aktionen",
+ "reorder": "Verschieben",
+ "storyboardDialogRemoveSection": {
+ "deleteWarning": "Möchtest du diesen Abschnitt wirklich löschen?",
+ "title": "Wirklich löschen?"
+ }
+ }
+ },
+ "dialog": {
+ "dialogActivityEdit": {
+ "title": "Aktivität bearbeiten"
+ },
+ "formScheduleEntryList": {
+ "name": "Geplante Termine"
+ }
+ },
+ "menuCardlessContentNode": {
+ "deletingDisabled": "Muss leer sein zum Löschen"
+ },
+ "scheduleEntry": {
+ "backToContents": "Zurück zum Bearbeiten des Inhalts",
+ "changeLayout": "Layout ändern",
+ "clipboardInfoDialog": {
+ "allow": "Jetzt erlauben",
+ "denied": "Du hast den Zugriff auf die Zwischenablage verweigert. Kopierte Aktivitäten können daher nicht eingefügt werden.",
+ "description": "Damit du eine kopierte Aktivität einfügen kannst, musst du eCamp v3 erlauben, deine Zwischenablage zu lesen.",
+ "granted": "Du kannst nun kopierte Aktivitäten einfügen.",
+ "title": "Aktivität kopieren & einfügen"
+ },
+ "copyScheduleEntry": "Aktivität kopieren",
+ "deleteWarning": "Möchtest du diese Aktivität wirklich löschen? Der komplette Inhalt dieser Aktivität wird gelöscht."
+ },
+ "togglePaperSize": {
+ "switchToFullSize": "Zum Breitformat umschalten",
+ "switchToPaperSize": "Zum Papierformat umschalten"
+ }
+ },
+ "camp": {
+ "campInvitations": {
+ "title": "Einladen"
+ },
+ "campMembers": {
+ "title": "Mitglieder"
+ }
+ },
+ "campAdmin": {
+ "campActivityProgressLabels": {
+ "create": "Status erstellen",
+ "deleteError": "Status konnte nicht gelöscht werden. Der Status wird noch verwendet.",
+ "deleteWarning": "Möchtest du dieses Status wirklich löschen?",
+ "exit": "Umsortieren beenden",
+ "moveDown": "Nach unten",
+ "moveUp": "Nach oben",
+ "reorder": "Umsortieren",
+ "title": "Block-Status"
+ },
+ "campAddress": {
+ "title": "Lageradresse"
+ },
+ "campCategories": {
+ "create": "Block-Kategorie erstellen",
+ "pasteCategory": "Kopierte Kategorie einfügen",
+ "title": "Block-Kategorien"
+ },
+ "campConditionalFields": {
+ "course": {
+ "title": "Kurse"
+ },
+ "title": "Einstellungen für J+S",
+ "ysCamp": {
+ "title": "Lager"
+ }
+ },
+ "campDangerZone": {
+ "deleteCamp": {
+ "description": "Nachdem ein Lager gelöscht ist, gibt es kein zurück mehr. Bitte fahre nur fort, wenn du sicher bist.",
+ "explanation": "Diese Aktion kann nicht rückgängig gemacht werden. Dadurch wird das Lager \"{campTitle}\" inklusive allen Aktivitäten, Materiallisten und Verantwortungszuweisungen dauerhaft gelöscht.",
+ "label": "Bitte gib zur Bestätigung \"{campTitle}\" ein.",
+ "title": "Lager löschen"
+ },
+ "title": "Gefahrenzone"
+ },
+ "campMaterialLists": {
+ "createMaterialList": "Materialliste erstellen",
+ "title": "Materiallisten"
+ },
+ "campPeriods": {
+ "createPeriod": "Lagerabschnitt erstellen",
+ "title": "Lagerabschnitt | Lagerabschnitte"
+ },
+ "campPeriodsListItem": {
+ "changePeriodDescription": "Bezeichnung ändern",
+ "deleteWarning": "Möchtest du diesen Lagerabschnitt wirklich löschen?",
+ "lastPeriodNotDeletable": "Der letzte Lagerabschnitt kann nicht gelöscht werden.",
+ "movePeriod": "Lagerabschnitt verschieben",
+ "periodChangeEnd": "Am Ende Tage hinzufügen/entfernen",
+ "periodChangeStart": "Zu Begin Tage hinzufügen/entfernen"
+ },
+ "campSettings": {
+ "title": "Beschreibung"
+ },
+ "createCampPeriods": {
+ "add": "Weiteren Lagerabschnitt hinzufügen"
+ },
+ "dialogActivityProgressLabelCreate": {
+ "title": "Block-Status erstellen"
+ },
+ "dialogActivityProgressLabelEdit": {
+ "title": "Status bearbeiten"
+ },
+ "dialogCategoryCreate": {
+ "clearClipboard": "Zwischenablage leeren",
+ "clipboard": "Zwischenablage",
+ "clipboardInfoDialog": {
+ "allow": "Jetzt erlauben",
+ "denied": "Du hast den Zugriff auf die Zwischenablage verweigert. Kopierte Kategorien können daher nicht eingefügt werden.",
+ "description": "Damit du eine kopierte Kategorie einfügen kannst, musst du eCamp v3 erlauben, deine Zwischenablage zu lesen.",
+ "granted": "Du kannst nun kopierte Kategorien einfügen.",
+ "title": "Kategorie kopieren & einfügen"
+ },
+ "copyCategoryOrActivity": "Kategorie oder Aktivität kopieren",
+ "copyContent": "Inhalt kopieren",
+ "copyPasteCategory": "Kategorie kopieren & einfügen",
+ "copySourceInfo": "Hier kannst du die URL einer Block-Kategorie oder einer Aktivität einfügen, um dessen Inhalte zu kopieren.",
+ "pasteCategory": "Kopierte Kategorie oder Aktivität einfügen",
+ "title": "Block-Kategorie erstellen"
+ },
+ "dialogMaterialListCreate": {
+ "title": "Materialliste erstellen"
+ },
+ "dialogMaterialListEdit": {
+ "deleteError": "Materialliste konnte nicht gelöscht werden. Überprüfe vor dem Löschen, dass die Liste leer ist.",
+ "title": "Materialliste bearbeiten"
+ },
+ "dialogPeriodCreate": {
+ "title": "Lagerabschnitt erstellen"
+ },
+ "dialogPeriodDateEdit": {
+ "movePeriod": "Lagerabschnitt verschieben",
+ "periodChangeEnd": "Am Ende vom Lagerabschnitt Tage hinzufügen / entfernen",
+ "periodChangeStart": "Am Anfang vom Lagerabschnitt Tage hinzufügen / entfernen",
+ "periodDuration": "Anzahl Tage"
+ },
+ "dialogPeriodEdit": {
+ "moveScheduleEntries": "Aktivitäten verschieben"
+ },
+ "errorExistingActivitiesList": {
+ "description": "Kann nicht gelöscht werden. Wird noch von folgenden Aktivitäten verwendet:"
+ }
+ },
+ "campCreate": {
+ "campCreate": {
+ "steps": {
+ "configurate": "Konfigurieren",
+ "infos": "Infos",
+ "template": "Vorlage"
+ }
+ },
+ "campCreateStep1": {
+ "submitTooltip": "Bitte fülle alle Pflichtfelder aus.",
+ "titlePlaceholder": "Klassenlager 2024 5. Klasse"
+ },
+ "campCreateStep2": {
+ "category": "Block-Kategorien",
+ "checklistItemCount": "Keine Einträge | Ein Eintrag | {count} Einträge",
+ "checklists": "Checklisten",
+ "clipboardInfoDialog": {
+ "allow": "Jetzt erlauben",
+ "denied": "Du hast den Zugriff auf die Zwischenablage verweigert. Bitte füge den Link zum Vorlage-Lager stattdessen von Hand ein.",
+ "description": "Damit du die Einstellungen eines kopierten Lagers einfügen kannst, musst du eCamp v3 erlauben, deine Zwischenablage zu lesen.",
+ "granted": "Du kannst nun kopierte Lagereinstellungen einfügen.",
+ "title": "Lagereinstellungen kopieren & einfügen"
+ },
+ "create": "Lager erstellen",
+ "materialLists": "Materiallisten",
+ "noContent": "Keine Inhalte",
+ "noPrototype": "Keine Vorlage",
+ "noPrototypeAlert": {
+ "description": "Du musst alle Einstellungen manuell vornehmen. Es sind keine Blockvorlagen & Layouts vorhanden. Dies ist nur für erfahrene Nutzende geeignet.",
+ "title": "Achtung: Du hast \"Keine Vorlage\" ausgewählt."
+ },
+ "otherPrototype": "Einstellungen von einem anderen Lager kopieren…",
+ "pasteCamp": "Kopierte Lagereinstellungen einfügen",
+ "preview": "Vorschau der Lagervorlage",
+ "progressLabels": "Blockstatus",
+ "prototypeCampUrl": "Link zum gewünschten Vorlage-Lager",
+ "prototypeHint": "Kopiere Kategorien, Blockvorlagen, Blockstatus, Material- und Checklisten von einer Lagervorlage",
+ "prototypeHintEmpty": "Keine Kategorien, Blockvorlagen, Blockstatus, Material- und Checklisten aus einer Lagervorlage kopieren",
+ "prototypeHintOther": "Kopiere Kategorien, Blockvorlagen, Blockstatus, unpersönliche Material- und Checklisten von diesem anderen Lager. Es werden keine Aktivitäten kopiert.",
+ "prototypeHintSelected": "Kopiere Kategorien, Blockvorlagen, Blockstatus und Materiallisten von dieser Lagervorlage",
+ "submitTooltipPrototype": "Du musst noch auswählen, ob und welche Lagervorlage du verwenden möchtest."
+ }
+ },
+ "category": {
+ "categoryTemplate": {
+ "contents": "Inhalte",
+ "createLayoutHelp": "Hier kannst du die Vorlage für neue {categoryShort}-Blöcke definieren.{br}Blockinhalt & Layout bereits erstellter {categoryShort}-Blöcke, werden nicht angepasst.",
+ "layout": "Layout",
+ "noTemplate": "Keine Vorlage"
+ }
+ },
+ "checklist": {
+ "checklistCreate": {
+ "title": "Checkliste erstellen"
+ },
+ "checklistDetail": {
+ "deleteError": "Checkliste konnte nicht gelöscht werden. Überprüfe vor dem Löschen, dass die Checkliste nicht mehr in Aktivitäten verwendet wird.",
+ "deleteWarning": "Möchtest du diese Checkliste wirklich löschen? Der komplette Inhalt dieser Checkliste wird gelöscht."
+ },
+ "checklistItemCreate": {
+ "add": "Checklisten-Eintrag erstellen",
+ "title": "Checklisten-Eintrag hinzufügen"
+ },
+ "checklistItemEdit": {
+ "delete": "Möchtest du diesen Eintrag wirklich löschen?",
+ "title": "Checklisten-Eintrag bearbeiten"
+ },
+ "sortableChecklist": {
+ "add": "Zu \"{parent}\" hinzufügen"
+ }
+ },
+ "collaborator": {
+ "collaboratorCreate": {
+ "invite": "Einladung verschicken",
+ "inviteCta": "Ins Team einladen",
+ "title": "Person einladen"
+ },
+ "collaboratorEdit": {
+ "cannotRemoveLastManager": "Du kannst die letzte Person mit administrativen Rechten nicht deaktivieren",
+ "deactivate": "Deaktivieren",
+ "delete": "Möchtest du die Person '{name}' wirklich entfernen?",
+ "inviteAgain": "Erneut einladen",
+ "resendEmail": "E-Mail erneut senden",
+ "resentEmail": "Einladung gesendet",
+ "title": "{user} bearbeiten"
+ },
+ "collaboratorForm": {
+ "overrideAvatar": "Avatar für dieses Lager überschreiben",
+ "roleHint": "Jedes Lager benötigt mindestens eine Person mit Administrationsrechten."
+ },
+ "promptCollaboratorDeactivate": {
+ "deactivate": "Deaktivieren",
+ "warningText": "Möchtest du '{name}' wirklich deaktivieren?"
+ }
+ },
+ "dashboard": {
+ "selectFilter": {
+ "clear": "Zurücksetzen"
+ }
+ },
+ "dialog": {
+ "dialogEntityDelete": {
+ "title": "Wirklich löschen?"
+ }
+ },
+ "form": {
+ "base": {
+ "eColorField": {
+ "parseError": "Bitte gültige Farbe eingeben."
+ },
+ "eColorPicker": {
+ "closePicker": "Dialog schliessen",
+ "openPicker": "Dialog öffnen, um eine Farbe für {label} zu wählen"
+ },
+ "eDatePicker": {
+ "invalidFormat": "Ungültiges Format, bitte gib das Datum im Format DD.MM.YYYY ein",
+ "openPicker": "Dialog öffnen, um ein Datum für {label} zu wählen"
+ },
+ "eTimePicker": {
+ "invalidFormat": "Ungültiges Format, bitte gib die Zeit im Format HH:MM ein",
+ "openPicker": "Dialog öffnen, um eine Zeit für {label} zu wählen"
+ }
+ }
+ },
+ "generic": {
+ "lockButton": {
+ "clickToLock": "Klicken um zu sperren",
+ "clickToUnlock": "Klicken um zu entsperren",
+ "guestsCannotEdit": "Gäste können nicht bearbeiten"
+ }
+ },
+ "layout": {
+ "authContainer": {
+ "photoCredits": "Foto von Markus Rohner / Lotos"
+ }
+ },
+ "material": {
+ "dialogMaterialItemCreate": {
+ "title": "Materialeintrag erstellen"
+ },
+ "dialogMaterialItemEdit": {
+ "title": "Materialeintrag bearbeiten"
+ },
+ "materialCreateItem": {
+ "campSettingsButton": "Einstellungen",
+ "noMaterialListAvailable": "Für dieses Lager sind noch keine Materiallisten erfasst. Du kannst diese unter 'Admin' erfassen."
+ },
+ "materialLists": {
+ "materialsCount": "Keine Einträge | 1 Eintrag | {count} Einträge",
+ "overview": "Gesamtübersicht"
+ },
+ "materialTable": {
+ "addNewItem": "Eintrag hinzufügen",
+ "noItems": "Keine Einträge gefunden",
+ "periodOnly": "Filter: Lagerabschnitt",
+ "reference": "Aktivität / Abschnitt"
+ },
+ "useMaterialViewHelper": {
+ "detail": "Materialliste",
+ "overview": "Gesamtübersicht"
+ }
+ },
+ "navigation": {
+ "userMeta": {
+ "admin": "Admin",
+ "invitations": "Einladungen",
+ "logOut": "Ausloggen",
+ "myCamps": "Meine Lager",
+ "profile": "Profil"
+ }
+ },
+ "personalInvitations": {
+ "dialogPersonalInvitationReject": {
+ "rejectInvitation": "Einladung ablehnen",
+ "warningText": "Möchtest du die Einladung zum Lager \"{campTitle}\" wirklich ablehnen?"
+ },
+ "personalInvitations": {
+ "accept": "Akzeptieren",
+ "noOpenInvitations": "Keine offene Einladungen. Wurde die Einladung an eine andere Adresse als \"{email}\" versendet?",
+ "reject": "Ablehnen"
+ }
+ },
+ "print": {
+ "config": {
+ "activityConfig": {
+ "activity": "Aktivität"
+ },
+ "dialogScheduleEntryFilter": {
+ "filterActive": "Filter: {filtered} von {total} Aktivitäten",
+ "filterActivities": "{total} Aktivitäten filtern",
+ "resultCount": "Resultat: {filtered} von {total} Aktivitäten",
+ "title": "Aktivitäten filtern"
+ },
+ "picassoConfig": {
+ "orientation": "Seitenlayout",
+ "periods": "Lagerabschnitt(e)"
+ },
+ "programConfig": {
+ "dayOverview": "Tagesübersicht"
+ }
+ },
+ "documents": {
+ "campPrint": {
+ "filename": {
+ "activitiesOnly": "Aktivitäten {camp}",
+ "picassoOnly": "Grobprogramm {camp}"
+ }
+ }
+ },
+ "localPdfDownloadButton": {
+ "error": "Etwas hat nicht geklappt. Probiere es nochmals, oder lade die Seite neu."
+ },
+ "printClient": {
+ "downloadClientPdfButton": {
+ "label": "PDF herunterladen (Layout #2)"
+ },
+ "downloadClientPdfListItem": {
+ "label": "PDF herunterladen (Layout #2)"
+ },
+ "generatePdfMixin": {
+ "error": "Etwas hat nicht geklappt. Probiere es nochmals, oder lade die Seite neu."
+ },
+ "printPreviewClient": {
+ "previewError": "Etwas hat nicht geklappt. Probiere es nochmals mit anderen Druckeinstellungen, oder lade die Seite neu.",
+ "previewIframeTitle": "Druckvorschau"
+ }
+ },
+ "printConfigurator": {
+ "add": "Inhalt hinzufügen",
+ "config": {
+ "Activity": "Einzelne Aktivität",
+ "ActivityList": "Aktivitätenliste (Kurse)",
+ "Cover": "Titelseite",
+ "Picasso": "Grobprogramm",
+ "Program": "Detailprogramm",
+ "SafetyConsiderations": "Sicherheitsüberlegungen",
+ "Story": "Geschichte",
+ "Toc": "Inhaltsverzeichnis"
+ }
+ },
+ "printNuxt": {
+ "downloadNuxtPdfButton": {
+ "label": "PDF herunterladen (Layout #1)"
+ },
+ "downloadNuxtPdfListItem": {
+ "label": "PDF herunterladen (Layout #1)"
+ },
+ "generatePdfMixin": {
+ "error": "Etwas hat nicht geklappt. Probiere es nochmals, oder lade die Seite neu.",
+ "queueFull": "Alle unsere PDF-Drucker sind im Moment beschäftigt. Bitte versuche es später nochmals."
+ },
+ "printPreviewNuxt": {
+ "openPreview": "Vorschau in neuem Fenster öffnen",
+ "previewError": "Etwas hat nicht geklappt. Probiere es nochmals mit anderen Druckeinstellungen, oder lade die Seite neu.",
+ "previewIframeTitle": "Druckvorschau"
+ }
+ }
+ },
+ "program": {
+ "dialogActivityCreate": {
+ "clearClipboard": "Zwischenablage leeren",
+ "clipboard": "Zwischenablage",
+ "clipboardInfoDialog": {
+ "allow": "Jetzt erlauben",
+ "denied": "Du hast den Zugriff auf die Zwischenablage verweigert. Kopierte Aktivitäten können daher nicht eingefügt werden.",
+ "description": "Damit du eine kopierte Aktivität einfügen kannst, musst du eCamp v3 erlauben, deine Zwischenablage zu lesen.",
+ "granted": "Du kannst nun kopierte Aktivitäten einfügen.",
+ "title": "Aktivität kopieren & einfügen"
+ },
+ "copyActivity": "Aktivität kopieren",
+ "copyActivityContent": "Inhalt von Aktivität kopieren",
+ "copyPasteActivity": "Aktivität kopieren & einfügen",
+ "copySourceInfo": "Hier kannst du die URL einer Aktivität einfügen, um dessen Inhalte zu kopieren.",
+ "pasteActivity": "Kopierte Aktivität einfügen"
+ },
+ "formScheduleEntryItem": {
+ "end": "Ende",
+ "start": "Start"
+ },
+ "formScheduleEntryList": {
+ "name": "Geplante Termine"
+ },
+ "periodSwitcher": {
+ "title": "Lagerabschnitt wählen"
+ },
+ "picasso": {
+ "picasso": {
+ "datetime": {
+ "fullDate": "dd, DD. MMMM YYYY",
+ "smallDate": "dd, D.MM. | dd, D. MMM | dd, D. MMM YY"
+ }
+ },
+ "picassoEntry": {
+ "clipboardInfoDialog": {
+ "allow": "Jetzt erlauben",
+ "denied": "Du hast den Zugriff auf die Zwischenablage verweigert. Kopierte Aktivitäten können daher nicht eingefügt werden.",
+ "description": "Damit du eine kopierte Aktivität einfügen kannst, musst du eCamp v3 erlauben, deine Zwischenablage zu lesen.",
+ "granted": "Du kannst nun kopierte Aktivitäten einfügen.",
+ "title": "Aktivität kopieren & einfügen"
+ },
+ "location": "Ort:",
+ "responsible": "Verantwortlich: "
+ }
+ },
+ "scheduleEntryFilters": {
+ "category": "Kategorie",
+ "clearFilters": "Filter entfernen",
+ "day": "Datum",
+ "dayLabel": "Tag {dayNumber} ({date})",
+ "onlyMyActivities": "Nur meine Aktivitäten",
+ "period": "Lagerabschnitt",
+ "progressLabel": "Status",
+ "progressLabelNone": "Kein Status",
+ "responsible": "Verantwortlich",
+ "responsibleNone": "Keine Verantwortlichen"
+ }
+ },
+ "prompt": {
+ "promptEntityDelete": {
+ "title": "Wirklich löschen?"
+ }
+ },
+ "story": {
+ "storyDay": {
+ "noStory": "Die Blöcke an diesem Tag enthalten keinen roten Faden."
+ }
+ },
+ "toast": {
+ "toasts": {
+ "multiLineToast": {
+ "generalError": "Ein Fehler ist aufgetreten."
+ }
+ }
+ },
+ "user": {
+ "dialogChangeMail": {
+ "error": "Leider ist ein Fehler aufgetreten.",
+ "message": "Zur Verifikation schicken wir dir eine Mail.",
+ "success": "Bevor du die neue E-Mail-Adresse verwenden kannst, muss du diese verifizieren. Prüfe jetzt deine Mailbox.",
+ "title": "E-Mail-Adresse ändern"
+ },
+ "dialogChangeMailRunning": {
+ "error": "Leider ist ein Fehler aufgetreten.",
+ "message": "E-Mail-Adresse wird geändert...",
+ "success": "E-Mail-Adresse erfolgreich geändert.",
+ "title": "E-Mail-Adresse wird geändert"
+ }
+ }
+ },
+ "global": {
+ "button": {
+ "add": "Hinzufügen",
+ "back": "Zurück",
+ "cancel": "Abbrechen",
+ "close": "Schliessen",
+ "content": "Inhalt",
+ "continue": "Weiter",
+ "create": "Erstellen",
+ "delete": "Löschen",
+ "discard": "Verwerfen",
+ "download": "Herunterladen",
+ "edit": "Bearbeiten",
+ "editable": "Bearbeitbar",
+ "filter": "Filtern",
+ "lock": "Sperren",
+ "login": "Anmelden",
+ "logout": "Ausloggen",
+ "move": "Verschieben",
+ "ok": "OK",
+ "open": "Öffnen",
+ "remove": "Entfernen",
+ "rename": "Umbenennen",
+ "reset": "Zurücksetzen",
+ "save": "Speichern",
+ "saving": "Speichert",
+ "search": "Suchen",
+ "submit": "Abschicken",
+ "tryagain": "Erneut versuchen",
+ "unlock": "Entsperren",
+ "update": "Aktualisieren"
+ },
+ "changeLanguage": "Sprache ändern",
+ "collaborationAbilities": {
+ "guest": "Nur Leserecht",
+ "manager": "Vollständige Lageradministration, sowie Lese- & Schreibrecht",
+ "member": "Lese- & Schreibrecht"
+ },
+ "datetime": {
+ "vuetifyTimePickerFormat": "24hr"
+ },
+ "info": {
+ "offline": {
+ "description": "Daten speichern/laden nicht möglich.",
+ "title": "Du bist offline:"
+ }
+ },
+ "language": "Deutsch",
+ "loading": "Laden …",
+ "navigation": {
+ "admin": {
+ "title": "Admin"
+ },
+ "help": "Hilfe",
+ "news": "News"
+ },
+ "serverError": {
+ "409": "Uuuups... Diese Aktion hat zu einem Fehler auf dem Server geführt.",
+ "short": "Serverfehler"
+ },
+ "toast": {
+ "copied": "{source} kopiert"
+ },
+ "validation": {
+ "greaterThan": "{_field_} muss grösser sein als {min}",
+ "greaterThanOrEqual_date": "{_field_} darf nicht vor {min} liegen",
+ "greaterThan_time": "{_field_} muss später als {min} sein",
+ "lessThanOrEqual_date": "{_field_} darf nicht nach {max} liegen",
+ "oneEmojiOrTwoCharacters": "{_field_} darf nur 1 Emoji oder 2 Buchstaben/Zahlen haben"
+ },
+ "warning": {
+ "delete": "Möchtest du das wirklich löschen? | Möchtest du \"{entity}\" wirklich löschen?"
+ }
+ },
+ "views": {
+ "auth": {
+ "activate": {
+ "error": "Aktivierung fehlgeschlagen",
+ "success": "Account erfolgreich aktiviert",
+ "title": "Dein Account wird aktiviert"
+ },
+ "login": {
+ "acceptTermsOfServiceOnOAuthLogin": "Beim Login via einen dieser Services akzeptierst du die {termsOfServiceLink}.",
+ "accountless": "Hast du noch keinen Account?",
+ "email": "E-Mail",
+ "infoText": {
+ "dev": "Dies ist die Entwickler-Version von eCamp v3.{br}WICHTIG: Nur für Entwickler-Gebrauch geeignet. Alle Daten sind öffentlich und werden periodisch gelöscht!{br}Login: test(at)example.com / test"
+ },
+ "loginCallback": {
+ "loginInProgress": "Du wirst eingeloggt"
+ },
+ "notActivated": "Nicht aktiviert?",
+ "or": "oder mit",
+ "password": "Passwort",
+ "passwordForgotten": "Passwort vergessen?",
+ "provider": {
+ "cevidb": "CeviDB",
+ "ecamp": "Anmelden mit eCamp",
+ "google": "Google",
+ "jubladb": "JublaDB",
+ "midata": "MiData"
+ },
+ "registernow": "Jetzt registrieren",
+ "resendActivation": "Aktivierungsmail erneut senden",
+ "resetPassword": "Passwort zurücksetzen",
+ "termsOfServiceLink": "Nutzungsbedingungen"
+ },
+ "register": {
+ "acceptTermsOfService": "Nutzungsbedingungen akzeptieren",
+ "alreadyHaveAnAccount": "Hast du bereits ein Konto?",
+ "passwordConfirmation": "Passwort erneut eingeben",
+ "register": "Registrieren",
+ "requiredField": "Pflichtfelder",
+ "title": "Ein Konto erstellen"
+ },
+ "registerDone": {
+ "message": "Wir haben dir eine Mail geschickt. Bitte schliesse die Registrierung ab, in dem du den Aktivierungs-Link im Mail aufrufst.",
+ "success": "Erfolgreich registriert",
+ "title": "Konto erstellen"
+ },
+ "resendActivation": {
+ "errorMessage": "Erneutes Senden der Aktivierung fehlgeschlagen.",
+ "send": "Abschicken",
+ "successMessage": "Mail mit Link für 'Aktivierung' wird versendet.",
+ "title": "Aktivierungsmail erneut senden"
+ },
+ "resetPassword": {
+ "errorMessage": "Passwort konnte nicht geändert werden.",
+ "invalidRequest": "Ungültiger Link",
+ "password": "Neues Passwort",
+ "passwordConfirmation": "Neues Passwort wiederholen",
+ "send": "Passwort setzen",
+ "successMessage": "Neues Passwort erfolgreich gesetzt.",
+ "title": "Neues Passwort setzen"
+ },
+ "resetPasswordRequest": {
+ "errorMessage": "Passwort zurücksetzen nicht möglich.",
+ "send": "Abschicken",
+ "successMessage": "Mail mit Link für 'Passwort zurücksetzen' wird versendet.",
+ "title": "Passwort zurücksetzen"
+ }
+ },
+ "camp": {
+ "activity": {
+ "printPreview": "Druckvorschau öffnen",
+ "sideBarProgram": {
+ "title": "Tagesübersicht"
+ }
+ },
+ "admin": {
+ "activity": {
+ "title": "Aktivitätseinstellungen"
+ },
+ "adminMaterialLists": {
+ "title": "Materiallisten"
+ },
+ "collaborators": {
+ "email": "E-Mail-Adresse",
+ "inactiveCollaborators": "Inaktiv",
+ "members": "Mitarbeitende",
+ "openInvitations": "Offene Einladungen",
+ "title": "Team"
+ },
+ "info": {
+ "title": "Lagerinfos"
+ },
+ "print": {
+ "title": "Lager drucken"
+ },
+ "sideBarAdmin": {
+ "itemActivity": "Aktivitäten",
+ "itemActivitySubtitle": "Kategorie, Vorlagen & Status",
+ "itemCollaborators": "Team",
+ "itemInfos": "Lagerinfos",
+ "itemMaterialLists": "Materiallisten",
+ "itemPrint": "PDF / Drucken"
+ },
+ "title": "Admin"
+ },
+ "campProgram": {
+ "reminderLockedCreate": "Ziehen zum Erstellen ist nur im entsperrten Modus möglich.",
+ "reminderLockedMove": "Ziehen zum Verschieben ist nur im entsperrten Modus möglich.",
+ "title": "Grobprogramm"
+ },
+ "category": {
+ "category": {
+ "clipboardInfoDialog": {
+ "allow": "Jetzt erlauben",
+ "denied": "Du hast den Zugriff auf die Zwischenablage verweigert. Kopierte Kategorien können daher nicht eingefügt werden.",
+ "description": "Damit du eine kopierte Kategorie einfügen kannst, musst du eCamp v3 erlauben, deine Zwischenablage zu lesen.",
+ "granted": "Du kannst nun kopierte Kategorien einfügen.",
+ "title": "Kategorie kopieren & einfügen"
+ },
+ "copyCategory": "Kategorie kopieren",
+ "deleteCategory": "Kategorie löschen",
+ "properties": "Eigenschaften",
+ "template": "Vorlage für neue Blöcke"
+ },
+ "sideBarCategory": {
+ "title": "Kategorien"
+ }
+ },
+ "checklistOverview": {
+ "checklistLists": {
+ "title": "Checklisten-Übersicht"
+ }
+ },
+ "dashboard": {
+ "activities": "Aktivitäten",
+ "columns": {
+ "category": "Kategorie",
+ "number": "Nummer",
+ "responsible": "Verantwortlich",
+ "time": "Zeit",
+ "title": "Titel"
+ },
+ "noEntries": "Keine Aktivitäten gefunden. Versuche die Filter zu entfernen oder lade die Seite neu.",
+ "today": "Heute",
+ "welcome": "Willkommen in deinem neuen Lager. Es sind noch keine Aktivitäten erfasst. "
+ },
+ "invitation": {
+ "acceptCurrentAuth": "Einladung mit aktuellem Account akzeptieren",
+ "backToHome": "Zurück zur Startseite",
+ "error": "Ein unerwarteter Fehler ist aufgetreten",
+ "notFound": "Die Einladung wurde bereits angenommen oder gelöscht",
+ "openCamp": "Lager öffnen",
+ "register": "Registrieren",
+ "reject": "Einladung ablehnen",
+ "successfullyRejected": "Die Einladung wurde erfolgreich abgelehnt",
+ "title": "Einladung",
+ "useOtherAuth": "Ausloggen und einen anderen Account benutzen",
+ "userAlreadyInCamp": "Du arbeitest schon an diesem Lager mit"
+ },
+ "material": {
+ "materialLists": {
+ "title": "Materiallisten"
+ },
+ "materialOverview": {
+ "createNewList": "Materialliste erstellen",
+ "download": "Übersicht herunterladen",
+ "title": "Gesamtübersicht"
+ },
+ "sideBarMaterialLists": {
+ "title": "Materiallisten"
+ }
+ },
+ "navigation": {
+ "desktop": {
+ "navTopbar": {
+ "admin": "Admin",
+ "campIsLoading": "Lager wird geladen",
+ "checklist": "Checkliste",
+ "material": "Material",
+ "print": "Drucken",
+ "program": "Programm",
+ "story": "Geschichte",
+ "team": "Team"
+ }
+ },
+ "mobile": {
+ "navBottombar": {
+ "material": "Material",
+ "more": "Mehr",
+ "program": "Programm",
+ "story": "Geschichte"
+ },
+ "navSidebar": {
+ "itemActivity": "Aktivitäten",
+ "itemActivitySubtitle": "Kategorie, Vorlagen & Status",
+ "itemCamps": "Meine Lager",
+ "itemChecklists": "Checklisten-Übersicht",
+ "itemClose": "Menü schliessen",
+ "itemCollaborators": "Team",
+ "itemInfos": "Lagerinfos",
+ "itemMaterialLists": "Materiallisten",
+ "itemPrinting": "PDF / Drucken"
+ }
+ }
+ },
+ "story": {
+ "title": "Geschichte"
+ }
+ },
+ "campCreate": {
+ "title": "Lager erstellen"
+ },
+ "camps": {
+ "create": "Lager erstellen",
+ "pastCamps": "Alte Lager",
+ "prototypeCamps": "Vorlagen",
+ "title": "Meine Lager"
+ },
+ "invitations": {
+ "personalInvitations": "Einladungen"
+ },
+ "pageNotFound": {
+ "backToHome": "Zurück zur Startseite",
+ "detail": "Hoppla. Du bist vom Weg abgekommen…{br}Dieser Link funktioniert leider nicht."
+ },
+ "profile": {
+ "changeEmail": "Ändern",
+ "profile": "Profil"
+ }
+ }
+}
diff --git a/frontend-vue3/src/locales/en-CH-scout.json b/frontend-vue3/src/locales/en-CH-scout.json
new file mode 100644
index 0000000000..3c097e08c2
--- /dev/null
+++ b/frontend-vue3/src/locales/en-CH-scout.json
@@ -0,0 +1,12 @@
+{
+ "entity": {
+ "user": {
+ "fields": {
+ "nickname": "Scout Name"
+ }
+ }
+ },
+ "global": {
+ "language": "English (Scout)"
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/locales/en.json b/frontend-vue3/src/locales/en.json
new file mode 100644
index 0000000000..db18b9d0ab
--- /dev/null
+++ b/frontend-vue3/src/locales/en.json
@@ -0,0 +1,823 @@
+{
+ "components": {
+ "activity": {
+ "content": {
+ "checklist": {
+ "title": "Edit checklist"
+ },
+ "columnLayout": {
+ "columnOperations": {
+ "addColumn": "Add a column",
+ "removeColumn": "Remove empty column"
+ }
+ },
+ "lAThematicArea": {
+ "placeholder": "Choose thematic area"
+ },
+ "storyboard": {
+ "controls": "Controls",
+ "reorder": "Reorder",
+ "storyboardDialogRemoveSection": {
+ "deleteWarning": "Do you really want to remove this section?",
+ "title": "Really delete?"
+ }
+ }
+ },
+ "dialog": {
+ "dialogActivityEdit": {
+ "title": "Edit activity"
+ },
+ "formScheduleEntryList": {
+ "name": "Scheduled"
+ }
+ },
+ "menuCardlessContentNode": {
+ "deletingDisabled": "Must be empty to delete"
+ },
+ "scheduleEntry": {
+ "backToContents": "Back to editing content",
+ "changeLayout": "Change layout",
+ "clipboardInfoDialog": {
+ "allow": "Allow now",
+ "denied": "You have denied access to your clipboard. Therefore, you cannot paste copied activities.",
+ "description": "In order to paste a copied activity, you must allow eCamp v3 to read your clipboard.",
+ "granted": "You can now paste copied activities.",
+ "title": "Copy & paste activity"
+ },
+ "copyScheduleEntry": "Copy activity",
+ "deleteWarning": "Do you really want to delete this activity? All content of this activity will be removed."
+ },
+ "togglePaperSize": {
+ "switchToFullSize": "Switch to full size",
+ "switchToPaperSize": "Switch to paper size"
+ }
+ },
+ "camp": {
+ "campInvitations": {
+ "title": "Invite"
+ },
+ "campMembers": {
+ "title": "Members"
+ }
+ },
+ "campAdmin": {
+ "campActivityProgressLabels": {
+ "create": "Create a state",
+ "deleteError": "State can't be deleted. It is still used.",
+ "deleteWarning": "Do you really want to delete this state?",
+ "exit": "Exit reordering",
+ "moveDown": "Move down",
+ "moveUp": "Move up",
+ "reorder": "Reorder",
+ "title": "Activity state"
+ },
+ "campAddress": {
+ "title": "Address"
+ },
+ "campCategories": {
+ "create": "Create activity category",
+ "pasteCategory": "Paste category",
+ "title": "Activity categories"
+ },
+ "campConditionalFields": {
+ "course": {
+ "title": "Courses"
+ },
+ "title": "Settings for Y+S",
+ "ysCamp": {
+ "title": "Camps"
+ }
+ },
+ "campDangerZone": {
+ "deleteCamp": {
+ "description": "Once you delete a camp, there is no going back. Please be certain.",
+ "explanation": "This action cannot be undone. This will permanently delete the \"{campTitle}\" camp, activities, material lists and remove all collaborator associations.",
+ "label": "Please type \"{campTitle}\" to confirm.",
+ "title": "Delete Camp"
+ },
+ "title": "Danger Zone"
+ },
+ "campMaterialLists": {
+ "createMaterialList": "Create material list",
+ "title": "Material lists"
+ },
+ "campPeriods": {
+ "createPeriod": "Create period",
+ "title": "Period | Periods"
+ },
+ "campPeriodsListItem": {
+ "changePeriodDescription": "Change description",
+ "deleteWarning": "Do you really want to delete this period?",
+ "lastPeriodNotDeletable": "Last period is not deletable.",
+ "movePeriod": "Move period",
+ "periodChangeEnd": "Add/remove days at end",
+ "periodChangeStart": "Add/remove days at start"
+ },
+ "campSettings": {
+ "title": "Settings"
+ },
+ "createCampPeriods": {
+ "add": "Add a period"
+ },
+ "dialogActivityProgressLabelCreate": {
+ "title": "Create activity state"
+ },
+ "dialogActivityProgressLabelEdit": {
+ "title": "Edit activity state"
+ },
+ "dialogCategoryCreate": {
+ "clearClipboard": "Clear clipboard",
+ "clipboard": "Clipboard",
+ "clipboardInfoDialog": {
+ "allow": "Allow now",
+ "denied": "You have denied access to your clipboard. Therefore, you cannot paste copied categories.",
+ "description": "In order to paste a copied category, you must allow eCamp v3 to read your clipboard.",
+ "granted": "You can now paste copied categories.",
+ "title": "Copy & paste category"
+ },
+ "copyCategoryOrActivity": "Copy category or activity",
+ "copyContent": "Copy content",
+ "copyPasteCategory": "Copy & paste category",
+ "copySourceInfo": "Here you can paste the URL of a category or an activity to copy its contents.",
+ "pasteCategory": "paste category or activity",
+ "title": "Create activity category"
+ },
+ "dialogMaterialListCreate": {
+ "title": "Create material list"
+ },
+ "dialogMaterialListEdit": {
+ "deleteError": "Could not delete the material list. Check if the list is empty before deleting it.",
+ "title": "Edit material list"
+ },
+ "dialogPeriodCreate": {
+ "title": "Create period"
+ },
+ "dialogPeriodDateEdit": {
+ "movePeriod": "Move period",
+ "periodChangeEnd": "Add / remove days at end of this period",
+ "periodChangeStart": "Add / remove days at start of this period",
+ "periodDuration": "Number of days"
+ },
+ "dialogPeriodEdit": {
+ "moveScheduleEntries": "Move schedule entries"
+ },
+ "errorExistingActivitiesList": {
+ "description": "Cannot be deleted. Still used by the following activities:"
+ }
+ },
+ "campCreate": {
+ "campCreate": {
+ "steps": {
+ "configurate": "Configure",
+ "infos": "Info",
+ "template": "Template"
+ }
+ },
+ "campCreateStep1": {
+ "submitTooltip": "Please fill out all required fields.",
+ "titlePlaceholder": "Summer camp 2024"
+ },
+ "campCreateStep2": {
+ "category": "Activity categories",
+ "checklistItemCount": "No entries | One entry | {count} entries",
+ "checklists": "Checklists",
+ "clearClipboard": "Clear clipboard",
+ "clipboard": "Clipboard",
+ "clipboardInfoDialog": {
+ "allow": "Allow now",
+ "denied": "You have denied access to your clipboard. Therefore, you have to enter the link to the template camp manually.",
+ "description": "In order to paste the settings of a copied camp, you must allow eCamp v3 to read your clipboard.",
+ "granted": "You can now paste copied camp settings.",
+ "title": "Copy & paste camp settings"
+ },
+ "create": "Create the Camp",
+ "materialLists": "Materiallisten",
+ "noContent": "No Content",
+ "noPrototype": "No template",
+ "noPrototypeAlert": {
+ "description": "You must make all settings manually. There are no activity templates & layouts available. This is only suitable for experienced users.",
+ "title": "Attention: You chose \"No template\"."
+ },
+ "otherPrototype": "Copy the settings from another camp…",
+ "pasteCamp": "Paste copied camp settings",
+ "preview": "Preview of camp template",
+ "progressLabels": "Activity states",
+ "prototypeCampUrl": "Link of desired template camp",
+ "prototypeHint": "Copy categories, activity templates, states, material lists and checklists from a template.",
+ "prototypeHintEmpty": "Don't copy any categories, activity templates, states, material lists or checklists.",
+ "prototypeHintOther": "Copy categories, activity templates, states, unpersonal material lists and checklists from this other camp. No activities are copied.",
+ "prototypeHintSelected": "Copy categories, activity templates, states and material lists from this template.",
+ "submitTooltipPrototype": "You need to choose if and which template you want."
+ }
+ },
+ "category": {
+ "categoryTemplate": {
+ "contents": "Contents",
+ "createLayoutHelp": "Here you can define the template for new {categoryShort} activities.{br}The content & layout of already created {categoryShort} activities will not be adjusted.",
+ "layout": "Layout",
+ "noTemplate": "No template"
+ }
+ },
+ "checklist": {
+ "checklistCreate": {
+ "title": "Create checklist"
+ },
+ "checklistDetail": {
+ "deleteError": "Checklist couldn't be deleted. Ensure checklist is not used within activities before trying to delete it.",
+ "deleteWarning": "Do you really want to remove this checklist? All content of the checklist will be deleted."
+ },
+ "checklistItemCreate": {
+ "add": "Create checklist entry",
+ "title": "Add checklist entry"
+ },
+ "checklistItemEdit": {
+ "delete": "Do you really want to remove this item?",
+ "title": "Edit checklist entry"
+ },
+ "sortableChecklist": {
+ "add": "Add to \"{parent}\""
+ }
+ },
+ "collaborator": {
+ "collaboratorCreate": {
+ "invite": "Send invitation",
+ "inviteCta": "Invite to team",
+ "title": "Invite people"
+ },
+ "collaboratorEdit": {
+ "cannotRemoveLastManager": "You cannot remove the last person with administrative rights.",
+ "deactivate": "Deactivate",
+ "delete": "Do you really want to remove collaborator '{name}'?",
+ "inviteAgain": "Invite again",
+ "resendEmail": "Resend invite",
+ "resentEmail": "Invitation sent",
+ "title": "Edit {user}"
+ },
+ "collaboratorForm": {
+ "overrideAvatar": "Overwrite avatar for this camp",
+ "roleHint": "Each camp needs at least one person with administrative rights."
+ },
+ "promptCollaboratorDeactivate": {
+ "deactivate": "Deactivate",
+ "warningText": "Do you want to deactivate '{name}'?"
+ }
+ },
+ "dashboard": {
+ "selectFilter": {
+ "clear": "Clear"
+ }
+ },
+ "dialog": {
+ "dialogEntityDelete": {
+ "title": "Really delete?"
+ }
+ },
+ "form": {
+ "base": {
+ "eColorField": {
+ "parseError": "Please enter a valid color."
+ },
+ "eColorPicker": {
+ "closePicker": "Close dialog",
+ "openPicker": "Open dialog to select a color for {label}"
+ },
+ "eDatePicker": {
+ "invalidFormat": "Invalid format, please enter the date in the format MM/DD/YYYY",
+ "openPicker": "Open dialog to select a date for {label}"
+ },
+ "eTimePicker": {
+ "invalidFormat": "Invalid format, please enter the time in the format HH:MM AM/PM",
+ "openPicker": "Open dialog to select a time for {label}"
+ }
+ }
+ },
+ "generic": {
+ "lockButton": {
+ "clickToLock": "Click to lock",
+ "clickToUnlock": "Click to unlock",
+ "guestsCannotEdit": "Guests have no permission to edit"
+ }
+ },
+ "layout": {
+ "authContainer": {
+ "photoCredits": "Photo by Markus Rohner / Lotos"
+ }
+ },
+ "material": {
+ "dialogMaterialItemCreate": {
+ "title": "Create material item"
+ },
+ "dialogMaterialItemEdit": {
+ "title": "Edit material item"
+ },
+ "materialCreateItem": {
+ "campSettingsButton": "Settings",
+ "noMaterialListAvailable": "There are no material lists for this camp yet. You can create them in 'Admin'."
+ },
+ "materialLists": {
+ "materialsCount": "No entries | 1 entry | {count} entries",
+ "overview": "General overview"
+ },
+ "materialTable": {
+ "addNewItem": "Add new item",
+ "noItems": "No material items found",
+ "periodOnly": "Filter: Period",
+ "reference": "Activity / Period"
+ },
+ "useMaterialViewHelper": {
+ "detail": "Material list",
+ "overview": "General overview"
+ }
+ },
+ "navigation": {
+ "userMeta": {
+ "admin": "Admin",
+ "invitations": "Invitations",
+ "logOut": "Log out",
+ "myCamps": "My camps",
+ "profile": "Profile"
+ }
+ },
+ "personalInvitations": {
+ "dialogPersonalInvitationReject": {
+ "rejectInvitation": "Reject invitation",
+ "warningText": "Are you sure you want to reject the initation to the camp \"{campTitle}\"?"
+ },
+ "personalInvitations": {
+ "accept": "Accept",
+ "noOpenInvitations": "No open invitations. Was the invitation sent to an address other than \"{email}\"?",
+ "reject": "Reject"
+ }
+ },
+ "print": {
+ "config": {
+ "activityConfig": {
+ "activity": "Activity"
+ },
+ "dialogScheduleEntryFilter": {
+ "filterActive": "Filter: {filtered} of {total} activities",
+ "filterActivities": "Filter {total} activities",
+ "resultCount": "Result: {filtered} of {total} activities",
+ "title": "Filter activities"
+ },
+ "picassoConfig": {
+ "orientation": "Page layout",
+ "periods": "Period(s)"
+ },
+ "programConfig": {
+ "dayOverview": "print day overview"
+ }
+ },
+ "documents": {
+ "campPrint": {
+ "filename": {
+ "activitiesOnly": "Activities {camp}",
+ "picassoOnly": "Picasso {camp}"
+ }
+ }
+ },
+ "localPdfDownloadButton": {
+ "error": "Something didn't work. Try again, or reload the page."
+ },
+ "printClient": {
+ "downloadClientPdfButton": {
+ "label": "Download PDF (layout #2)"
+ },
+ "downloadClientPdfListItem": {
+ "label": "Download PDF (layout #2)"
+ },
+ "generatePdfMixin": {
+ "error": "Something did not work. Please try again, or try reloading the page."
+ },
+ "printPreviewClient": {
+ "previewError": "Something did not work. Please try again with different printing settings, or reload the page.",
+ "previewIframeTitle": "Print preview"
+ }
+ },
+ "printConfigurator": {
+ "add": "Add content",
+ "config": {
+ "Activity": "Single activity",
+ "ActivityList": "Activity list (courses)",
+ "Cover": "Cover page",
+ "Picasso": "Picasso",
+ "Program": "Program",
+ "SafetyConsiderations": "Safety considerations",
+ "Story": "Story",
+ "Toc": "Table of contents"
+ }
+ },
+ "printNuxt": {
+ "downloadNuxtPdfButton": {
+ "label": "Download PDF (layout #1)"
+ },
+ "downloadNuxtPdfListItem": {
+ "label": "Download PDF (layout #1)"
+ },
+ "generatePdfMixin": {
+ "error": "Something did not work. Please try again, or try reloading the page.",
+ "queueFull": "All our PDF printers are busy at the moment. Please try again later."
+ },
+ "printPreviewNuxt": {
+ "openPreview": "Open preview in new window",
+ "previewError": "Something did not work. Please try again with different printing settings, or reload the page.",
+ "previewIframeTitle": "Print preview"
+ }
+ }
+ },
+ "program": {
+ "dialogActivityCreate": {
+ "clearClipboard": "Clear clipboard",
+ "clipboard": "Clipboard",
+ "clipboardInfoDialog": {
+ "allow": "Allow now",
+ "denied": "You have denied access to your clipboard. Therefore, you cannot paste copied activities.",
+ "description": "In order to paste a copied activity, you must allow eCamp v3 to read your clipboard.",
+ "granted": "You can now paste copied activities.",
+ "title": "Copy & paste activity"
+ },
+ "copyActivity": "Copy activity",
+ "copyActivityContent": "Copy content from activity",
+ "copyPasteActivity": "Copy & paste activity",
+ "copySourceInfo": "Here you can paste the URL of an activity to copy its contents.",
+ "pasteActivity": "paste activity"
+ },
+ "formScheduleEntryItem": {
+ "end": "End",
+ "start": "Start"
+ },
+ "formScheduleEntryList": {
+ "name": "Scheduled"
+ },
+ "periodSwitcher": {
+ "title": "Choose period"
+ },
+ "picasso": {
+ "picasso": {
+ "datetime": {
+ "fullDate": "ddd, DD. MMMM YYYY",
+ "smallDate": "dd, D.MM. | dd, D. MMM | ddd, D. MMM YY"
+ }
+ },
+ "picassoEntry": {
+ "clipboardInfoDialog": {
+ "allow": "Allow now",
+ "denied": "You have denied access to your clipboard. Therefore, you cannot paste copied activities.",
+ "description": "In order to paste a copied activity, you must allow eCamp v3 to read your clipboard.",
+ "granted": "You can now paste copied activities.",
+ "title": "Copy & paste activity"
+ },
+ "location": "Location:",
+ "responsible": "Responsible: "
+ }
+ },
+ "scheduleEntryFilters": {
+ "category": "Category",
+ "clearFilters": "Clear filters",
+ "day": "Date",
+ "dayLabel": "Day {dayNumber} ({date})",
+ "onlyMyActivities": "Only my activities",
+ "period": "Period",
+ "progressLabel": "State",
+ "progressLabelNone": "No state",
+ "responsible": "Responsible",
+ "responsibleNone": "No responsibles"
+ }
+ },
+ "prompt": {
+ "promptEntityDelete": {
+ "title": "Really delete?"
+ }
+ },
+ "story": {
+ "storyDay": {
+ "noStory": "The activities on this day do not contain any story content."
+ }
+ },
+ "toast": {
+ "toasts": {
+ "multiLineToast": {
+ "generalError": "An error has occurred."
+ }
+ }
+ },
+ "user": {
+ "dialogChangeMail": {
+ "error": "An error has occurred.",
+ "message": "You will receive an email for verification.",
+ "success": "Before you can use your new email address, you have to verify it. Check your mailbox now.",
+ "title": "Change email address"
+ },
+ "dialogChangeMailRunning": {
+ "error": "An error has occurred.",
+ "message": "Changing email address ...",
+ "success": "Email address successfully changed.",
+ "title": "Changing email address"
+ }
+ }
+ },
+ "global": {
+ "button": {
+ "add": "Add",
+ "back": "Back",
+ "cancel": "Cancel",
+ "close": "Close",
+ "content": "Content",
+ "continue": "Continue",
+ "create": "Create",
+ "delete": "Delete",
+ "discard": "Discard",
+ "download": "Download",
+ "edit": "Edit",
+ "editable": "Editable",
+ "filter": "Filter",
+ "lock": "Lock",
+ "login": "Log in",
+ "logout": "Logout",
+ "move": "Move",
+ "ok": "OK",
+ "open": "Open",
+ "remove": "Remove",
+ "rename": "Rename",
+ "reset": "Reset",
+ "save": "Save",
+ "saving": "Saving",
+ "search": "Search",
+ "submit": "Submit",
+ "tryagain": "Try again",
+ "unlock": "Unlock",
+ "update": "Update"
+ },
+ "changeLanguage": "Change language",
+ "collaborationAbilities": {
+ "guest": "Read-only",
+ "manager": "Read, write & camp management",
+ "member": "Read & write"
+ },
+ "datetime": {
+ "vuetifyTimePickerFormat": "ampm"
+ },
+ "info": {
+ "offline": {
+ "description": "Data saving/loading not possible.",
+ "title": "Your are offline:"
+ }
+ },
+ "language": "English",
+ "loading": "Loading …",
+ "navigation": {
+ "admin": {
+ "title": "Admin"
+ },
+ "help": "Help",
+ "news": "News"
+ },
+ "serverError": {
+ "409": "Uuuups... This action caused an server-side error.",
+ "short": "Server error"
+ },
+ "toast": {
+ "copied": "{source} copied"
+ },
+ "validation": {
+ "greaterThan": "{_field_} must be greater than {min}",
+ "greaterThanOrEqual_date": "{_field_} may not be earlier than {min}",
+ "greaterThan_time": "{_field_} must be later than {min}",
+ "lessThanOrEqual_date": "{_field_} may not be later than {max}",
+ "oneEmojiOrTwoCharacters": "{_field_} may only have 1 emoji or 2 letters/numbers"
+ },
+ "warning": {
+ "delete": "Do you really want to delete this? | Do you really want to delete \"{entity}\"?"
+ }
+ },
+ "views": {
+ "auth": {
+ "activate": {
+ "error": "Activation failed",
+ "success": "Account successfully activated",
+ "title": "Your account will be activated"
+ },
+ "login": {
+ "acceptTermsOfServiceOnOAuthLogin": "By logging in via one of these services, you accept the {termsOfServiceLink}.",
+ "accountless": "Don't have an account yet?",
+ "email": "Email",
+ "infoText": {
+ "dev": "This is the development version of eCamp v3.{br}IMPORTANT: This is meant for development usage only. All data is public and will be deleted periodically!{br}Login: test@example.com / test"
+ },
+ "loginCallback": {
+ "loginInProgress": "You will be logged in"
+ },
+ "notActivated": "Not activated?",
+ "or": "or with",
+ "password": "Password",
+ "passwordForgotten": "Forgotten your password?",
+ "provider": {
+ "cevidb": "CeviDB",
+ "ecamp": "Login with eCamp",
+ "google": "Google",
+ "jubladb": "JublaDB",
+ "midata": "MiData"
+ },
+ "registernow": "Register now",
+ "resendActivation": "Send activation email again",
+ "resetPassword": "Reset password",
+ "termsOfServiceLink": "terms of service"
+ },
+ "register": {
+ "acceptTermsOfService": "Accept the terms of service",
+ "alreadyHaveAnAccount": "Already have an account?",
+ "passwordConfirmation": "Enter password again",
+ "register": "Register",
+ "requiredField": "required field",
+ "title": "Create an account"
+ },
+ "registerDone": {
+ "message": "We sent you an email. Please complete your registration by clicking the activation-link in the email",
+ "success": "Successfully registered",
+ "title": "Create account"
+ },
+ "resendActivation": {
+ "errorMessage": "Sending the activation email again failed.",
+ "send": "Send",
+ "successMessage": "Mail with link to activate your account will be delivered.",
+ "title": "Send activation email again"
+ },
+ "resetPassword": {
+ "errorMessage": "Reset password failed.",
+ "invalidRequest": "Invalid link",
+ "password": "New password",
+ "passwordConfirmation": "New password again",
+ "send": "Set password",
+ "successMessage": "Successfully set new password.",
+ "title": "Reset password"
+ },
+ "resetPasswordRequest": {
+ "errorMessage": "Reset password failed.",
+ "send": "Send",
+ "successMessage": "Mail with Link to reset your password will be delivered.",
+ "title": "Reset password"
+ }
+ },
+ "camp": {
+ "activity": {
+ "printPreview": "Open print preview",
+ "sideBarProgram": {
+ "title": "Activities on this day"
+ }
+ },
+ "admin": {
+ "activity": {
+ "title": "Activity settings"
+ },
+ "adminMaterialLists": {
+ "title": "Material lists"
+ },
+ "collaborators": {
+ "email": "Email address",
+ "inactiveCollaborators": "Inactive",
+ "members": "Members",
+ "openInvitations": "Open invitations",
+ "title": "Team"
+ },
+ "info": {
+ "title": "Camp infos"
+ },
+ "print": {
+ "title": "Print camp"
+ },
+ "sideBarAdmin": {
+ "itemActivity": "Activities",
+ "itemActivitySubtitle": "Category, templates & status",
+ "itemCollaborators": "Team",
+ "itemInfos": "Camp infos",
+ "itemMaterialLists": "Material lists",
+ "itemPrint": "PDF / Print"
+ },
+ "title": "Admin"
+ },
+ "campProgram": {
+ "reminderLockedCreate": "Drag to create is only possible in unlocked mode.",
+ "reminderLockedMove": "Drag to move is only possible in unlocked mode.",
+ "title": "Picasso"
+ },
+ "category": {
+ "category": {
+ "clipboardInfoDialog": {
+ "allow": "Allow now",
+ "denied": "You have denied access to your clipboard. Therefore, you cannot paste copied categories.",
+ "description": "In order to paste a copied category, you must allow eCamp v3 to read your clipboard.",
+ "granted": "You can now paste copied categories.",
+ "title": "Copy & paste category"
+ },
+ "copyCategory": "Copy category",
+ "deleteCategory": "Delete category",
+ "properties": "Properties",
+ "template": "Template for new activities"
+ },
+ "sideBarCategory": {
+ "title": "Categories"
+ }
+ },
+ "checklistOverview": {
+ "checklistLists": {
+ "title": "Checklist Overview"
+ }
+ },
+ "dashboard": {
+ "activities": "Activities",
+ "columns": {
+ "category": "Category",
+ "number": "Number",
+ "responsible": "Responsible",
+ "time": "Time",
+ "title": "Title"
+ },
+ "noEntries": "No activities found. Try clearing the selection filters and/or reloading the page.",
+ "today": "Today",
+ "welcome": "Welcome to your new camp. There aren't any activities defined yet."
+ },
+ "invitation": {
+ "acceptCurrentAuth": "Accept invitation with current account",
+ "backToHome": "Back to home",
+ "error": "An unexpected error occurred",
+ "notFound": "This invitation was already accepted or deleted",
+ "openCamp": "Open camp",
+ "register": "Register",
+ "reject": "Deny invitation",
+ "successfullyRejected": "The invitation was successfully rejected",
+ "title": "Invitation",
+ "useOtherAuth": "Logout & use another account",
+ "userAlreadyInCamp": "You are already participating in this camp"
+ },
+ "material": {
+ "materialLists": {
+ "title": "Material lists"
+ },
+ "materialOverview": {
+ "createNewList": "Create material list",
+ "download": "Download overview",
+ "title": "General overview"
+ },
+ "sideBarMaterialLists": {
+ "title": "Material lists"
+ }
+ },
+ "navigation": {
+ "desktop": {
+ "navTopbar": {
+ "admin": "Admin",
+ "campIsLoading": "Camp is loading",
+ "checklist": "Checklist",
+ "material": "Materials",
+ "print": "Print",
+ "program": "Program",
+ "story": "Story",
+ "team": "Team"
+ }
+ },
+ "mobile": {
+ "navBottombar": {
+ "material": "Materials",
+ "more": "More",
+ "program": "Program",
+ "story": "Story"
+ },
+ "navSidebar": {
+ "itemActivity": "Activities",
+ "itemActivitySubtitle": "Category, templates & status",
+ "itemCamps": "My Camps",
+ "itemChecklists": "Checklist Overview",
+ "itemClose": "Close menu",
+ "itemCollaborators": "Team",
+ "itemInfos": "Camp infos",
+ "itemMaterialLists": "Material lists",
+ "itemPrinting": "PDF / Print"
+ }
+ }
+ },
+ "story": {
+ "title": "Story"
+ }
+ },
+ "campCreate": {
+ "title": "Create a Camp"
+ },
+ "camps": {
+ "create": "Create a camp",
+ "pastCamps": "Past camps",
+ "prototypeCamps": "Prototypes",
+ "title": "My Camps"
+ },
+ "invitations": {
+ "personalInvitations": "Invitations"
+ },
+ "pageNotFound": {
+ "backToHome": "Back to home",
+ "detail": "Oops. You've lost your way…{br}Unfortunately, this link does not work."
+ },
+ "profile": {
+ "changeEmail": "Change",
+ "profile": "Profile"
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/locales/fr-CH-scout.json b/frontend-vue3/src/locales/fr-CH-scout.json
new file mode 100644
index 0000000000..4893b0fa29
--- /dev/null
+++ b/frontend-vue3/src/locales/fr-CH-scout.json
@@ -0,0 +1,33 @@
+{
+ "components": {
+ "print": {
+ "printConfigurator": {
+ "config": {
+ "Story": "Fil rouge"
+ }
+ }
+ }
+ },
+ "contentNode": {
+ "storycontext": {
+ "name": "Fil rouge"
+ }
+ },
+ "entity": {
+ "user": {
+ "fields": {
+ "nickname": "Totem"
+ }
+ }
+ },
+ "global": {
+ "language": "Français (Scout)"
+ },
+ "views": {
+ "camp": {
+ "story": {
+ "title": "Fil rouge"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/locales/fr.json b/frontend-vue3/src/locales/fr.json
new file mode 100644
index 0000000000..db9db6f922
--- /dev/null
+++ b/frontend-vue3/src/locales/fr.json
@@ -0,0 +1,811 @@
+{
+ "components": {
+ "activity": {
+ "content": {
+ "checklist": {
+ "title": "Modifier la check-list"
+ },
+ "columnLayout": {
+ "columnOperations": {
+ "addColumn": "Ajouter une colonne",
+ "removeColumn": "Supprimer la colonne vide"
+ }
+ },
+ "lAThematicArea": {
+ "placeholder": "Choisir un domaine thématique"
+ },
+ "storyboard": {
+ "controls": "Actions",
+ "reorder": "Déplacer",
+ "storyboardDialogRemoveSection": {
+ "deleteWarning": "Veux-tu vraiment supprimer cette ligne ?",
+ "title": "Confirmer la suppression ?"
+ }
+ }
+ },
+ "dialog": {
+ "dialogActivityEdit": {
+ "title": "Modifier l'activité"
+ }
+ },
+ "dialog": {
+ "dialogActivityEdit": {
+ "title": "Modifier l'activité"
+ },
+ "formScheduleEntryList": {
+ "name": "Dates planifiées"
+ }
+ },
+ "menuCardlessContentNode": {
+ "deletingDisabled": "Doit être vide pour être supprimé"
+ },
+ "scheduleEntry": {
+ "backToContents": "Retour à l'édition du contenu",
+ "changeLayout": "Changer la mise en page",
+ "clipboardInfoDialog": {
+ "allow": "Autoriser maintenant",
+ "denied": "Vous avez refusé l'accès à votre presse-papiers. Par conséquent, vous ne pouvez pas coller les activités copiées.",
+ "description": "Pour coller une activité copiée, vous devez autoriser eCamp v3 à lire votre presse-papiers.",
+ "granted": "Vous pouvez maintenant coller les activités copiées.",
+ "title": "Copier et coller une activité"
+ },
+ "copyScheduleEntry": "Copier une activité",
+ "deleteWarning": "Veux-tu vraiment supprimer cette activité ? Tout le contenu de cette activité sera supprimé."
+ },
+ "togglePaperSize": {
+ "switchToFullSize": "Passer au format large",
+ "switchToPaperSize": "Passer au format papier"
+ }
+ },
+ "camp": {
+ "campInvitations": {
+ "title": "Inviter"
+ },
+ "campMembers": {
+ "title": "Membres"
+ }
+ },
+ "campAdmin": {
+ "campActivityProgressLabels": {
+ "create": "Créer un statut",
+ "deleteError": "Le statut ne peut pas être supprimé. Il est toujours utilisé.",
+ "deleteWarning": "Veux-tu vraiment supprimer ce statut?",
+ "exit": "Fin du réagencement",
+ "moveDown": "Descendre",
+ "moveUp": "Monter",
+ "reorder": "Réordonner",
+ "title": "Statut des activités"
+ },
+ "campAddress": {
+ "title": "Adresse"
+ },
+ "campCategories": {
+ "create": "Créer une catégorie d'activité",
+ "pasteCategory": "Coller la catégorie",
+ "title": "Catégories d'activités"
+ },
+ "campConditionalFields": {
+ "course": {
+ "title": "Cours"
+ },
+ "title": "Paramètres pour J+S",
+ "ysCamp": {
+ "title": "Camps"
+ }
+ },
+ "campDangerZone": {
+ "deleteCamp": {
+ "description": "Une fois un camp supprimé, il est impossible de revenir en arrière. Ne continue que si tu es sûr.",
+ "explanation": "Cette action ne peut pas être annulée. Cette action supprimera définitivement le camp \"{campTitle}\", les activités, les listes de matériel et les personnes ajoutées.",
+ "label": "Veuillez saisir \"{campTitle}\" pour confirmer.",
+ "title": "Supprimer le camp"
+ },
+ "title": "Zone à risque"
+ },
+ "campMaterialLists": {
+ "createMaterialList": "Créer une liste de matériel",
+ "title": "Listes de matériel"
+ },
+ "campPeriods": {
+ "createPeriod": "Créer une période",
+ "title": "Période | Périodes"
+ },
+ "campPeriodsListItem": {
+ "changePeriodDescription": "Modifier la description",
+ "deleteWarning": "Veux-tu vraiment supprimer cette période ?",
+ "lastPeriodNotDeletable": "La dernière période ne peut pas être supprimée",
+ "movePeriod": "Déplacer la période",
+ "periodChangeEnd": "Ajouter/supprimer des jours à la fin",
+ "periodChangeStart": "Ajouter/supprimer des jours au début"
+ },
+ "campSettings": {
+ "title": "Paramètres"
+ },
+ "createCampPeriods": {
+ "add": "Ajouter une période"
+ },
+ "dialogActivityProgressLabelCreate": {
+ "title": "Créer un statut"
+ },
+ "dialogActivityProgressLabelEdit": {
+ "title": "Modifier le statut"
+ },
+ "dialogCategoryCreate": {
+ "clipboardInfoDialog": {
+ "allow": "Autoriser maintenant",
+ "denied": "Vous avez refusé l'accès à votre presse-papiers. Par conséquent, vous ne pouvez pas coller les catégories copiées.",
+ "description": "Pour coller une catégorie copiée, vous devez autoriser eCamp v3 à lire votre presse-papiers.",
+ "granted": "Vous pouvez maintenant coller les catégories copiées.",
+ "title": "Copier et coller une catégorie"
+ },
+ "title": "Créer une catégorie d'activité"
+ },
+ "dialogMaterialListCreate": {
+ "title": "Créer une liste de matériel"
+ },
+ "dialogMaterialListEdit": {
+ "deleteError": "Impossible de supprimer la liste de matériel. Vérifie que la liste soit vide avant de la supprimer.",
+ "title": "Modifier la liste de matériel"
+ },
+ "dialogPeriodCreate": {
+ "title": "Créer une période"
+ },
+ "dialogPeriodDateEdit": {
+ "movePeriod": "Déplacer la période",
+ "periodChangeEnd": "Ajouter / supprimer des jours à la fin de cette période",
+ "periodChangeStart": "Ajouter / supprimer des jours au début de cette période",
+ "periodDuration": "Nombre de jours"
+ },
+ "dialogPeriodEdit": {
+ "moveScheduleEntries": "Déplacer les entrées du calendrier"
+ },
+ "errorExistingActivitiesList": {
+ "description": "Ne peut pas être supprimé. Toujours utilisé par les activités suivantes :"
+ }
+ },
+ "campCreate": {
+ "campCreate": {
+ "steps": {
+ "configurate": "Configuration",
+ "infos": "Info",
+ "template": "Modèle"
+ }
+ },
+ "campCreateStep1": {
+ "submitTooltip": "Remplis tous les champs obligatoires.",
+ "titlePlaceholder": "Camp d'été 2024"
+ },
+ "campCreateStep2": {
+ "category": "Catégories d'activités",
+ "create": "Créer le camp",
+ "noContent": "Pas de contenu",
+ "noPrototype": "Pas de modèle",
+ "noPrototypeAlert": {
+ "description": "Tu dois effectuer tous les réglages manuellement. Il n'y a pas de modèles de blocs ni de mises en page. Ceci ne convient qu'aux utilisateurs expérimentés.",
+ "title": "Attention : Vous avez choisi \"Pas de modèle\"."
+ },
+ "preview": "Aperçu du modèle du camp",
+ "progressLabels": "États d'activités",
+ "prototypeHint": "Copie les catégories, les modèles de blocs et les états de blocs d'un modèle de camp.",
+ "prototypeHintEmpty": "Ne pas copier de catégories, de modèles de blocs et de statuts de blocs à partir d'un modèle de camp.",
+ "prototypeHintSelected": "Copie les catégories, les modèles de blocs et les statuts de blocs de ce modèle de camp.",
+ "submitTooltipPrototype": "Tu dois encore choisir si tu veux utiliser un modèle de champ et lequel."
+ }
+ },
+ "category": {
+ "categoryTemplate": {
+ "contents": "Contenus",
+ "createLayoutHelp": "Ici, vous pouvez définir le modèle pour de nouvelles activités {categoryShort}.{br}Le contenu et la mise en page des activités {categoryShort} déjà créées ne seront pas ajustés.",
+ "layout": "Layout",
+ "noTemplate": "Pas de modèle"
+ },
+ "copyCategoryInfoDialog": {
+ "allow": "Autoriser maintenant",
+ "denied": "Tu as refusé l'accès à ton presse-papiers. Par conséquent, tu ne peux pas coller les catégories copiées.",
+ "description": "Pour coller une catégorie copiée, tu dois autoriser eCamp à lire ton presse-papiers.",
+ "granted": "Tu peux maintenant coller les catégories copiées.",
+ "title": "Copier et coller la catégorie"
+ }
+ },
+ "checklist": {
+ "checklistCreate": {
+ "title": "Créer une check-list"
+ },
+ "checklistDetail": {
+ "deleteError": "La check-list n'a pas pu être supprimée. Assure-toi que la check-list n'est pas utilisée dans les activités avant d'essayer de la supprimer.",
+ "deleteWarning": "Veux-tu vraiment supprimer cette check-list ? Tout le contenu de cette check-list sera supprimé."
+ },
+ "checklistItemCreate": {
+ "add": "Créer un point de check-list",
+ "title": "Ajouter un point de check-list"
+ },
+ "checklistItemEdit": {
+ "delete": "Veux-tu vraiment supprimer cet élément ?",
+ "title": "Modifier le point de check-list"
+ },
+ "sortableChecklist": {
+ "add": "Ajouter à \"{parent}\""
+ }
+ },
+ "collaborator": {
+ "collaboratorCreate": {
+ "invite": "Envoyer l'invitation",
+ "inviteCta": "Inviter",
+ "title": "Inviter une personne"
+ },
+ "collaboratorEdit": {
+ "cannotRemoveLastManager": "Tu ne peux pas supprimer le dernier manager.",
+ "deactivate": "Désactiver",
+ "delete": "Veux-tu vraiment supprimer la personne '{name}' ?",
+ "inviteAgain": "Inviter de nouveau",
+ "resendEmail": "Renvoyer l'email",
+ "resentEmail": "Invitation envoyée",
+ "title": "Modifier {user}"
+ },
+ "collaboratorForm": {
+ "overrideAvatar": "Remplacer l'avatar pour ce camp",
+ "roleHint": "Chaque camp nécessite au moins une personne disposant de droits d'administrateur."
+ },
+ "promptCollaboratorDeactivate": {
+ "deactivate": "Désactiver",
+ "warningText": "Veux-tu désactiver '{name}' ?"
+ }
+ },
+ "dashboard": {
+ "selectFilter": {
+ "clear": "Vider"
+ }
+ },
+ "dialog": {
+ "dialogEntityDelete": {
+ "title": "Confirmation de suppression"
+ }
+ },
+ "form": {
+ "base": {
+ "eColorField": {
+ "parseError": "Merci de saisir une couleur valide."
+ },
+ "eColorPicker": {
+ "closePicker": "Fermer le dialogue",
+ "openPicker": "Ouvre un dialogue pour sélectionner une couleur pour {label}"
+ },
+ "eDatePicker": {
+ "invalidFormat": "Format non valide, veuillez saisir la date au format MM/JJ/AAAA.",
+ "openPicker": "Ouvre un dialogue pour sélectionner une date pour {label}"
+ },
+ "eTimePicker": {
+ "invalidFormat": "Format non valide, veuillez saisir l'heure au format HH:MM AM/PM",
+ "openPicker": "Ouvre un dialogue pour sélectionner une heure pour {label}"
+ }
+ }
+ },
+ "generic": {
+ "lockButton": {
+ "clickToLock": "Cliquer pour verrouiller",
+ "clickToUnlock": "Cliquer pour déverrouiller",
+ "guestsCannotEdit": "Les invités n'ont pas le droit de modifier"
+ }
+ },
+ "layout": {
+ "authContainer": {
+ "photoCredits": "Photo par Markus Rohner / Lotos"
+ }
+ },
+ "material": {
+ "dialogMaterialItemCreate": {
+ "title": "Ajouter du matériel"
+ },
+ "dialogMaterialItemEdit": {
+ "title": "Modifier l'entrée de matériel"
+ },
+ "materialCreateItem": {
+ "campSettingsButton": "Paramètres",
+ "noMaterialListAvailable": "Il n'y a pas encore de liste de matériel pour ce camp. Tu peux les créer dans 'Admin'."
+ },
+ "materialLists": {
+ "materialsCount": "Pas des éléments | Un élément | {count} éléments",
+ "overview": "Aperçu général"
+ },
+ "materialTable": {
+ "addNewItem": "Ajoute un nouvel élément",
+ "noItems": "Aucun élément matériel trouvé",
+ "periodOnly": "Filtre : Période",
+ "reference": "Activité / Période"
+ },
+ "useMaterialViewHelper": {
+ "detail": "Liste de matériel",
+ "overview": "Aperçu général"
+ }
+ },
+ "navigation": {
+ "userMeta": {
+ "admin": "Admin",
+ "invitations": "Invitations",
+ "logOut": "Se déconnecter",
+ "myCamps": "Mes camps",
+ "profile": "Profil"
+ }
+ },
+ "personalInvitations": {
+ "dialogPersonalInvitationReject": {
+ "rejectInvitation": "Refuser l'invitation",
+ "warningText": "Tu veux vraiment refuser l'invitation au camp \"{campTitle}\" ?"
+ },
+ "personalInvitations": {
+ "accept": "Accepter",
+ "noOpenInvitations": "Aucune invitation ouverte. L'invitation a-t-elle été envoyée à une autre adresse que \"{email}\" ?",
+ "reject": "Refuser"
+ }
+ },
+ "print": {
+ "config": {
+ "activityConfig": {
+ "activity": "Activité"
+ },
+ "dialogScheduleEntryFilter": {
+ "filterActive": "Filtre: {filtered} activités sur {total}",
+ "filterActivities": "Filtre: {total} activités",
+ "resultCount": "Résultat: {filtered} des activités sur {total}",
+ "title": "Filtrer les activités"
+ },
+ "picassoConfig": {
+ "orientation": "Mise en page",
+ "periods": "Période(s) du camp"
+ },
+ "programConfig": {
+ "dayOverview": "Aperçu des jours"
+ }
+ },
+ "documents": {
+ "campPrint": {
+ "filename": {
+ "activitiesOnly": "Activités {camp}",
+ "picassoOnly": "Programme général {camp}"
+ }
+ }
+ },
+ "localPdfDownloadButton": {
+ "error": "Une erreur est survenue. Essaie à nouveau, ou recharge la page."
+ },
+ "printClient": {
+ "downloadClientPdfButton": {
+ "label": "Télécharger le PDF (mise en page #2)"
+ },
+ "downloadClientPdfListItem": {
+ "label": "Télécharger le PDF (mise en page #2)"
+ },
+ "generatePdfMixin": {
+ "error": "Une erreur est survenue. Essaie à nouveau, ou recharge la page."
+ },
+ "printPreviewClient": {
+ "previewError": "Une erreur est survenue. Veuillez réessayer avec des paramètres d'impression différents, ou recharger la page.",
+ "previewIframeTitle": "Aperçu avant impression"
+ }
+ },
+ "printConfigurator": {
+ "add": "Ajouter du contenu",
+ "config": {
+ "Activity": "Activité unique",
+ "ActivityList": "Liste des blocs (cours)",
+ "Cover": "Page de couverture",
+ "Picasso": "Picasso",
+ "Program": "Programme",
+ "SafetyConsiderations": "Considérations sur la sécurité",
+ "Story": "Histoire",
+ "Toc": "Table des matières"
+ }
+ },
+ "printNuxt": {
+ "downloadNuxtPdfButton": {
+ "label": "Télécharger le PDF (mise en page #1)"
+ },
+ "downloadNuxtPdfListItem": {
+ "label": "Télécharger le PDF (mise en page #1)"
+ },
+ "generatePdfMixin": {
+ "error": "Une erreur est survenue. Essaie à nouveau, ou recharge la page.",
+ "queueFull": "Toutes nos imprimantes PDF sont occupées en ce moment. Veuillez réessayer plus tard."
+ },
+ "printPreviewNuxt": {
+ "openPreview": "Ouvrir l'aperçu dans une nouvelle fenêtre",
+ "previewError": "Une erreur est survenue. Veuillez réessayer avec des paramètres d'impression différents, ou recharger la page.",
+ "previewIframeTitle": "Aperçu avant impression"
+ }
+ }
+ },
+ "program": {
+ "dialogActivityCreate": {
+ "clearClipboard": "Vider le presse-papier",
+ "clipboard": "Presse-papier",
+ "clipboardInfoDialog": {
+ "allow": "Autoriser maintenant",
+ "denied": "Vous avez refusé l'accès à votre presse-papiers. Par conséquent, vous ne pouvez pas coller les activités copiées.",
+ "description": "Pour coller une activité copiée, vous devez autoriser eCamp v3 à lire votre presse-papiers.",
+ "granted": "Vous pouvez maintenant coller les activités copiées.",
+ "title": "Copier et coller une activité"
+ },
+ "copyActivity": "Copier une activité",
+ "copyActivityContent": "Copier le contenu depuis une activité",
+ "copyPasteActivity": "Copier et coller une activité",
+ "copySourceInfo": "Vous pouvez coller ici l'URL d'une activité pour copier son contenu.",
+ "pasteActivity": "coller l'activité"
+ },
+ "formScheduleEntryItem": {
+ "end": "Fin",
+ "start": "Début"
+ },
+ "formScheduleEntryList": {
+ "name": "Dates planifiées"
+ },
+ "periodSwitcher": {
+ "title": "Choisir la période"
+ },
+ "picasso": {
+ "picasso": {
+ "datetime": {
+ "fullDate": "dd DD. MMMM YYYY",
+ "smallDate": "dd D.MM. | dd D. MMM | dd D. MMM YY"
+ }
+ },
+ "picassoEntry": {
+ "clipboardInfoDialog": {
+ "allow": "Autoriser maintenant",
+ "denied": "Vous avez refusé l'accès à votre presse-papiers. Par conséquent, vous ne pouvez pas coller les activités copiées.",
+ "description": "Pour coller une activité copiée, vous devez autoriser eCamp v3 à lire votre presse-papiers.",
+ "granted": "Vous pouvez maintenant coller les activités copiées.",
+ "title": "Copier et coller une activité"
+ },
+ "location": "Lieu:",
+ "responsible": "Responsable:"
+ }
+ },
+ "scheduleEntryFilters": {
+ "category": "Catégorie",
+ "clearFilters": "Effacer les filtres",
+ "day": "Date",
+ "dayLabel": "Jour {dayNumber} ({date})",
+ "onlyMyActivities": "Seulement mes activités",
+ "period": "Période",
+ "progressLabel": "Statut",
+ "progressLabelNone": "Aucun statut",
+ "responsible": "Responsable",
+ "responsibleNone": "Aucun responsables"
+ }
+ },
+ "prompt": {
+ "promptEntityDelete": {
+ "title": "Confirmation de suppression"
+ }
+ },
+ "story": {
+ "storyDay": {
+ "noStory": "Aucun file rouge trouvé ce jour-là..."
+ }
+ },
+ "toast": {
+ "toasts": {
+ "multiLineToast": {
+ "generalError": "Une erreur est survenue."
+ }
+ }
+ },
+ "user": {
+ "dialogChangeMail": {
+ "error": "Une erreur est survenue.",
+ "message": "Un e-mail de vérification sera envoyé.",
+ "success": "Ta nouvelle adresse e-mail doit être vérifiée avant de pouvoir être utilisée. Vérifie ta boîte mail.",
+ "title": "Changer d'adresse e-mail"
+ },
+ "dialogChangeMailRunning": {
+ "error": "Une erreur est survenue.",
+ "message": "Changement d'adresse e-mail ...",
+ "success": "L'adresse e-mail a été modifiée avec succès.",
+ "title": "Changement d'adresse e-mail"
+ }
+ }
+ },
+ "global": {
+ "button": {
+ "add": "Ajouter",
+ "back": "Retour",
+ "cancel": "Annuler",
+ "close": "Fermer",
+ "content": "Contenu",
+ "continue": "Continuer",
+ "create": "Créer",
+ "delete": "Supprimer",
+ "discard": "Rejeter",
+ "download": "Télécharger",
+ "edit": "Éditer",
+ "editable": "Editable",
+ "filter": "Filtrer",
+ "lock": "Verrouiller",
+ "login": "Se connecter",
+ "logout": "Déconnexion",
+ "move": "Déplacer",
+ "ok": "OK",
+ "open": "Ouvrir",
+ "remove": "Retirer",
+ "rename": "Renommer",
+ "reset": "Réinitialiser",
+ "save": "Sauvegarder",
+ "saving": "En cours de sauvegarde",
+ "search": "Rechercher",
+ "submit": "Envoyer",
+ "tryagain": "Réessayer",
+ "unlock": "Déverrouiller",
+ "update": "Mise à jour"
+ },
+ "changeLanguage": "Changer de langue",
+ "collaborationAbilities": {
+ "guest": "Lecture uniquement",
+ "manager": "Lecture, écriture & administration du camp",
+ "member": "Lecture & écriture"
+ },
+ "datetime": {
+ "vuetifyTimePickerFormat": "24hr"
+ },
+ "info": {
+ "offline": {
+ "description": "Impossible d'enregistrer / de charger des données.",
+ "title": "Tu es hors ligne :"
+ }
+ },
+ "language": "Français",
+ "loading": "Chargement ...",
+ "navigation": {
+ "admin": {
+ "title": "Admin"
+ },
+ "help": "Aide",
+ "news": "Actualités"
+ },
+ "serverError": {
+ "409": "Oooops... Cette action a provoqué une erreur côté serveur.",
+ "short": "erreur de serveur"
+ },
+ "toast": {
+ "copied": "{source} copié"
+ },
+ "validation": {
+ "greaterThan": "{_field_} doit être supérieur à {min}",
+ "greaterThanOrEqual_date": "{_field_} ne peut pas être antérieure à {min}",
+ "greaterThan_time": "{_field_} doit être postérieure à {min}",
+ "lessThanOrEqual_date": "{_field_} ne peut pas être postérieure à {max}",
+ "oneEmojiOrTwoCharacters": "{_field_} ne peut avoir que 1 emoji ou 2 lettres/chiffres"
+ },
+ "warning": {
+ "delete": "Veux-tu vraiment le supprimer ? | Veux-tu vraiment supprimer \"{entity}\" ?"
+ }
+ },
+ "views": {
+ "auth": {
+ "activate": {
+ "error": "L'activation a échoué",
+ "success": "Le compte a été activé avec succès",
+ "title": "Ton compte sera activé"
+ },
+ "login": {
+ "acceptTermsOfServiceOnOAuthLogin": "En te connectant via l'un de ces services, tu acceptes les {termsOfServiceLink}.",
+ "accountless": "Vous n'avez pas encore de compte?",
+ "email": "E-mail",
+ "infoText": {
+ "dev": "Ceci est la version de développement d'eCamp v3.{br}IMPORTANT : Ceci est destiné à un usage de développement uniquement. Toutes les données sont publiques et seront supprimées périodiquement !{br}Login : test@example.com / test"
+ },
+ "loginCallback": {
+ "loginInProgress": "Vous allez être connecté"
+ },
+ "notActivated": "Pas activité ?",
+ "or": "ou avec",
+ "password": "Mot de passe",
+ "passwordForgotten": "Tu as oublié ton mot de passe ?",
+ "provider": {
+ "cevidb": "CeviDB",
+ "ecamp": "Connectez-vous avec eCamp",
+ "google": "Google",
+ "jubladb": "Jubla",
+ "midata": "MiData"
+ },
+ "registernow": "Inscrivez-vous maintenant",
+ "resendActivation": "Envoyer à nouveau l'e-mail d'activation",
+ "resetPassword": "Réinitialiser le mot de passe",
+ "termsOfServiceLink": "conditions d'utilisation"
+ },
+ "register": {
+ "acceptTermsOfService": "Accepter les conditions d'utilisation",
+ "alreadyHaveAnAccount": "Vous avez déjà un compte ?",
+ "passwordConfirmation": "Entrez à nouveau votre mot de passe",
+ "register": "S'inscrire",
+ "requiredField": "champ obligatoire",
+ "title": "Créer un compte"
+ },
+ "registerDone": {
+ "message": "Nous t'avons envoyé un e-mail. Merci de compléter ton inscription en cliquant sur le lien d'activation dans l'email.",
+ "success": "Enregistré avec succès",
+ "title": "Créer un compte"
+ },
+ "resendActivation": {
+ "errorMessage": "L'envoi de l'e-mail d'activation a échoué à nouveau.",
+ "send": "Envoyer",
+ "successMessage": "Un e-mail avec le lien pour réinitialiser le mot de passe sera envoyé.",
+ "title": "Envoyer à nouveau l'e-mail d'activation"
+ },
+ "resetPassword": {
+ "errorMessage": "La réinitialisation du mot de passe a échoué.",
+ "invalidRequest": "Lien invalide",
+ "password": "Nouveau mot de passe",
+ "passwordConfirmation": "Confirmer le nouveau mot de passe",
+ "send": "Set mot de passe",
+ "successMessage": "Le nouveau mot de passe a été défini avec succès.",
+ "title": "Réinitialiser le mot de passe"
+ },
+ "resetPasswordRequest": {
+ "errorMessage": "La réinitialisation du mot de passe a échoué.",
+ "send": "Envoyer",
+ "successMessage": "Un e-mail avec le lien pour réinitialiser le mot de passe sera envoyé.",
+ "title": "Réinitialiser le mot de passe"
+ }
+ },
+ "camp": {
+ "activity": {
+ "printPreview": "Ouvrir l'aperçu avant impression",
+ "sideBarProgram": {
+ "title": "Activités du jour"
+ }
+ },
+ "admin": {
+ "activity": {
+ "title": "Paramètres d'activité"
+ },
+ "adminMaterialLists": {
+ "title": "Listes de matériel"
+ },
+ "collaborators": {
+ "email": "Adresse e-mail",
+ "inactiveCollaborators": "Inactif",
+ "members": "Membres",
+ "openInvitations": "Invitations ouvertes",
+ "title": "Equipe"
+ },
+ "info": {
+ "title": "Infos sur le camp"
+ },
+ "print": {
+ "title": "Imprimer le camp"
+ },
+ "sideBarAdmin": {
+ "itemActivity": "Activités",
+ "itemActivitySubtitle": "Catégorie, modèles et statut",
+ "itemCollaborators": "Equipe",
+ "itemInfos": "Infos sur le camp",
+ "itemMaterialLists": "Listes de matériel",
+ "itemPrint": "PDF / Imprimer"
+ },
+ "title": "Admin"
+ },
+ "campProgram": {
+ "reminderLockedCreate": "Glisser pour créer n'est possible qu'en mode déverrouillé.",
+ "reminderLockedMove": "Glisser pour déplacer n'est possible qu'en mode déverrouillé.",
+ "title": "Programme général"
+ },
+ "category": {
+ "category": {
+ "clipboardInfoDialog": {
+ "allow": "Autoriser maintenant",
+ "denied": "Vous avez refusé l'accès à votre presse-papiers. Par conséquent, vous ne pouvez pas coller les catégories copiées.",
+ "description": "Pour coller une catégorie copiée, vous devez autoriser eCamp v3 à lire votre presse-papiers.",
+ "granted": "Vous pouvez maintenant coller les catégories copiées.",
+ "title": "Copier et coller une catégorie"
+ },
+ "deleteCategory": "Supprimer l'activité",
+ "properties": "Propriétés",
+ "template": "Modèle pour les nouvelles activités"
+ },
+ "sideBarCategory": {
+ "title": "Catégories"
+ }
+ },
+ "checklistOverview": {
+ "checklistLists": {
+ "title": "Vue d'ensemble de la check-list"
+ }
+ },
+ "dashboard": {
+ "activities": "Activités",
+ "columns": {
+ "category": "Catégorie",
+ "number": "Numéro",
+ "responsible": "Responsable",
+ "time": "Temps",
+ "title": "Titre"
+ },
+ "noEntries": "Aucune activité trouvée. Essaie d'effacer les filtres de sélection et/ou de recharger la page.",
+ "today": "Aujourd'hui",
+ "welcome": "Bienvenue dans ton nouveau camp. Il n'y a pas encore d'activités définies."
+ },
+ "invitation": {
+ "acceptCurrentAuth": "Accepter l'invitation avec le compte courant",
+ "backToHome": "Retour à l'accueil",
+ "error": "Une erreur inattendue s'est produite",
+ "notFound": "Cette invitation est déjà acceptée ou supprimée",
+ "openCamp": "Camp ouvert",
+ "register": "S'enregistrer",
+ "reject": "Refuser l'invitation",
+ "successfullyRejected": "L'invitation a été rejetée avec succès",
+ "title": "Invitation",
+ "useOtherAuth": "Déconnecte-toi et utilise un autre compte",
+ "userAlreadyInCamp": "Tu participes déjà à ce camp"
+ },
+ "material": {
+ "materialLists": {
+ "title": "Listes de matériel"
+ },
+ "materialOverview": {
+ "createNewList": "Créer une liste de matériel",
+ "download": "Télécharger l'aperçu",
+ "title": "Aperçu général"
+ },
+ "sideBarMaterialLists": {
+ "title": "Listes de matériel"
+ }
+ },
+ "navigation": {
+ "desktop": {
+ "navTopbar": {
+ "admin": "Admin",
+ "campIsLoading": "Le camp est en cours de chargement",
+ "checklist": "Check-list",
+ "material": "Matériel",
+ "print": "Imprimer",
+ "program": "Programme",
+ "story": "Histoire",
+ "team": "Team"
+ }
+ },
+ "mobile": {
+ "navBottombar": {
+ "material": "Matériel",
+ "more": "Plus",
+ "program": "Programme",
+ "story": "Histoire"
+ },
+ "navSidebar": {
+ "itemActivity": "Activités",
+ "itemActivitySubtitle": "Catégorie, modèle & statut",
+ "itemCamps": "Mes Camps",
+ "itemChecklists": "Vue d'ensemble de la check-list",
+ "itemClose": "Fermer le menu",
+ "itemCollaborators": "Team",
+ "itemInfos": "Infos sur le camp",
+ "itemMaterialLists": "Liste de matériel",
+ "itemPrinting": "PDF / Imprimer"
+ }
+ }
+ },
+ "story": {
+ "title": "Histoire"
+ }
+ },
+ "campCreate": {
+ "title": "Créer un camp"
+ },
+ "camps": {
+ "create": "Créer un camp",
+ "pastCamps": "Anciens camps",
+ "prototypeCamps": "Prototypes",
+ "title": "Mes camps"
+ },
+ "invitations": {
+ "personalInvitations": "Invitations"
+ },
+ "pageNotFound": {
+ "backToHome": "Retour à l'accueil",
+ "detail": "Hop là ! Tu t'es égaré...{br}Ce lien ne fonctionne malheureusement pas."
+ },
+ "profile": {
+ "changeEmail": "Changement",
+ "profile": "Profil"
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/locales/it-CH-scout.json b/frontend-vue3/src/locales/it-CH-scout.json
new file mode 100644
index 0000000000..410997594a
--- /dev/null
+++ b/frontend-vue3/src/locales/it-CH-scout.json
@@ -0,0 +1,24 @@
+{
+ "contentNode": {
+ "storycontext": {
+ "name": "Filo rosso"
+ }
+ },
+ "entity": {
+ "user": {
+ "fields": {
+ "nickname": "Nome del Scout"
+ }
+ }
+ },
+ "global": {
+ "language": "Italiano (Scout)"
+ },
+ "views": {
+ "camp": {
+ "story": {
+ "title": "Filo rosso"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/locales/it.json b/frontend-vue3/src/locales/it.json
new file mode 100644
index 0000000000..0abde0d6eb
--- /dev/null
+++ b/frontend-vue3/src/locales/it.json
@@ -0,0 +1,706 @@
+{
+ "components": {
+ "activity": {
+ "content": {
+ "columnLayout": {
+ "columnOperations": {
+ "addColumn": "Aggiungi una colonna",
+ "removeColumn": "Rimuovi la colonna vuota"
+ }
+ },
+ "lAThematicArea": {
+ "placeholder": "Selezionare l'area tematica"
+ },
+ "storyboard": {
+ "controls": "Azioni",
+ "reorder": "Spostare",
+ "storyboardDialogRemoveSection": {
+ "deleteWarning": "Vuoi davvero rimuovere questa sezione?",
+ "title": "Cancellare davvero?"
+ }
+ }
+ },
+ "dialog": {
+ "dialogActivityEdit": {
+ "title": "Modificare l'actività"
+ },
+ "formScheduleEntryList": {
+ "name": "Programmato"
+ }
+ },
+ "menuCardlessContentNode": {
+ "deletingDisabled": "Deve essere vuoto per essere eliminato"
+ },
+ "scheduleEntry": {
+ "backToContents": "Torna alla modifica dei contenuti",
+ "changeLayout": "Cambia il layout",
+ "clipboardInfoDialog": {
+ "allow": "Consenti ora"
+ },
+ "deleteWarning": "Vuoi davvero cancellare questa attività? Tutti i contenuti di questa attività saranno rimossi."
+ },
+ "togglePaperSize": {
+ "switchToFullSize": "Passare al formato largo",
+ "switchToPaperSize": "Passare al formato carta"
+ }
+ },
+ "camp": {
+ "campInvitations": {
+ "title": "Invitare"
+ },
+ "campMembers": {
+ "title": "Membri"
+ }
+ },
+ "campAdmin": {
+ "campActivityProgressLabels": {
+ "create": "Creare uno stato",
+ "deleteError": "Lo stato non può essere cancellato. Viene ancora utilizzato.",
+ "deleteWarning": "Vuoi davvero cancellare questo stato?",
+ "exit": "Terminare il riordino",
+ "moveDown": "Spostare in basso",
+ "moveUp": "Spostare in alto",
+ "reorder": "Riordinare",
+ "title": "Stati delle attività"
+ },
+ "campAddress": {
+ "title": "Indirizzo"
+ },
+ "campCategories": {
+ "create": "Creare categoria di attività",
+ "title": "Categorie di attività"
+ },
+ "campConditionalFields": {
+ "course": {
+ "title": "Corsi"
+ },
+ "title": "Impostazioni per G+S",
+ "ysCamp": {
+ "title": "Campi"
+ }
+ },
+ "campDangerZone": {
+ "deleteCamp": {
+ "description": "Una volta eliminato un campo, non è più possibile tornare indietro. Siate certi.",
+ "explanation": "Questa azione non può essere annullata. Questo eliminerà definitivamente il campo \"{campTitle}\", le attività, gli elenchi di materiali e rimuoverà tutte le associazioni di collaboratori.",
+ "label": "Digita \"{campTitle}\" per confermare.",
+ "title": "Elimina il campo"
+ },
+ "title": "Zona di pericolo"
+ },
+ "campMaterialLists": {
+ "createMaterialList": "Crea l'elenco dei materiali",
+ "title": "Elenchi di materiali"
+ },
+ "campPeriods": {
+ "createPeriod": "Creare il periodo",
+ "title": "Periodo | Periodi"
+ },
+ "campPeriodsListItem": {
+ "changePeriodDescription": "Cambia la descrizione",
+ "deleteWarning": "Volete davvero cancellarlo?",
+ "lastPeriodNotDeletable": "L'ultimo periodo non è cancellabile.",
+ "movePeriod": "Periodo di spostamento",
+ "periodChangeEnd": "Aggiungi/rimuovi giorni alla fine",
+ "periodChangeStart": "Aggiungi/rimuovi giorni all'inizio"
+ },
+ "campSettings": {
+ "title": "Impostazioni"
+ },
+ "createCampPeriods": {
+ "add": "Aggiungi un punto"
+ },
+ "dialogActivityProgressLabelCreate": {
+ "title": "Creare uno stato"
+ },
+ "dialogActivityProgressLabelEdit": {
+ "title": "Modificare il stato"
+ },
+ "dialogCategoryCreate": {
+ "clipboardInfoDialog": {
+ "allow": "Consenti ora"
+ },
+ "title": "Creare categoria di attività"
+ },
+ "dialogMaterialListCreate": {
+ "title": "Crea l'elenco dei materiali"
+ },
+ "dialogMaterialListEdit": {
+ "deleteError": "Impossibile eliminare l'elenco dei materiali. Controlla che l'elenco sia vuoto prima di eliminarlo.",
+ "title": "Modifica elenco materiali"
+ },
+ "dialogPeriodCreate": {
+ "title": "Creare il periodo"
+ },
+ "dialogPeriodDateEdit": {
+ "movePeriod": "Periodo di spostamento",
+ "periodChangeEnd": "Aggiungi/togli giorni alla fine di questo periodo",
+ "periodChangeStart": "Aggiungi/togli giorni all'inizio di questo periodo",
+ "periodDuration": "Numero di giorni"
+ },
+ "dialogPeriodEdit": {
+ "moveScheduleEntries": "Sposta le voci del programma"
+ },
+ "errorExistingActivitiesList": {
+ "description": "Non può essere eliminato. Ancora utilizzato dalle seguenti attività:"
+ }
+ },
+ "campCreate": {
+ "campCreate": {
+ "steps": {
+ "configurate": "Configurazione",
+ "infos": "Info",
+ "template": "Modello"
+ }
+ },
+ "campCreateStep1": {
+ "submitTooltip": "Compilare tutti i campi richiesti."
+ },
+ "campCreateStep2": {
+ "category": "Categorie di attività",
+ "create": "Creare il campo",
+ "noContent": "Nessun contenuto",
+ "noPrototype": "Nessun modello",
+ "noPrototypeAlert": {
+ "description": "È necessario effettuare tutte le impostazioni manualmente. Non sono disponibili modelli e layout di blocco. È adatto solo agli utenti esperti.",
+ "title": "Nota bene: avete scelto \"Nessun modello\"."
+ },
+ "preview": "Anteprima del modello di campo",
+ "progressLabels": "Stati di attività",
+ "prototypeHint": "Copiare le categorie, i modelli di blocco e stati di blocchi da un modello di campo.",
+ "prototypeHintEmpty": "Non copiare categorie, modelli di blocco e stati di blocco da un modello di campo.",
+ "prototypeHintSelected": "Copiate le categorie, i modelli di blocco e stati di blocchi da questo modello di campo.",
+ "submitTooltipPrototype": "È ancora necessario selezionare se e quale modello di campo si desidera utilizzare."
+ }
+ },
+ "category": {
+ "categoryTemplate": {
+ "contents": "Contenuti",
+ "createLayoutHelp": "Qui puoi definire il modello per le nuove attività {categoryShort}.{br}Il contenuto e il layout delle attività {categoryShort} già create non verranno modificati.",
+ "layout": "Layout",
+ "noTemplate": "Nessun modello"
+ }
+ },
+ "collaborator": {
+ "collaboratorCreate": {
+ "invite": "Inviare l'invito",
+ "inviteCta": "Invitare",
+ "title": "Invitare una persona"
+ },
+ "collaboratorEdit": {
+ "cannotRemoveLastManager": "Non è possibile rimuovere l'ultimo gestore.",
+ "deactivate": "Disattivare",
+ "delete": "Vuoi davvero rimuovere la persona '{name}'?",
+ "inviteAgain": "Invitare di nuovo",
+ "resendEmail": "Reinvia l'email",
+ "resentEmail": "Invito inviato",
+ "title": "Éditer {user}"
+ },
+ "collaboratorForm": {
+ "overrideAvatar": "Sovrascrivere l'avatar per questo campo",
+ "roleHint": "Ogni campo ha bisogno di almeno una persona con diritti di amministratore."
+ },
+ "promptCollaboratorDeactivate": {
+ "deactivate": "Disattivare",
+ "warningText": "Vuoi disattivare '{name}'?"
+ }
+ },
+ "dashboard": {
+ "selectFilter": {
+ "clear": "Libero"
+ }
+ },
+ "dialog": {
+ "dialogEntityDelete": {
+ "title": "Davvero cancellare?"
+ }
+ },
+ "form": {
+ "base": {
+ "eColorPicker": {
+ "closePicker": "Chiudere il dialogo",
+ "openPicker": "Apri una finestra di dialogo per selezionare un colore per {label}"
+ },
+ "eDatePicker": {
+ "invalidFormat": "Formato non valido, inserisci la data nel formato MM/GG/AAAA",
+ "openPicker": "Apri una finestra di dialogo per selezionare una data per {label}"
+ },
+ "eTimePicker": {
+ "invalidFormat": "Formato non valido, inserire l'ora nel formato HH:MM AM/PM",
+ "openPicker": "Apri una finestra di dialogo per selezionare un orario per {label}"
+ }
+ }
+ },
+ "generic": {
+ "lockButton": {
+ "clickToLock": "Clic per bloccare",
+ "clickToUnlock": "Clic per sbloccare",
+ "guestsCannotEdit": "Gli ospiti non hanno il permesso di modificare"
+ }
+ },
+ "layout": {
+ "authContainer": {
+ "photoCredits": "Foto di Markus Rohner / Lotos"
+ }
+ },
+ "material": {
+ "dialogMaterialItemCreate": {
+ "title": "Crea un oggetto materiale"
+ },
+ "dialogMaterialItemEdit": {
+ "title": "Modifica della voce materiale"
+ },
+ "materialCreateItem": {
+ "campSettingsButton": "Impostazioni",
+ "noMaterialListAvailable": "Non ci sono ancora liste di materiali per questo campo. Puoi crearle in \"Amministrazione\"."
+ },
+ "materialLists": {
+ "materialsCount": "Nessuna voce | 1 voce | {count} voci",
+ "overview": "Panoramica generale"
+ },
+ "materialTable": {
+ "addNewItem": "Aggiungi un nuovo elemento",
+ "noItems": "Nessun oggetto materiale trovato",
+ "periodOnly": "Filtro: Periodo",
+ "reference": "Attività / Periodo"
+ },
+ "useMaterialViewHelper": {
+ "detail": "Liste di materiali",
+ "overview": "Panoramica generale"
+ }
+ },
+ "navigation": {
+ "userMeta": {
+ "invitations": "Inviti",
+ "logOut": "Disconnettiti",
+ "myCamps": "I miei campi",
+ "profile": "Profilo"
+ }
+ },
+ "personalInvitations": {
+ "dialogPersonalInvitationReject": {
+ "rejectInvitation": "Rifiuta l'invito",
+ "warningText": "Volete davvero declinare l'invito al campo \"{campTitle}\"?"
+ },
+ "personalInvitations": {
+ "noOpenInvitations": "Nessun invito aperto. L'invito è stato inviato a un indirizzo diverso da \"{email}\"?"
+ }
+ },
+ "print": {
+ "config": {
+ "activityConfig": {
+ "activity": "Attività"
+ },
+ "picassoConfig": {
+ "orientation": "Layout della pagina"
+ },
+ "programConfig": {
+ "dayOverview": "Panoramica della giornata di stampa"
+ }
+ },
+ "documents": {
+ "campPrint": {
+ "filename": {
+ "activitiesOnly": "Attività {camp}",
+ "picassoOnly": "Picasso {camp}"
+ }
+ }
+ },
+ "localPdfDownloadButton": {
+ "error": "Qualcosa non ha funzionato. Riprova o ricarica la pagina."
+ },
+ "printClient": {
+ "downloadClientPdfButton": {
+ "label": "Scarica il PDF (layout #2)"
+ },
+ "downloadClientPdfListItem": {
+ "label": "Scarica il PDF (layout #2)"
+ },
+ "generatePdfMixin": {
+ "error": "Qualcosa non ha funzionato. Riprova o ricarica la pagina."
+ },
+ "printPreviewClient": {
+ "previewError": "Qualcosa non ha funzionato. Riprova con altre impostazioni di stampa o ricarica la pagina.",
+ "previewIframeTitle": "Anteprima di stampa"
+ }
+ },
+ "printConfigurator": {
+ "add": "Aggiungi contenuti",
+ "config": {
+ "Activity": "Attività singola",
+ "Cover": "Pagina di copertina",
+ "Picasso": "Picasso",
+ "Program": "Programma",
+ "SafetyConsiderations": "Considerazioni sulla sicurezza",
+ "Story": "Riassunto della storia",
+ "Toc": "Indice dei contenuti"
+ }
+ },
+ "printNuxt": {
+ "downloadNuxtPdfButton": {
+ "label": "Scarica il PDF (layout #1)"
+ },
+ "downloadNuxtPdfListItem": {
+ "label": "Scarica il PDF (layout #1)"
+ },
+ "generatePdfMixin": {
+ "error": "Qualcosa non ha funzionato. Riprova o ricarica la pagina.",
+ "queueFull": "Tutte le nostre stampanti PDF sono occupate al momento. Riprova più tardi."
+ },
+ "printPreviewNuxt": {
+ "openPreview": "Apri l'anteprima in una nuova finestra",
+ "previewError": "Qualcosa non ha funzionato. Riprova con altre impostazioni di stampa o ricarica la pagina.",
+ "previewIframeTitle": "Anteprima di stampa"
+ }
+ }
+ },
+ "program": {
+ "formScheduleEntryItem": {
+ "end": "Fine",
+ "start": "Inizio"
+ },
+ "formScheduleEntryList": {
+ "name": "Programmato"
+ },
+ "periodSwitcher": {
+ "title": "Scegli il periodo"
+ },
+ "picasso": {
+ "picasso": {
+ "datetime": {
+ "fullDate": "dd DD. MMMM YYYY",
+ "smallDate": "dd D.MM. | dd D. MMM | dd D. MMM YY"
+ }
+ },
+ "picassoEntry": {
+ "clipboardInfoDialog": {
+ "allow": "Consenti ora"
+ },
+ "location": "Luogo:",
+ "responsible": "Responsable:"
+ }
+ },
+ "scheduleEntryFilters": {
+ "category": "Categoria",
+ "clearFilters": "Cancella i filtri",
+ "onlyMyActivities": "Solo le mie attività",
+ "period": "Periodo",
+ "progressLabel": "Stati",
+ "progressLabelNone": "Nessuno stato",
+ "responsible": "Responsabile",
+ "responsibleNone": "Nessuna responsabile"
+ }
+ },
+ "prompt": {
+ "promptEntityDelete": {
+ "title": "Davvero cancellare?"
+ }
+ },
+ "story": {
+ "storyDay": {
+ "noStory": "Nessun contenuto di storia trovato in questo giorno..."
+ }
+ },
+ "toast": {
+ "toasts": {
+ "multiLineToast": {
+ "generalError": "Si è verificato un errore."
+ }
+ }
+ },
+ "user": {
+ "dialogChangeMail": {
+ "error": "Si è verificato un errore.",
+ "message": "Riceverai un'e-mail di verifica.",
+ "success": "Prima di poter utilizzare il tuo nuovo indirizzo e-mail, devi verificarlo. Controlla ora la tua casella di posta elettronica.",
+ "title": "Cambia l'indirizzo e-mail"
+ },
+ "dialogChangeMailRunning": {
+ "error": "Si è verificato un errore.",
+ "message": "Modifica dell'indirizzo e-mail ...",
+ "success": "L'indirizzo e-mail è stato modificato con successo.",
+ "title": "Modifica dell'indirizzo e-mail"
+ }
+ }
+ },
+ "global": {
+ "button": {
+ "add": "Aggiungere",
+ "back": "Indietro",
+ "cancel": "Annullare",
+ "close": "Chiudi",
+ "content": "Contenuto",
+ "continue": "Continuare",
+ "create": "Creare",
+ "delete": "Eliminare",
+ "discard": "Scartare",
+ "download": "Scaricare",
+ "edit": "Modificare",
+ "editable": "Modificabile",
+ "filter": "Filtro",
+ "lock": "Blocco",
+ "login": "Accedi",
+ "logout": "Disconnessione",
+ "move": "Spostamento",
+ "ok": "Bene",
+ "open": "Aprire",
+ "remove": "Rimuovere",
+ "rename": "Rinominare",
+ "reset": "Reset",
+ "save": "Salvare",
+ "saving": "Salvataggio",
+ "search": "Ricerca",
+ "submit": "Inviare",
+ "tryagain": "Riprovare",
+ "unlock": "Sblocca",
+ "update": "Aggiornare"
+ },
+ "changeLanguage": "Cambia lingua",
+ "collaborationAbilities": {
+ "guest": "Solo lettura",
+ "manager": "Lettura, scrittura e amministrazione del campo",
+ "member": "Lettura e scrittura"
+ },
+ "datetime": {
+ "vuetifyTimePickerFormat": "24hr"
+ },
+ "info": {
+ "offline": {
+ "description": "Impossibile salvare/caricare dati.",
+ "title": "Sei offline:"
+ }
+ },
+ "language": "Italiano",
+ "loading": "Caricamento ...",
+ "navigation": {
+ "admin": {
+ "title": "Admin"
+ },
+ "help": "Aiuto",
+ "news": "Notizie"
+ },
+ "serverError": {
+ "409": "Oooops... Questa azione ha causato un errore sul lato server.",
+ "short": "Errore del server"
+ },
+ "validation": {
+ "greaterThan": "{_field_} deve essere maggiore di {min}",
+ "greaterThanOrEqual_date": "{_field_} non può essere prima che {min}",
+ "greaterThan_time": "{_camp_} deve essere posteriore a {min}",
+ "lessThanOrEqual_date": "{_camp_} non può essere successivo a {max}",
+ "oneEmojiOrTwoCharacters": "{_field_} può contenere solo 1 emoji o 2 lettere/numeri"
+ },
+ "warning": {
+ "delete": "Volete davvero cancellarlo? | Volete davvero cancellarlo \"{entity}\"?"
+ }
+ },
+ "views": {
+ "auth": {
+ "activate": {
+ "error": "Attivazione fallita",
+ "success": "L'account è stato attivato con successo",
+ "title": "Il tuo account sarà attivato"
+ },
+ "login": {
+ "acceptTermsOfServiceOnOAuthLogin": "Effettuando l'accesso tramite uno di questi servizi, si accettano i {termsOfServiceLink}.",
+ "accountless": "Non hanno ancora un conto?",
+ "email": "Indirizzo e-mail",
+ "infoText": {
+ "dev": "Questa è la versione di sviluppo di eCamp v3.{br}IMPORTANTE: è destinata esclusivamente all'uso per lo sviluppo. Tutti i dati sono pubblici e verranno cancellati periodicamente!{br}Login: test@example.com / test"
+ },
+ "loginCallback": {
+ "loginInProgress": "Sarai loggato"
+ },
+ "or": "oppure con",
+ "password": "Parola d'ordine",
+ "passwordForgotten": "Hai dimenticato la password?",
+ "provider": {
+ "cevidb": "CeviDB",
+ "ecamp": "Accedi con eCamp",
+ "google": "Google",
+ "jubladb": "JublaDB",
+ "midata": "MiData"
+ },
+ "registernow": "Iscriviti ora",
+ "termsOfServiceLink": "condizioni di utilizzo"
+ },
+ "register": {
+ "acceptTermsOfService": "Accettare le condizioni di utilizzo",
+ "alreadyHaveAnAccount": "Hai già un conto?",
+ "passwordConfirmation": "Inserisci di nuovo la password",
+ "register": "Registrati",
+ "requiredField": "campo obbligatorio",
+ "title": "Crea un conto"
+ },
+ "registerDone": {
+ "message": "Ti abbiamo inviato un'e-mail. Completa la tua registrazione cliccando sul link di attivazione contenuto nell'e-mail.",
+ "success": "Registrato con successo",
+ "title": "Crea un conto"
+ },
+ "resetPassword": {
+ "errorMessage": "La reimpostazione della password è fallita.",
+ "invalidRequest": "Link non valido",
+ "password": "Nuova password",
+ "passwordConfirmation": "Nuova password",
+ "send": "Imposta la password",
+ "successMessage": "La nuova password è stata impostata con successo.",
+ "title": "Reimposta la password"
+ },
+ "resetPasswordRequest": {
+ "errorMessage": "La reimpostazione della password è fallita.",
+ "send": "Invia",
+ "successMessage": "Verrà recapitata una mail con il link per reimpostare la password.",
+ "title": "Reimposta la password"
+ }
+ },
+ "camp": {
+ "activity": {
+ "printPreview": "Apri l'anteprima di stampa",
+ "sideBarProgram": {
+ "title": "Attività in questo giorno"
+ }
+ },
+ "admin": {
+ "activity": {
+ "title": "Impostazioni dell'attività"
+ },
+ "adminMaterialLists": {
+ "title": "Liste di materiali"
+ },
+ "collaborators": {
+ "email": "Indirizzo e-mail",
+ "inactiveCollaborators": "Inattivo",
+ "members": "Membri",
+ "openInvitations": "Inviti aperti",
+ "title": "Team"
+ },
+ "info": {
+ "title": "Info sul campo"
+ },
+ "print": {
+ "title": "Stampa il campo"
+ },
+ "sideBarAdmin": {
+ "itemActivity": "Attività",
+ "itemActivitySubtitle": "Categoria, modello, stati",
+ "itemCollaborators": "Team",
+ "itemInfos": "Info sul campo",
+ "itemMaterialLists": "Liste di materiali",
+ "itemPrint": "PDF / Stampa"
+ },
+ "title": "Admin"
+ },
+ "campProgram": {
+ "reminderLockedCreate": "Trascinare per creare è possibile solo in modalità sbloccata.",
+ "reminderLockedMove": "Trascinare per spostarsi è possibile solo in modalità sbloccata.",
+ "title": "Picasso"
+ },
+ "category": {
+ "category": {
+ "clipboardInfoDialog": {
+ "allow": "Consenti ora"
+ },
+ "deleteCategory": "Elimina la categoria",
+ "properties": "Proprietà",
+ "template": "Modello per le nuove attività"
+ },
+ "sideBarCategory": {
+ "title": "Categorie"
+ }
+ },
+ "dashboard": {
+ "activities": "Attività",
+ "columns": {
+ "category": "Categoria",
+ "number": "Numero",
+ "responsible": "Responsabile",
+ "time": "Tempo",
+ "title": "Titolo"
+ },
+ "noEntries": "Non sono state trovate attività. Prova a cancellare i filtri di selezione e/o a ricaricare la pagina.",
+ "today": "Oggi",
+ "welcome": "Benvenuto nel tuo nuovo campo. Non ci sono ancora attività definite."
+ },
+ "invitation": {
+ "acceptCurrentAuth": "Accetta l'invito con un conto corrente",
+ "backToHome": "Torna a casa",
+ "error": "Si è verificato un errore inatteso",
+ "notFound": "Questo invito è già stato accettato o cancellato",
+ "openCamp": "Campo aperto",
+ "register": "Registro",
+ "reject": "Rifiuta l'invito",
+ "successfullyRejected": "L'invito è stato rifiutato con successo",
+ "title": "Invito",
+ "useOtherAuth": "Esci e usa un altro account",
+ "userAlreadyInCamp": "Stai già partecipando a questo campo"
+ },
+ "material": {
+ "materialLists": {
+ "title": "Liste di materiali"
+ },
+ "materialOverview": {
+ "createNewList": "Creare un elenco di materiali",
+ "download": "Scarica la panoramica",
+ "title": "Panoramica generale"
+ },
+ "sideBarMaterialLists": {
+ "title": "Liste di materiali"
+ }
+ },
+ "navigation": {
+ "desktop": {
+ "navTopbar": {
+ "admin": "Admin",
+ "campIsLoading": "Il campo sta caricando",
+ "material": "Material",
+ "print": "Stampa",
+ "program": "Programm",
+ "story": "Storia",
+ "team": "Team"
+ }
+ },
+ "mobile": {
+ "navBottombar": {
+ "material": "Materiale",
+ "more": "Più",
+ "program": "Programma",
+ "story": "Storia"
+ },
+ "navSidebar": {
+ "itemActivity": "Attività",
+ "itemActivitySubtitle": "Categoria, modello, stati",
+ "itemCamps": "I miei campi",
+ "itemClose": "Chiudere il menu",
+ "itemCollaborators": "Team",
+ "itemInfos": "Info sul campo",
+ "itemMaterialLists": "Liste di materiali",
+ "itemPrinting": "PDF / Stampa"
+ }
+ }
+ },
+ "story": {
+ "title": "Storia"
+ }
+ },
+ "campCreate": {
+ "title": "Creare il campo"
+ },
+ "camps": {
+ "create": "Creare il campo",
+ "pastCamps": "Campi passati",
+ "prototypeCamps": "Prototipi",
+ "title": "I miei campi"
+ },
+ "invitations": {
+ "personalInvitations": "Inviti"
+ },
+ "pageNotFound": {
+ "backToHome": "Torna a casa",
+ "detail": "Ops. Hai perso la strada…{br}Purtroppo questo link non funziona."
+ },
+ "profile": {
+ "changeEmail": "Cambiamento",
+ "profile": "Profilo"
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/locales/rm-CH-scout.json b/frontend-vue3/src/locales/rm-CH-scout.json
new file mode 100644
index 0000000000..873a2203c2
--- /dev/null
+++ b/frontend-vue3/src/locales/rm-CH-scout.json
@@ -0,0 +1,24 @@
+{
+ "contentNode": {
+ "storycontext": {
+ "name": "Fil cotschen"
+ }
+ },
+ "entity": {
+ "user": {
+ "fields": {
+ "nickname": "Num da battasendas"
+ }
+ }
+ },
+ "global": {
+ "language": "Rumantsch (Battasendas)"
+ },
+ "views": {
+ "camp": {
+ "story": {
+ "title": "Fil cotschen"
+ }
+ }
+ }
+}
diff --git a/frontend-vue3/src/locales/rm.json b/frontend-vue3/src/locales/rm.json
new file mode 100644
index 0000000000..10f235f61b
--- /dev/null
+++ b/frontend-vue3/src/locales/rm.json
@@ -0,0 +1,644 @@
+{
+ "components": {
+ "activity": {
+ "content": {
+ "columnLayout": {
+ "columnOperations": {
+ "addColumn": "Agiuntar ina colonna",
+ "removeColumn": "Stizzar la colonna vida"
+ }
+ },
+ "storyboard": {
+ "controls": "Acziuns",
+ "reorder": "Spustar",
+ "storyboardDialogRemoveSection": {
+ "deleteWarning": "Vuls ti propi stizzar questa part?",
+ "title": "Propi stizzar?"
+ }
+ }
+ },
+ "dialog": {
+ "dialogActivityEdit": {
+ "title": "Modifitgar l'activitad"
+ },
+ "formScheduleEntryList": {
+ "name": "Termins planisads"
+ }
+ },
+ "menuCardlessContentNode": {
+ "deletingDisabled": "Sto esser vid per stizzar"
+ },
+ "scheduleEntry": {
+ "backToContents": "Enavos per modifitgar il cuntegn",
+ "changeLayout": "Midar il layout",
+ "deleteWarning": "Vuls ti propi stizzar questa activitad? I vegn stizzà l'entir cuntegn da l'activitad."
+ }
+ },
+ "camp": {
+ "campInvitations": {
+ "title": "Invit"
+ },
+ "campMembers": {
+ "title": "Commembers"
+ }
+ },
+ "campAdmin": {
+ "campActivityProgressLabels": {
+ "create": "Crear in status",
+ "deleteError": "Impussibel da stizzar il status. Il status vegn anc utilisà.",
+ "deleteWarning": "Vuls ti propi stizzar quest status?",
+ "exit": "Terminar il reordinar",
+ "moveDown": "Engiu",
+ "moveUp": "Ensi",
+ "reorder": "Reordinatur",
+ "title": "Status da l'activitad"
+ },
+ "campAddress": {
+ "title": "Adressa dal champ"
+ },
+ "campCategories": {
+ "create": "Crear ina categoria dad activitad",
+ "title": "Categorias d'activitads"
+ },
+ "campConditionalFields": {
+ "course": {
+ "title": "Curs"
+ },
+ "title": "Parameters per G+S",
+ "ysCamp": {
+ "title": "Champs"
+ }
+ },
+ "campDangerZone": {
+ "deleteCamp": {
+ "description": "Sche ti stizzas in champ è quai definitiv. Cuntinuescha mo sche ti es segir.",
+ "explanation": "Questa acziun na po betg vegnir revocada. Uschia vegn il champ \"{campTitle}\" stizzà permanentamain cun tut sias activitads, glistas da material ed urdens da responsabladad.",
+ "label": "Endatescha \"{campTitle}\" per confermar.",
+ "title": "Stizzar il champ"
+ },
+ "title": "Zona da privel"
+ },
+ "campMaterialLists": {
+ "createMaterialList": "Crear ina glista da material",
+ "title": "Glistas da material"
+ },
+ "campPeriods": {
+ "createPeriod": "Crear ina part dal champ",
+ "title": "Part dal champ | Parts dal champ"
+ },
+ "campPeriodsListItem": {
+ "changePeriodDescription": "Midar la descripziun",
+ "deleteWarning": "Vuls ti propi stizzar questa part?",
+ "lastPeriodNotDeletable": "Impussibel da stizzar l'ultima part.",
+ "movePeriod": "Spustar questa part dal champ",
+ "periodChangeEnd": "Agiuntar/allontanar dis a la fin",
+ "periodChangeStart": "Agiuntar/allontanar dis a l'entschatta"
+ },
+ "campSettings": {
+ "title": "Descripziun"
+ },
+ "createCampPeriods": {
+ "add": "Agiuntar in ulteriura part dal champ"
+ },
+ "dialogActivityProgressLabelCreate": {
+ "title": "Crear in status"
+ },
+ "dialogActivityProgressLabelEdit": {
+ "title": "Modifitgar il status"
+ },
+ "dialogCategoryCreate": {
+ "title": "Crear ina categoria d'activitad"
+ },
+ "dialogMaterialListCreate": {
+ "title": "Crear ina glista da material"
+ },
+ "dialogMaterialListEdit": {
+ "deleteError": "Impussibel da stizzar la glista da material. Verifitgescha che la glista è vida avant che stizzar.",
+ "title": "Modifitgar la glista da material"
+ },
+ "dialogPeriodCreate": {
+ "title": "Craer ina part dal champ"
+ },
+ "dialogPeriodDateEdit": {
+ "movePeriod": "Spustar la part dal champ",
+ "periodChangeEnd": "Agiuntar/allontanar dis a la fin da la part dal champ",
+ "periodChangeStart": "Agiuntar/allontanar dis a l'entschatta da la part dal champ",
+ "periodDuration": "Dumber da dis"
+ },
+ "dialogPeriodEdit": {
+ "moveScheduleEntries": "Spustar las activitads"
+ },
+ "errorExistingActivitiesList": {
+ "description": "I na po betg vegnir extendì. Las suandantas activitads vegnan anc utilisadas:"
+ }
+ },
+ "category": {
+ "categoryTemplate": {
+ "contents": "Cuntegns",
+ "createLayoutHelp": "Qua pudais vus definir il project per novas activitads da {categoryShort}.{br}Il cuntegn ed il layout ch'èn gia vegnidas fatgas da {categoryShort} na vegnan betg adattads.",
+ "layout": "Layout",
+ "noTemplate": "Nagin model"
+ }
+ },
+ "collaborator": {
+ "collaboratorCreate": {
+ "invite": "Trametter l'invitaziun",
+ "inviteCta": "Envidar en il team",
+ "title": "Envidar ina persuna"
+ },
+ "collaboratorEdit": {
+ "cannotRemoveLastManager": "Ti na pos betg deactivar l'ultima persuna cun dretgs d'administraziun.",
+ "deactivate": "Deactivar",
+ "delete": "Vuls ti propi allontanar la persuna '{name}'?",
+ "inviteAgain": "Envidar anc ina giada",
+ "resendEmail": "Trametter anc ina giada l'e-mail",
+ "resentEmail": "Tramess l'invit",
+ "title": "Modifitgar {user}"
+ },
+ "collaboratorForm": {
+ "roleHint": "Mintga champ dovra almain ina persuna cun dretgs d'administraziun."
+ },
+ "promptCollaboratorDeactivate": {
+ "deactivate": "Deactivar",
+ "warningText": "Vuls ti propi deactivar '{name}'?"
+ }
+ },
+ "dashboard": {
+ "selectFilter": {
+ "clear": "Reinizialisar"
+ }
+ },
+ "dialog": {
+ "dialogEntityDelete": {
+ "title": "Propi stizzar?"
+ }
+ },
+ "form": {
+ "base": {
+ "eColorPicker": {
+ "closePicker": "Terminar il dialog",
+ "openPicker": "Avrir il dialog per tscherner ina colur per {label}"
+ },
+ "eDatePicker": {
+ "invalidFormat": "Format nunvalid, inditgescha per plaschair la data en il format DD-MM-YYYY",
+ "openPicker": "Avrir il dialog per tscherner ina data per {label}"
+ },
+ "eTimePicker": {
+ "invalidFormat": "Format nunvalid, inditgescha per plaschair il temp en il format HH:MM",
+ "openPicker": "Avrir il dialog per tscherner in temp per {label}"
+ }
+ }
+ },
+ "generic": {
+ "lockButton": {
+ "clickToLock": "Cliccar per bloccar",
+ "clickToUnlock": "Cliccar per debloccar",
+ "guestsCannotEdit": "Giasts na pon betg modifitgar"
+ }
+ },
+ "layout": {
+ "authContainer": {
+ "photoCredits": "Foto da Markus Rohner / Lotos"
+ }
+ },
+ "material": {
+ "dialogMaterialItemCreate": {
+ "title": "Crear ina endataziun da material"
+ },
+ "dialogMaterialItemEdit": {
+ "title": "Modifitgar l'endataziun da material"
+ },
+ "materialCreateItem": {
+ "campSettingsButton": "Parameters",
+ "noMaterialListAvailable": "Per quest champ n'èn anc endatadas naginas glistas da material. Ti las pos endatar sut 'Admin'."
+ },
+ "materialLists": {
+ "materialsCount": "Naginas endataziuns | 1 endataziun | {count} endataziuns",
+ "overview": "Survista"
+ },
+ "materialTable": {
+ "addNewItem": "Agiuntar ina endataziun",
+ "noItems": "Na chattà naginas endataziuns",
+ "periodOnly": "Filter: part dal champ",
+ "reference": "Activitad / part"
+ },
+ "useMaterialViewHelper": {
+ "detail": "Glista da material",
+ "overview": "Survista"
+ }
+ },
+ "navigation": {
+ "userMeta": {
+ "invitations": "Invitaziuns",
+ "logOut": "Sortir",
+ "myCamps": "Mes champ",
+ "profile": "Profil"
+ }
+ },
+ "personalInvitations": {
+ "dialogPersonalInvitationReject": {
+ "rejectInvitation": "Refusar l'invit",
+ "warningText": "Vulais Vus propi refusar l'invitaziun al champ \"{campTitle}\"?"
+ },
+ "personalInvitations": {
+ "noOpenInvitations": "Naginas invitaziuns avertas. È l'invitaziun vegnida tramessa ad in'autra adressa che \"{email}\"?"
+ }
+ },
+ "print": {
+ "config": {
+ "activityConfig": {
+ "activity": "Activitad"
+ },
+ "picassoConfig": {
+ "orientation": "Layout da la pagina"
+ },
+ "programConfig": {
+ "dayOverview": "Survista dal di"
+ }
+ },
+ "documents": {
+ "campPrint": {
+ "filename": {
+ "activitiesOnly": "Activitads {camp}",
+ "picassoOnly": "Program general {camp}"
+ }
+ }
+ },
+ "localPdfDownloadButton": {
+ "error": "Insatge n'ha betg funcziunà. Emprova anc ina giada u rechargia la pagina."
+ },
+ "printClient": {
+ "downloadClientPdfButton": {
+ "label": "Telechargiar il PDF (layout #2)"
+ },
+ "downloadClientPdfListItem": {
+ "label": "Telechargiar il PDF (layout #2)"
+ },
+ "generatePdfMixin": {
+ "error": "Insatge n'ha betg funcziunà. Emprova anc ina giada u rechargia la pagina."
+ },
+ "printPreviewClient": {
+ "previewError": "Insatge n'ha betg funcziunà. Emprova anc ina giada cun auters parameters da stampa u rechargia la pagina.",
+ "previewIframeTitle": "Prevista da stampa"
+ }
+ },
+ "printConfigurator": {
+ "add": "Agiuntar cuntegn",
+ "config": {
+ "Activity": "Singula activitad",
+ "Cover": "Pagina da titel",
+ "Picasso": "Program general",
+ "Program": "Program en detagl",
+ "Story": "Fil cotschen",
+ "Toc": "Tavla da cuntegn"
+ }
+ },
+ "printNuxt": {
+ "downloadNuxtPdfButton": {
+ "label": "Telechargiar il PDF (layout #1)"
+ },
+ "downloadNuxtPdfListItem": {
+ "label": "Telechargiar il PDF (layout #1)"
+ },
+ "generatePdfMixin": {
+ "error": "Insatge n'ha betg funcziunà. Emprova anc ina giada u rechargia la pagina.",
+ "queueFull": "Tut noss stampaders da PDF èn occupads per il mument. Emprova per plaschair pli tard anc ina giada."
+ },
+ "printPreviewNuxt": {
+ "openPreview": "Avrir la prevista en ina nova fanestra",
+ "previewError": "Insatge n'ha betg funcziunà. Emprova anc ina giada cun auters parameters da stampa u rechargia la pagina.",
+ "previewIframeTitle": "Prevista da stampa"
+ }
+ }
+ },
+ "program": {
+ "formScheduleEntryItem": {
+ "end": "Fin",
+ "start": "Entschatta"
+ },
+ "formScheduleEntryList": {
+ "name": "Termins planisads"
+ },
+ "periodSwitcher": {
+ "title": "Tscherner ina part dal champ"
+ },
+ "picasso": {
+ "picasso": {
+ "datetime": {
+ "fullDate": "dd, DD. MMMM YYYY",
+ "smallDate": "dd, D.MM. | dd, D. MMM | dd, D. MMM YY"
+ }
+ },
+ "picassoEntry": {
+ "location": "Lieu:",
+ "responsible": "Responsabel: "
+ }
+ },
+ "scheduleEntryFilters": {
+ "category": "Categoria",
+ "clearFilters": "Allontanar il filter",
+ "onlyMyActivities": "Mo mias activitads",
+ "period": "Part dal champ",
+ "progressLabel": "Status",
+ "progressLabelNone": "Nagin status",
+ "responsible": "Responsabel",
+ "responsibleNone": "Naginas persunas responsablas"
+ }
+ },
+ "prompt": {
+ "promptEntityDelete": {
+ "title": "Propi stizzar?"
+ }
+ },
+ "toast": {
+ "toasts": {
+ "multiLineToast": {
+ "generalError": "I ha dà in sbagl."
+ }
+ }
+ },
+ "user": {
+ "dialogChangeMail": {
+ "error": "Deplorablamain hai dà in sbagl.",
+ "message": "Per la verificaziun ta tramettain nus in e-mail.",
+ "success": "Avant che ti pos utilisar la nova adressa dad e-mail, stos ti la verifitgar. Controllescha tia posta entrada.",
+ "title": "Midar l'adressa dad e-mail"
+ },
+ "dialogChangeMailRunning": {
+ "error": "Deplorablamain hai dà in sbagl.",
+ "message": "L'adressa dad e-mail vegn midada...",
+ "success": "Midà cun success l'adressa dad e-mail.",
+ "title": "Midar l'adressa dad e-mail"
+ }
+ }
+ },
+ "global": {
+ "button": {
+ "add": "Agiuntar",
+ "back": "Enavos",
+ "cancel": "Interrumper",
+ "close": "Serrar",
+ "content": "Cuntegn",
+ "create": "Crear",
+ "delete": "Stizzar",
+ "discard": "Sbittar",
+ "download": "Telechargiar",
+ "edit": "Modifitgar",
+ "editable": "Modifitgabel",
+ "filter": "Filtrar",
+ "lock": "Bloccar",
+ "login": "S'annunziar",
+ "logout": "Sortir",
+ "move": "Spustar",
+ "ok": "OK",
+ "open": "Avrir",
+ "remove": "Allontanar",
+ "rename": "Renumnar",
+ "reset": "Reparter",
+ "save": "Memorisar",
+ "saving": "Memorisà",
+ "search": "Tschertgar",
+ "submit": "Trametter",
+ "tryagain": "Empruvar anc ina giada",
+ "unlock": "Debloccar",
+ "update": "Actualisar"
+ },
+ "changeLanguage": "Midar la lingua",
+ "collaborationAbilities": {
+ "guest": "Dretg mo per lectura",
+ "manager": "Administraziun cumpletta dal champ, sco era dretg da leger e scriver",
+ "member": "Dretg da leger e scriver"
+ },
+ "datetime": {
+ "vuetifyTimePickerFormat": "24 h"
+ },
+ "info": {
+ "offline": {
+ "description": "Salvament/chargiament da datas nu è pussaivel.",
+ "title": "Ti es offline:"
+ }
+ },
+ "language": "Rumantsch",
+ "loading": "Chargiar…",
+ "navigation": {
+ "admin": {
+ "title": "Admin"
+ },
+ "help": "Agid",
+ "news": "Noviteds"
+ },
+ "serverError": {
+ "409": "Uuuups... Questa acziun ha chaschunà ina errur sin il server."
+ },
+ "validation": {
+ "greaterThanOrEqual_date": "{_field_} na dastga betg esser avant {min}",
+ "greaterThan_time": "{_field_} sto esser suenter {min}",
+ "lessThanOrEqual_date": "{_field_} na dastga betg esser suenter {max}"
+ },
+ "warning": {
+ "delete": "Vuls ti propi stizzar quai? | Vuls ti propi stizzar \"{entity}\"?"
+ }
+ },
+ "views": {
+ "auth": {
+ "activate": {
+ "error": "L'activaziun n'è betg reussida",
+ "success": "Activà cun success il conto",
+ "title": "Tes conto vegn activà"
+ },
+ "login": {
+ "acceptTermsOfServiceOnOAuthLogin": "Cun s'annunziar via in da quests servetschs acceptas ti las {termsOfServiceLink}.",
+ "accountless": "N'has ti anc nagin conto?",
+ "email": "E-mail",
+ "infoText": {
+ "dev": "Quai è la versiun per sviluppaders dad eCamp v3.{br}IMPURTANT: Mo adattà per il diever da sviluppaders. Tut las datas èn publicas e vegnan stizzadas regularmain!{br}Annunzia: test@example.com / test"
+ },
+ "loginCallback": {
+ "loginInProgress": "Ti vegns annunzià"
+ },
+ "or": "u cun",
+ "password": "pled-clav",
+ "passwordForgotten": "Emblidà il pled-clav?",
+ "provider": {
+ "cevidb": "CeviDB",
+ "ecamp": "S'annunziar cun eCamp",
+ "google": "Google",
+ "jubladb": "JublaDB",
+ "midata": "MiData"
+ },
+ "registernow": "Ussa sa registrar",
+ "termsOfServiceLink": "cundiziuns d'utilisaziun"
+ },
+ "register": {
+ "acceptTermsOfService": "Acceptar las cundiziuns d'utilisaziun",
+ "alreadyHaveAnAccount": "Has ti gia in conto?",
+ "passwordConfirmation": "Endatar anc ina giada il pled-clav",
+ "register": "Registrar",
+ "requiredField": "Champs obligatorics",
+ "title": "Crear in conto"
+ },
+ "registerDone": {
+ "message": "Nus avain ta tramess in e-mail. Terminescha per plaschair la registraziun cun avrir la colliaziun d'activaziun en l'e-mail.",
+ "success": "Registrà cun success",
+ "title": "Crear in conto"
+ },
+ "resetPassword": {
+ "errorMessage": "Impussibel da midar il pled-clav.",
+ "invalidRequest": "Colliaziun nunvalida",
+ "password": "Nov pled-clav",
+ "passwordConfirmation": "Repeter il nov pled-clav",
+ "send": "Definir il pled-clav",
+ "successMessage": "Definì cun success il nov pled-clav.",
+ "title": "Definir in nov pled-clav"
+ },
+ "resetPasswordRequest": {
+ "errorMessage": "Impussibel da reinizialisar il pled-clav.",
+ "send": "Trametter",
+ "successMessage": "In e-mail cun la colliaziun per 'reinizialisar il pled-clav' vegn tramess.",
+ "title": "Reinizialisar il pled-clav"
+ }
+ },
+ "camp": {
+ "activity": {
+ "printPreview": "Avrir la prevista da stampa",
+ "sideBarProgram": {
+ "title": "Survista dal di"
+ }
+ },
+ "admin": {
+ "activity": {
+ "title": "Parameters dad activitad"
+ },
+ "adminMaterialLists": {
+ "title": "Glistas da material"
+ },
+ "collaborators": {
+ "email": "Adressa dad e-mail",
+ "inactiveCollaborators": "Inactiv",
+ "members": "Collavuratur*as",
+ "openInvitations": "Invits averts",
+ "title": "Team"
+ },
+ "info": {
+ "title": "Infus dal champ"
+ },
+ "print": {
+ "title": "Stampar il champ"
+ },
+ "sideBarAdmin": {
+ "itemActivity": "Activitads",
+ "itemActivitySubtitle": "Categoria, model e status",
+ "itemCollaborators": "Team",
+ "itemInfos": "Infus dal champ",
+ "itemMaterialLists": "Glistas da material",
+ "itemPrint": "PDF / stampar"
+ },
+ "title": "Admin"
+ },
+ "campProgram": {
+ "reminderLockedCreate": "Trair per crear è mo pussaivel en il modus debloccà.",
+ "reminderLockedMove": "Trair per spustar è mo pussaivel en il modus debloccà.",
+ "title": "Program general"
+ },
+ "category": {
+ "category": {
+ "deleteCategory": "Stizzar la categoria",
+ "properties": "Proprietad",
+ "template": "Model per novas activitads"
+ },
+ "sideBarCategory": {
+ "title": "Categorias"
+ }
+ },
+ "dashboard": {
+ "activities": "Activitads",
+ "columns": {
+ "category": "Categoria",
+ "number": "Numer",
+ "responsible": "Responsabel",
+ "time": "Temp",
+ "title": "Titel"
+ },
+ "noEntries": "Chattà naginas activitads. Emprova dad allontanar ils filters u rechargia la pagina.",
+ "welcome": "Bainvegni en tes nov champ. Anc n'èn vegnidas endatadas naginas activitads."
+ },
+ "invitation": {
+ "acceptCurrentAuth": "Acceptar l'invit cun il conto actual",
+ "backToHome": "Enavos a la pagina da partenza",
+ "error": "Ina errur nunspetgada è succedida",
+ "notFound": "L'invit è gia acceptà u stizzà",
+ "openCamp": "Avrir il champ",
+ "register": "Registrar",
+ "reject": "Refusar l'invit",
+ "successfullyRejected": "L'invit è vegnì refusà cun success",
+ "title": "Invit",
+ "useOtherAuth": "Sortir ed utilisar in auter conto",
+ "userAlreadyInCamp": "Ti collavureschas gia en quest champ"
+ },
+ "material": {
+ "materialOverview": {
+ "createNewList": "Crear ina glista da material",
+ "download": "Telechargiar la survista",
+ "title": "Survista"
+ },
+ "sideBarMaterialLists": {
+ "title": "Glistas da material"
+ }
+ },
+ "navigation": {
+ "desktop": {
+ "navTopbar": {
+ "admin": "Admin",
+ "campIsLoading": "Il champ vegn chargià",
+ "material": "Material",
+ "print": "Stampar",
+ "program": "Program",
+ "story": "Istorgia",
+ "team": "Team"
+ }
+ },
+ "mobile": {
+ "navBottombar": {
+ "material": "Material",
+ "more": "Dapli",
+ "program": "Program",
+ "story": "Istorgia"
+ },
+ "navSidebar": {
+ "itemActivity": "Activitads",
+ "itemActivitySubtitle": "Categoria, models e status",
+ "itemCamps": "Mes champs",
+ "itemClose": "Serrar il menu",
+ "itemCollaborators": "Team",
+ "itemInfos": "Infus dal champ",
+ "itemMaterialLists": "Glistas da material",
+ "itemPrinting": "PDF / stampar"
+ }
+ }
+ },
+ "story": {
+ "title": "Istorgia"
+ }
+ },
+ "campCreate": {
+ "title": "Crear in champ"
+ },
+ "camps": {
+ "create": "Crear il champ",
+ "pastCamps": "Champs vegls",
+ "prototypeCamps": "Models",
+ "title": "Mes champs"
+ },
+ "invitations": {
+ "personalInvitations": "Invitaziuns"
+ },
+ "pageNotFound": {
+ "backToHome": "Enavos a la pagina da partenza",
+ "detail": "Hopla. Ti has pers la via…{br}Questa colliaziun na funcziuna deplorablamain betg."
+ },
+ "profile": {
+ "changeEmail": "Midar",
+ "profile": "Profil"
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend-vue3/src/main.js b/frontend-vue3/src/main.js
new file mode 100644
index 0000000000..063822df66
--- /dev/null
+++ b/frontend-vue3/src/main.js
@@ -0,0 +1,67 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from '@/router.js'
+import {
+ auth,
+ color,
+ dayjs,
+ formBaseComponents,
+ i18n,
+ storeLoader,
+ veeValidate,
+ vuetifyLoader,
+} from './plugins'
+import Toast from 'vue-toastification'
+import 'vue-toastification/dist/index.css'
+
+import { ClickOutside, Resize } from 'vuetify/directives'
+import ResizeObserver from 'v-resize-observer'
+
+import '@/scss/global.scss'
+import '@/scss/tailwind.scss'
+
+const app = createApp(App)
+
+// const env = getEnv()
+// if (env && env.SENTRY_FRONTEND_DSN) {
+// const sentryEnvironment = env.SENTRY_ENVIRONMENT ?? 'local'
+// Sentry.init({
+// Vue,
+// dsn: env.SENTRY_FRONTEND_DSN,
+// environment: sentryEnvironment,
+// enableTracing: false,
+// autoSessionTracking: false,
+// logErrors: process.env.NODE_ENV !== 'production',
+// })
+// }
+
+app.use(auth)
+app.use(formBaseComponents)
+// app.use(ignoreNativeBindingWarnMessages)
+app.use(storeLoader)
+app.use(vuetifyLoader)
+app.use(dayjs)
+app.use(color)
+//app.use(veeValidate)
+app.use(Toast, {
+ maxToasts: 2,
+})
+app.use(router)
+app.use(i18n)
+
+// manually importing necessary vuetify directives (there's no auomatic vuetify-loader for vitejs)
+app.directive('click-outside', ClickOutside)
+app.directive('resize', Resize)
+app.directive('resizeobserver', ResizeObserver.directive)
+
+// new Vue({
+// router,
+// store,
+// vuetify,
+// i18n,
+// render: (h) => h(App),
+// }).$mount('#app')'
+
+app.mount('#app')
+
+export default app
diff --git a/frontend-vue3/src/mixins/apiPropsMixin.js b/frontend-vue3/src/mixins/apiPropsMixin.js
new file mode 100644
index 0000000000..8f9db65bcc
--- /dev/null
+++ b/frontend-vue3/src/mixins/apiPropsMixin.js
@@ -0,0 +1,55 @@
+export const apiPropsMixin = {
+ inheritAttrs: false,
+ inject: {
+ apiUri: { default: null },
+ },
+ props: {
+ /* value is not required; by default value is read directly from api */
+ value: { required: false, default: null },
+
+ /* field path and URI for saving back to API */
+ path: { type: String, required: true },
+
+ /* load devault value from apiObject (via ApiForm injection) */
+ uri: {
+ type: String,
+ required: false,
+ default() {
+ if (this.apiUri === null) {
+ throw new Error(
+ 'ApiWrapper: `uri` not set on component; no ApiForm component found as parent for fallback'
+ )
+ }
+ return this.apiUri
+ },
+ },
+
+ /* overrideDirty=true will reset the input if 'value' changes, even if the input is dirty. Use with caution. */
+ overrideDirty: { type: Boolean, default: false, required: false },
+
+ /* enable/disable edit mode */
+ readonly: { type: Boolean, required: false, default: false }, // vuetify readonly: same look and feel as normal, but no changes possible
+ disabled: { type: Boolean, required: false, default: false }, // vuetify disabled: input greyed out, not focusable
+
+ /* enable/disable auto save */
+ autoSave: { type: Boolean, default: true, required: false },
+ autoSaveDelay: { type: Number, default: 800, required: false },
+
+ /* control style */
+ filled: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ outlined: {
+ type: Boolean,
+ default: true,
+ required: false,
+ },
+ dense: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ },
+}
diff --git a/frontend-vue3/src/mixins/campRoleMixin.js b/frontend-vue3/src/mixins/campRoleMixin.js
new file mode 100644
index 0000000000..913a99b4cc
--- /dev/null
+++ b/frontend-vue3/src/mixins/campRoleMixin.js
@@ -0,0 +1,42 @@
+export const campRoleMixin = {
+ computed: {
+ isContributor() {
+ return this.isMember || this.isManager
+ },
+ isGuest() {
+ return this.role === 'guest'
+ },
+ isManager() {
+ return this.role === 'manager'
+ },
+ isMember() {
+ return this.role === 'member'
+ },
+ role() {
+ const currentUserLink = this.$store.getters.getLoggedInUser?._meta.self
+ const result = this._campCollaborations
+ .filter((coll) => typeof coll.user === 'function')
+ .find((coll) => coll.user()._meta.self === currentUserLink)
+
+ if (result?._meta.loading) return null
+ return result?.role
+ },
+ _campCollaborations() {
+ const campCollaborations = this._camp?.campCollaborations()
+ return campCollaborations?.items
+ },
+ _camp() {
+ if (typeof this.camp === 'function') {
+ return this.camp()
+ }
+ return this.camp
+ },
+ },
+ mounted() {
+ if (typeof this.camp !== 'object' && typeof this.camp !== 'function') {
+ throw new Error(
+ 'User of the campRoleMixin must expose a camp as object proxy or function'
+ )
+ }
+ },
+}
diff --git a/frontend-vue3/src/mixins/contentNodeMixin.js b/frontend-vue3/src/mixins/contentNodeMixin.js
new file mode 100644
index 0000000000..6490727fb5
--- /dev/null
+++ b/frontend-vue3/src/mixins/contentNodeMixin.js
@@ -0,0 +1,14 @@
+export const contentNodeMixin = {
+ props: {
+ contentNode: { type: Object, required: true },
+ layoutMode: { type: Boolean, required: true },
+ draggable: { type: Boolean, default: false },
+ disabled: { type: Boolean, default: false },
+ },
+ inject: ['camp'],
+ computed: {
+ camp() {
+ return this.camp()
+ },
+ },
+}
diff --git a/frontend-vue3/src/mixins/dateHelperUTCFormatted.js b/frontend-vue3/src/mixins/dateHelperUTCFormatted.js
new file mode 100644
index 0000000000..656061e569
--- /dev/null
+++ b/frontend-vue3/src/mixins/dateHelperUTCFormatted.js
@@ -0,0 +1,43 @@
+import {
+ dateShort,
+ dateLong,
+ hourShort,
+ hourLong,
+ timeDurationShort,
+ rangeTime,
+ rangeShort,
+ rangeLongEnd,
+ dateRange,
+} from '@/common/helpers/dateHelperUTCFormatted.js'
+
+export const dateHelperUTCFormatted = {
+ methods: {
+ dateShort(dateTimeString) {
+ return dateShort(dateTimeString, this.$t.bind(this))
+ },
+ dateLong(dateTimeString) {
+ return dateLong(dateTimeString, this.$t.bind(this))
+ },
+ hourShort(dateTimeString) {
+ return hourShort(dateTimeString, this.$t.bind(this))
+ },
+ hourLong(dateTimeString) {
+ return hourLong(dateTimeString, this.$t.bind(this))
+ },
+ timeDurationShort(start, end) {
+ return timeDurationShort(start, end, this.$t.bind(this))
+ },
+ rangeTime(start, end) {
+ return rangeTime(start, end, this.$t.bind(this))
+ },
+ rangeShort(start, end) {
+ return rangeShort(start, end, this.$t.bind(this))
+ },
+ rangeLongEnd(start, end) {
+ return rangeLongEnd(start, end, this.$t.bind(this))
+ },
+ dateRange(start, end) {
+ return dateRange(start, end, this.$t.bind(this))
+ },
+ },
+}
diff --git a/frontend-vue3/src/mixins/formComponentMixin.js b/frontend-vue3/src/mixins/formComponentMixin.js
new file mode 100644
index 0000000000..0e1ba4bdf2
--- /dev/null
+++ b/frontend-vue3/src/mixins/formComponentMixin.js
@@ -0,0 +1,28 @@
+export const formComponentMixin = {
+ props: {
+ // ID for vee-validation
+ veeId: {
+ type: String,
+ required: false,
+ default: null,
+ },
+
+ // rules for vee-validation
+ veeRules: {
+ type: [String, Object],
+ required: false,
+ default: '',
+ },
+ },
+ computed: {
+ required() {
+ if ('object' === typeof this.veeRules) {
+ return Object.keys(this.veeRules).includes('required')
+ }
+ return this.veeRules
+ .split('|')
+ .map((rule) => rule.replace(/:.*/, ''))
+ .includes('required')
+ },
+ },
+}
diff --git a/frontend-vue3/src/mixins/formComponentPropsMixin.js b/frontend-vue3/src/mixins/formComponentPropsMixin.js
new file mode 100644
index 0000000000..ed2c5f3457
--- /dev/null
+++ b/frontend-vue3/src/mixins/formComponentPropsMixin.js
@@ -0,0 +1,86 @@
+export const formComponentPropsMixin = {
+ inject: {
+ entityName: { default: null },
+ },
+ props: {
+ id: {
+ type: String,
+ required: false,
+ default: null,
+ },
+
+ // vuetify property hideDetails
+ filled: {
+ type: Boolean,
+ default: true,
+ },
+
+ // vuetify property hideDetails
+ hideDetails: {
+ type: [String, Boolean],
+ default: 'auto',
+ },
+
+ // set classes on input
+ inputClass: {
+ type: String,
+ default: '',
+ required: false,
+ },
+
+ /**
+ * used as field path for validation
+ * and together with entityName as label (if no override label is provided)
+ */
+ path: {
+ type: String,
+ required: false,
+ default: null,
+ },
+
+ /**
+ * override the automatic entity field label
+ */
+ label: {
+ type: String,
+ required: false,
+ default: undefined,
+ },
+
+ /**
+ * override the automatic validation field name
+ */
+ validationLabelOverride: {
+ type: String,
+ required: false,
+ default: undefined,
+ },
+
+ // error messages from outside which should be displayed on the component
+ errorMessages: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ },
+ computed: {
+ labelOrEntityFieldLabel() {
+ if (this.label !== undefined) {
+ return this.label
+ }
+ if (!this.entityName || !this.path) {
+ return null
+ }
+ return this.$t(`entity.${this.entityName}.fields.${this.path}`)
+ },
+ validationLabel() {
+ if (this.validationLabelOverride !== undefined) {
+ return this.validationLabelOverride
+ }
+ if (this.label) {
+ return this.label
+ }
+ return this.$t(`entity.${this.entityName}.fields.${this.path}`)
+ },
+ },
+}
diff --git a/frontend-vue3/src/mixins/passwordStrengthMixin.js b/frontend-vue3/src/mixins/passwordStrengthMixin.js
new file mode 100644
index 0000000000..4643f90c06
--- /dev/null
+++ b/frontend-vue3/src/mixins/passwordStrengthMixin.js
@@ -0,0 +1,32 @@
+import { throttle } from 'lodash-es'
+
+export const passwordStrengthMixin = {
+ data: () => ({
+ passwordStrength: 0,
+ passwordStrengthColor: 'green',
+ }),
+ methods: {
+ async strength(password, lang = this.$store.state.lang.language.substring(0, 2)) {
+ if (password.length === 0) {
+ this.passwordStrength = 0
+ } else {
+ // Use dynamic import for large dependency which is only used on very few pages
+ const { passwordStrength } = await import('@/plugins/passwordStrength.js')
+ const strengthInfo = await passwordStrength(password, lang)
+ this.passwordStrength = (1 + strengthInfo.score) * 20
+ }
+ return this.passwordStrength
+ },
+ async strengthColor(password) {
+ const strength = await this.strength(password)
+ this.passwordStrengthColor = 'green'
+ if (strength <= 75) this.passwordStrengthColor = 'yellow'
+ if (strength <= 50) this.passwordStrengthColor = 'orange'
+ if (strength <= 25) this.passwordStrengthColor = 'red'
+ return this.passwordStrengthColor
+ },
+ debouncedPasswordStrengthCheck: throttle(function (password) {
+ this.strengthColor(password).then()
+ }, 250),
+ },
+}
diff --git a/frontend-vue3/src/pdf/favicon.ico b/frontend-vue3/src/pdf/favicon.ico
new file mode 100644
index 0000000000..df36fcfb72
Binary files /dev/null and b/frontend-vue3/src/pdf/favicon.ico differ
diff --git a/frontend-vue3/src/pdf/pdf.js b/frontend-vue3/src/pdf/pdf.js
new file mode 100644
index 0000000000..0308d357b2
--- /dev/null
+++ b/frontend-vue3/src/pdf/pdf.js
@@ -0,0 +1,11219 @@
+import dayjs from "../common/helpers/dayjs.js";
+import camelCase from "lodash-es/camelCase.js";
+import * as primitives from "@react-pdf/primitives";
+import FontStore from "@react-pdf/font";
+import layoutDocument from "@react-pdf/layout";
+import PDFDocument from "@react-pdf/pdfkit";
+import renderPDF from "@react-pdf/render";
+import InterDisplay from "@/assets/fonts/Inter/InterDisplay-Regular.ttf";
+import InterDisplayItalic from "@/assets/fonts/Inter/InterDisplay-Italic.ttf";
+import InterDisplayMedium from "@/assets/fonts/Inter/InterDisplay-Medium.ttf";
+import InterDisplaySemiBold from "@/assets/fonts/Inter/InterDisplay-SemiBold.ttf";
+import InterDisplayBold from "@/assets/fonts/Inter/InterDisplay-Bold.ttf";
+import InterDisplayBoldItalic from "@/assets/fonts/Inter/InterDisplay-BoldItalic.ttf";
+import maxBy from "lodash-es/maxBy.js";
+import Color from "colorjs.io";
+import runes from "runes";
+import minBy from "lodash-es/minBy.js";
+import sortBy from "lodash-es/sortBy.js";
+import keyBy from "lodash-es/keyBy.js";
+import groupBy from "lodash-es/groupBy.js";
+import uniqWith from "lodash-es/uniqWith.js";
+import { wordHyphenation } from "@react-pdf/textkit";
+const styleStore = {};
+const htmlToPdfElementMap = { ...primitives };
+delete htmlToPdfElementMap.__esModule;
+delete htmlToPdfElementMap.TextInstance;
+function noop(fn) {
+ throw Error(`no-op: ${fn}`);
+}
+function patchProp(el, key, prevVal, nextVal) {
+ if (["debug", "fixed"].includes(key) && Object.values(htmlToPdfElementMap).includes(el.type)) {
+ el.props[camelCase(key)] = nextVal !== false;
+ } else if (key === "style") {
+ const transformed = Object.fromEntries(
+ Object.entries(nextVal || {}).map(([key2, value]) => [camelCase(key2), value])
+ );
+ el.style = Object.assign(el.style, transformed);
+ } else if (key === "class") {
+ const styles = nextVal.split(" ").map((styleClass) => styleStore[styleClass] || {});
+ el.style = Object.assign(el.style, ...styles);
+ } else {
+ el.props[camelCase(key)] = nextVal;
+ }
+}
+function insert(child, parent, _) {
+ if (!child || !parent) return;
+ if (child.type === "TEXT_INSTANCE" && child.value === "") {
+ return;
+ }
+ if (child.type === "PAGE" && parent.type !== "DOCUMENT") {
+ throw Error("Tag can only be used at the top level of a document.");
+ }
+ if (child.type !== "PAGE" && parent.type === "DOCUMENT") {
+ throw Error(
+ "Only tags can be used at the top level of a document. Please wrap your elements in a element."
+ );
+ }
+ if (child.type === "TEXT_INSTANCE" && parent.type !== "TEXT") {
+ parent.children.push({
+ box: {},
+ children: [child],
+ props: {},
+ style: {},
+ type: "TEXT",
+ parent
+ });
+ return;
+ }
+ if (child.type === "DOCUMENT") {
+ if (parent.type !== void 0) {
+ throw Error("Tag can only be used at the top level.");
+ }
+ if (parent.doc !== void 0) ;
+ parent.doc = child;
+ child.parent = null;
+ return;
+ }
+ parent.children.push(child);
+ child.parent = parent;
+}
+function createElement(tag, isSVG, isCustomizedBuiltIn, vnodeProps) {
+ if (!(tag in htmlToPdfElementMap)) {
+ throw Error(
+ `Tag <${tag}> cannot be used inside a pdf. Did you forget to import a Vue component?`
+ );
+ }
+ const camelCasedProps = Object.fromEntries(
+ Object.entries(vnodeProps || {}).map(([key, value]) => [camelCase(key), value])
+ );
+ return {
+ type: htmlToPdfElementMap[tag],
+ box: {},
+ style: {},
+ props: camelCasedProps,
+ children: []
+ };
+}
+function createText(text) {
+ return {
+ type: "TEXT_INSTANCE",
+ value: text
+ };
+}
+function setElementText(element, text) {
+ insert(createText(text), element);
+}
+function parentNode(element) {
+ return (element == null ? void 0 : element.parent) || null;
+}
+function nextSibling(element) {
+ if (!(element == null ? void 0 : element.parent)) return null;
+ const nextSiblingIndex = element.parent.children.findIndex((el) => el === element) + 1;
+ return element.parent.children[nextSiblingIndex] || null;
+}
+function remove$1(element) {
+ if (!(element == null ? void 0 : element.parent)) return null;
+ const index = element.parent.children.findIndex((el) => el === element);
+ element.parent.children.splice(index, 1);
+}
+function createComment() {
+}
+function setText() {
+ noop("setText");
+}
+function querySelector() {
+ noop("querySelector");
+}
+function setScopeId() {
+ noop("setScopeId");
+}
+function cloneNode() {
+ noop("cloneNode");
+}
+function insertStaticContent() {
+ noop("insertStaticContent");
+}
+function forcePatchProp() {
+ noop("forcePatchProp");
+}
+const nodeOps = {
+ patchProp,
+ insert,
+ createElement,
+ createText,
+ setElementText,
+ parentNode,
+ createComment,
+ setText,
+ nextSibling,
+ querySelector,
+ setScopeId,
+ cloneNode,
+ insertStaticContent,
+ forcePatchProp,
+ remove: remove$1
+};
+/**
+* @vue/shared v3.5.17
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/
+/*! #__NO_SIDE_EFFECTS__ */
+// @__NO_SIDE_EFFECTS__
+function makeMap(str) {
+ const map2 = /* @__PURE__ */ Object.create(null);
+ for (const key of str.split(",")) map2[key] = 1;
+ return (val) => val in map2;
+}
+const EMPTY_OBJ = !!(process.env.NODE_ENV !== "production") ? Object.freeze({}) : {};
+const EMPTY_ARR = !!(process.env.NODE_ENV !== "production") ? Object.freeze([]) : [];
+const NOOP = () => {
+};
+const NO = () => false;
+const isOn = (key) => key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && // uppercase letter
+(key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97);
+const isModelListener = (key) => key.startsWith("onUpdate:");
+const extend = Object.assign;
+const remove = (arr, el) => {
+ const i2 = arr.indexOf(el);
+ if (i2 > -1) {
+ arr.splice(i2, 1);
+ }
+};
+const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
+const hasOwn = (val, key) => hasOwnProperty$1.call(val, key);
+const isArray = Array.isArray;
+const isMap = (val) => toTypeString(val) === "[object Map]";
+const isSet = (val) => toTypeString(val) === "[object Set]";
+const isFunction = (val) => typeof val === "function";
+const isString = (val) => typeof val === "string";
+const isSymbol = (val) => typeof val === "symbol";
+const isObject = (val) => val !== null && typeof val === "object";
+const isPromise = (val) => {
+ return (isObject(val) || isFunction(val)) && isFunction(val.then) && isFunction(val.catch);
+};
+const objectToString = Object.prototype.toString;
+const toTypeString = (value) => objectToString.call(value);
+const toRawType = (value) => {
+ return toTypeString(value).slice(8, -1);
+};
+const isPlainObject = (val) => toTypeString(val) === "[object Object]";
+const isIntegerKey = (key) => isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key;
+const isReservedProp = /* @__PURE__ */ makeMap(
+ // the leading comma is intentional so empty string "" is also included
+ ",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"
+);
+const isBuiltInDirective = /* @__PURE__ */ makeMap(
+ "bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo"
+);
+const cacheStringFunction = (fn) => {
+ const cache = /* @__PURE__ */ Object.create(null);
+ return (str) => {
+ const hit = cache[str];
+ return hit || (cache[str] = fn(str));
+ };
+};
+const camelizeRE = /-(\w)/g;
+const camelize = cacheStringFunction(
+ (str) => {
+ return str.replace(camelizeRE, (_, c2) => c2 ? c2.toUpperCase() : "");
+ }
+);
+const hyphenateRE = /\B([A-Z])/g;
+const hyphenate = cacheStringFunction(
+ (str) => str.replace(hyphenateRE, "-$1").toLowerCase()
+);
+const capitalize = cacheStringFunction((str) => {
+ return str.charAt(0).toUpperCase() + str.slice(1);
+});
+const toHandlerKey = cacheStringFunction(
+ (str) => {
+ const s2 = str ? `on${capitalize(str)}` : ``;
+ return s2;
+ }
+);
+const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
+const invokeArrayFns = (fns, ...arg) => {
+ for (let i2 = 0; i2 < fns.length; i2++) {
+ fns[i2](...arg);
+ }
+};
+const def = (obj, key, value, writable = false) => {
+ Object.defineProperty(obj, key, {
+ configurable: true,
+ enumerable: false,
+ writable,
+ value
+ });
+};
+const looseToNumber = (val) => {
+ const n2 = parseFloat(val);
+ return isNaN(n2) ? val : n2;
+};
+let _globalThis;
+const getGlobalThis = () => {
+ return _globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {});
+};
+function normalizeStyle(value) {
+ if (isArray(value)) {
+ const res = {};
+ for (let i2 = 0; i2 < value.length; i2++) {
+ const item = value[i2];
+ const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item);
+ if (normalized) {
+ for (const key in normalized) {
+ res[key] = normalized[key];
+ }
+ }
+ }
+ return res;
+ } else if (isString(value) || isObject(value)) {
+ return value;
+ }
+}
+const listDelimiterRE = /;(?![^(]*\))/g;
+const propertyDelimiterRE = /:([^]+)/;
+const styleCommentRE = /\/\*[^]*?\*\//g;
+function parseStringStyle(cssText) {
+ const ret = {};
+ cssText.replace(styleCommentRE, "").split(listDelimiterRE).forEach((item) => {
+ if (item) {
+ const tmp = item.split(propertyDelimiterRE);
+ tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
+ }
+ });
+ return ret;
+}
+function normalizeClass(value) {
+ let res = "";
+ if (isString(value)) {
+ res = value;
+ } else if (isArray(value)) {
+ for (let i2 = 0; i2 < value.length; i2++) {
+ const normalized = normalizeClass(value[i2]);
+ if (normalized) {
+ res += normalized + " ";
+ }
+ }
+ } else if (isObject(value)) {
+ for (const name in value) {
+ if (value[name]) {
+ res += name + " ";
+ }
+ }
+ }
+ return res.trim();
+}
+const isRef$1 = (val) => {
+ return !!(val && val["__v_isRef"] === true);
+};
+const toDisplayString = (val) => {
+ return isString(val) ? val : val == null ? "" : isArray(val) || isObject(val) && (val.toString === objectToString || !isFunction(val.toString)) ? isRef$1(val) ? toDisplayString(val.value) : JSON.stringify(val, replacer, 2) : String(val);
+};
+const replacer = (_key, val) => {
+ if (isRef$1(val)) {
+ return replacer(_key, val.value);
+ } else if (isMap(val)) {
+ return {
+ [`Map(${val.size})`]: [...val.entries()].reduce(
+ (entries, [key, val2], i2) => {
+ entries[stringifySymbol(key, i2) + " =>"] = val2;
+ return entries;
+ },
+ {}
+ )
+ };
+ } else if (isSet(val)) {
+ return {
+ [`Set(${val.size})`]: [...val.values()].map((v) => stringifySymbol(v))
+ };
+ } else if (isSymbol(val)) {
+ return stringifySymbol(val);
+ } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
+ return String(val);
+ }
+ return val;
+};
+const stringifySymbol = (v, i2 = "") => {
+ var _a;
+ return (
+ // Symbol.description in es2019+ so we need to cast here to pass
+ // the lib: es2016 check
+ isSymbol(v) ? `Symbol(${(_a = v.description) != null ? _a : i2})` : v
+ );
+};
+/**
+* @vue/reactivity v3.5.17
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/
+function warn(msg, ...args) {
+ console.warn(`[Vue warn] ${msg}`, ...args);
+}
+let activeEffectScope;
+class EffectScope {
+ constructor(detached = false) {
+ this.detached = detached;
+ this._active = true;
+ this._on = 0;
+ this.effects = [];
+ this.cleanups = [];
+ this._isPaused = false;
+ this.parent = activeEffectScope;
+ if (!detached && activeEffectScope) {
+ this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(
+ this
+ ) - 1;
+ }
+ }
+ get active() {
+ return this._active;
+ }
+ pause() {
+ if (this._active) {
+ this._isPaused = true;
+ let i2, l;
+ if (this.scopes) {
+ for (i2 = 0, l = this.scopes.length; i2 < l; i2++) {
+ this.scopes[i2].pause();
+ }
+ }
+ for (i2 = 0, l = this.effects.length; i2 < l; i2++) {
+ this.effects[i2].pause();
+ }
+ }
+ }
+ /**
+ * Resumes the effect scope, including all child scopes and effects.
+ */
+ resume() {
+ if (this._active) {
+ if (this._isPaused) {
+ this._isPaused = false;
+ let i2, l;
+ if (this.scopes) {
+ for (i2 = 0, l = this.scopes.length; i2 < l; i2++) {
+ this.scopes[i2].resume();
+ }
+ }
+ for (i2 = 0, l = this.effects.length; i2 < l; i2++) {
+ this.effects[i2].resume();
+ }
+ }
+ }
+ }
+ run(fn) {
+ if (this._active) {
+ const currentEffectScope = activeEffectScope;
+ try {
+ activeEffectScope = this;
+ return fn();
+ } finally {
+ activeEffectScope = currentEffectScope;
+ }
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ warn(`cannot run an inactive effect scope.`);
+ }
+ }
+ /**
+ * This should only be called on non-detached scopes
+ * @internal
+ */
+ on() {
+ if (++this._on === 1) {
+ this.prevScope = activeEffectScope;
+ activeEffectScope = this;
+ }
+ }
+ /**
+ * This should only be called on non-detached scopes
+ * @internal
+ */
+ off() {
+ if (this._on > 0 && --this._on === 0) {
+ activeEffectScope = this.prevScope;
+ this.prevScope = void 0;
+ }
+ }
+ stop(fromParent) {
+ if (this._active) {
+ this._active = false;
+ let i2, l;
+ for (i2 = 0, l = this.effects.length; i2 < l; i2++) {
+ this.effects[i2].stop();
+ }
+ this.effects.length = 0;
+ for (i2 = 0, l = this.cleanups.length; i2 < l; i2++) {
+ this.cleanups[i2]();
+ }
+ this.cleanups.length = 0;
+ if (this.scopes) {
+ for (i2 = 0, l = this.scopes.length; i2 < l; i2++) {
+ this.scopes[i2].stop(true);
+ }
+ this.scopes.length = 0;
+ }
+ if (!this.detached && this.parent && !fromParent) {
+ const last = this.parent.scopes.pop();
+ if (last && last !== this) {
+ this.parent.scopes[this.index] = last;
+ last.index = this.index;
+ }
+ }
+ this.parent = void 0;
+ }
+ }
+}
+function getCurrentScope() {
+ return activeEffectScope;
+}
+let activeSub;
+const pausedQueueEffects = /* @__PURE__ */ new WeakSet();
+class ReactiveEffect {
+ constructor(fn) {
+ this.fn = fn;
+ this.deps = void 0;
+ this.depsTail = void 0;
+ this.flags = 1 | 4;
+ this.next = void 0;
+ this.cleanup = void 0;
+ this.scheduler = void 0;
+ if (activeEffectScope && activeEffectScope.active) {
+ activeEffectScope.effects.push(this);
+ }
+ }
+ pause() {
+ this.flags |= 64;
+ }
+ resume() {
+ if (this.flags & 64) {
+ this.flags &= -65;
+ if (pausedQueueEffects.has(this)) {
+ pausedQueueEffects.delete(this);
+ this.trigger();
+ }
+ }
+ }
+ /**
+ * @internal
+ */
+ notify() {
+ if (this.flags & 2 && !(this.flags & 32)) {
+ return;
+ }
+ if (!(this.flags & 8)) {
+ batch(this);
+ }
+ }
+ run() {
+ if (!(this.flags & 1)) {
+ return this.fn();
+ }
+ this.flags |= 2;
+ cleanupEffect(this);
+ prepareDeps(this);
+ const prevEffect = activeSub;
+ const prevShouldTrack = shouldTrack;
+ activeSub = this;
+ shouldTrack = true;
+ try {
+ return this.fn();
+ } finally {
+ if (!!(process.env.NODE_ENV !== "production") && activeSub !== this) {
+ warn(
+ "Active effect was not restored correctly - this is likely a Vue internal bug."
+ );
+ }
+ cleanupDeps(this);
+ activeSub = prevEffect;
+ shouldTrack = prevShouldTrack;
+ this.flags &= -3;
+ }
+ }
+ stop() {
+ if (this.flags & 1) {
+ for (let link = this.deps; link; link = link.nextDep) {
+ removeSub(link);
+ }
+ this.deps = this.depsTail = void 0;
+ cleanupEffect(this);
+ this.onStop && this.onStop();
+ this.flags &= -2;
+ }
+ }
+ trigger() {
+ if (this.flags & 64) {
+ pausedQueueEffects.add(this);
+ } else if (this.scheduler) {
+ this.scheduler();
+ } else {
+ this.runIfDirty();
+ }
+ }
+ /**
+ * @internal
+ */
+ runIfDirty() {
+ if (isDirty(this)) {
+ this.run();
+ }
+ }
+ get dirty() {
+ return isDirty(this);
+ }
+}
+let batchDepth = 0;
+let batchedSub;
+let batchedComputed;
+function batch(sub, isComputed = false) {
+ sub.flags |= 8;
+ if (isComputed) {
+ sub.next = batchedComputed;
+ batchedComputed = sub;
+ return;
+ }
+ sub.next = batchedSub;
+ batchedSub = sub;
+}
+function startBatch() {
+ batchDepth++;
+}
+function endBatch() {
+ if (--batchDepth > 0) {
+ return;
+ }
+ if (batchedComputed) {
+ let e2 = batchedComputed;
+ batchedComputed = void 0;
+ while (e2) {
+ const next = e2.next;
+ e2.next = void 0;
+ e2.flags &= -9;
+ e2 = next;
+ }
+ }
+ let error;
+ while (batchedSub) {
+ let e2 = batchedSub;
+ batchedSub = void 0;
+ while (e2) {
+ const next = e2.next;
+ e2.next = void 0;
+ e2.flags &= -9;
+ if (e2.flags & 1) {
+ try {
+ ;
+ e2.trigger();
+ } catch (err) {
+ if (!error) error = err;
+ }
+ }
+ e2 = next;
+ }
+ }
+ if (error) throw error;
+}
+function prepareDeps(sub) {
+ for (let link = sub.deps; link; link = link.nextDep) {
+ link.version = -1;
+ link.prevActiveLink = link.dep.activeLink;
+ link.dep.activeLink = link;
+ }
+}
+function cleanupDeps(sub) {
+ let head;
+ let tail = sub.depsTail;
+ let link = tail;
+ while (link) {
+ const prev = link.prevDep;
+ if (link.version === -1) {
+ if (link === tail) tail = prev;
+ removeSub(link);
+ removeDep(link);
+ } else {
+ head = link;
+ }
+ link.dep.activeLink = link.prevActiveLink;
+ link.prevActiveLink = void 0;
+ link = prev;
+ }
+ sub.deps = head;
+ sub.depsTail = tail;
+}
+function isDirty(sub) {
+ for (let link = sub.deps; link; link = link.nextDep) {
+ if (link.dep.version !== link.version || link.dep.computed && (refreshComputed(link.dep.computed) || link.dep.version !== link.version)) {
+ return true;
+ }
+ }
+ if (sub._dirty) {
+ return true;
+ }
+ return false;
+}
+function refreshComputed(computed2) {
+ if (computed2.flags & 4 && !(computed2.flags & 16)) {
+ return;
+ }
+ computed2.flags &= -17;
+ if (computed2.globalVersion === globalVersion) {
+ return;
+ }
+ computed2.globalVersion = globalVersion;
+ if (!computed2.isSSR && computed2.flags & 128 && (!computed2.deps && !computed2._dirty || !isDirty(computed2))) {
+ return;
+ }
+ computed2.flags |= 2;
+ const dep = computed2.dep;
+ const prevSub = activeSub;
+ const prevShouldTrack = shouldTrack;
+ activeSub = computed2;
+ shouldTrack = true;
+ try {
+ prepareDeps(computed2);
+ const value = computed2.fn(computed2._value);
+ if (dep.version === 0 || hasChanged(value, computed2._value)) {
+ computed2.flags |= 128;
+ computed2._value = value;
+ dep.version++;
+ }
+ } catch (err) {
+ dep.version++;
+ throw err;
+ } finally {
+ activeSub = prevSub;
+ shouldTrack = prevShouldTrack;
+ cleanupDeps(computed2);
+ computed2.flags &= -3;
+ }
+}
+function removeSub(link, soft = false) {
+ const { dep, prevSub, nextSub } = link;
+ if (prevSub) {
+ prevSub.nextSub = nextSub;
+ link.prevSub = void 0;
+ }
+ if (nextSub) {
+ nextSub.prevSub = prevSub;
+ link.nextSub = void 0;
+ }
+ if (!!(process.env.NODE_ENV !== "production") && dep.subsHead === link) {
+ dep.subsHead = nextSub;
+ }
+ if (dep.subs === link) {
+ dep.subs = prevSub;
+ if (!prevSub && dep.computed) {
+ dep.computed.flags &= -5;
+ for (let l = dep.computed.deps; l; l = l.nextDep) {
+ removeSub(l, true);
+ }
+ }
+ }
+ if (!soft && !--dep.sc && dep.map) {
+ dep.map.delete(dep.key);
+ }
+}
+function removeDep(link) {
+ const { prevDep, nextDep } = link;
+ if (prevDep) {
+ prevDep.nextDep = nextDep;
+ link.prevDep = void 0;
+ }
+ if (nextDep) {
+ nextDep.prevDep = prevDep;
+ link.nextDep = void 0;
+ }
+}
+let shouldTrack = true;
+const trackStack = [];
+function pauseTracking() {
+ trackStack.push(shouldTrack);
+ shouldTrack = false;
+}
+function resetTracking() {
+ const last = trackStack.pop();
+ shouldTrack = last === void 0 ? true : last;
+}
+function cleanupEffect(e2) {
+ const { cleanup } = e2;
+ e2.cleanup = void 0;
+ if (cleanup) {
+ const prevSub = activeSub;
+ activeSub = void 0;
+ try {
+ cleanup();
+ } finally {
+ activeSub = prevSub;
+ }
+ }
+}
+let globalVersion = 0;
+class Link {
+ constructor(sub, dep) {
+ this.sub = sub;
+ this.dep = dep;
+ this.version = dep.version;
+ this.nextDep = this.prevDep = this.nextSub = this.prevSub = this.prevActiveLink = void 0;
+ }
+}
+class Dep {
+ // TODO isolatedDeclarations "__v_skip"
+ constructor(computed2) {
+ this.computed = computed2;
+ this.version = 0;
+ this.activeLink = void 0;
+ this.subs = void 0;
+ this.map = void 0;
+ this.key = void 0;
+ this.sc = 0;
+ this.__v_skip = true;
+ if (!!(process.env.NODE_ENV !== "production")) {
+ this.subsHead = void 0;
+ }
+ }
+ track(debugInfo) {
+ if (!activeSub || !shouldTrack || activeSub === this.computed) {
+ return;
+ }
+ let link = this.activeLink;
+ if (link === void 0 || link.sub !== activeSub) {
+ link = this.activeLink = new Link(activeSub, this);
+ if (!activeSub.deps) {
+ activeSub.deps = activeSub.depsTail = link;
+ } else {
+ link.prevDep = activeSub.depsTail;
+ activeSub.depsTail.nextDep = link;
+ activeSub.depsTail = link;
+ }
+ addSub(link);
+ } else if (link.version === -1) {
+ link.version = this.version;
+ if (link.nextDep) {
+ const next = link.nextDep;
+ next.prevDep = link.prevDep;
+ if (link.prevDep) {
+ link.prevDep.nextDep = next;
+ }
+ link.prevDep = activeSub.depsTail;
+ link.nextDep = void 0;
+ activeSub.depsTail.nextDep = link;
+ activeSub.depsTail = link;
+ if (activeSub.deps === link) {
+ activeSub.deps = next;
+ }
+ }
+ }
+ if (!!(process.env.NODE_ENV !== "production") && activeSub.onTrack) {
+ activeSub.onTrack(
+ extend(
+ {
+ effect: activeSub
+ },
+ debugInfo
+ )
+ );
+ }
+ return link;
+ }
+ trigger(debugInfo) {
+ this.version++;
+ globalVersion++;
+ this.notify(debugInfo);
+ }
+ notify(debugInfo) {
+ startBatch();
+ try {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ for (let head = this.subsHead; head; head = head.nextSub) {
+ if (head.sub.onTrigger && !(head.sub.flags & 8)) {
+ head.sub.onTrigger(
+ extend(
+ {
+ effect: head.sub
+ },
+ debugInfo
+ )
+ );
+ }
+ }
+ }
+ for (let link = this.subs; link; link = link.prevSub) {
+ if (link.sub.notify()) {
+ ;
+ link.sub.dep.notify();
+ }
+ }
+ } finally {
+ endBatch();
+ }
+ }
+}
+function addSub(link) {
+ link.dep.sc++;
+ if (link.sub.flags & 4) {
+ const computed2 = link.dep.computed;
+ if (computed2 && !link.dep.subs) {
+ computed2.flags |= 4 | 16;
+ for (let l = computed2.deps; l; l = l.nextDep) {
+ addSub(l);
+ }
+ }
+ const currentTail = link.dep.subs;
+ if (currentTail !== link) {
+ link.prevSub = currentTail;
+ if (currentTail) currentTail.nextSub = link;
+ }
+ if (!!(process.env.NODE_ENV !== "production") && link.dep.subsHead === void 0) {
+ link.dep.subsHead = link;
+ }
+ link.dep.subs = link;
+ }
+}
+const targetMap = /* @__PURE__ */ new WeakMap();
+const ITERATE_KEY = Symbol(
+ !!(process.env.NODE_ENV !== "production") ? "Object iterate" : ""
+);
+const MAP_KEY_ITERATE_KEY = Symbol(
+ !!(process.env.NODE_ENV !== "production") ? "Map keys iterate" : ""
+);
+const ARRAY_ITERATE_KEY = Symbol(
+ !!(process.env.NODE_ENV !== "production") ? "Array iterate" : ""
+);
+function track(target, type, key) {
+ if (shouldTrack && activeSub) {
+ let depsMap = targetMap.get(target);
+ if (!depsMap) {
+ targetMap.set(target, depsMap = /* @__PURE__ */ new Map());
+ }
+ let dep = depsMap.get(key);
+ if (!dep) {
+ depsMap.set(key, dep = new Dep());
+ dep.map = depsMap;
+ dep.key = key;
+ }
+ if (!!(process.env.NODE_ENV !== "production")) {
+ dep.track({
+ target,
+ type,
+ key
+ });
+ } else {
+ dep.track();
+ }
+ }
+}
+function trigger(target, type, key, newValue, oldValue, oldTarget) {
+ const depsMap = targetMap.get(target);
+ if (!depsMap) {
+ globalVersion++;
+ return;
+ }
+ const run = (dep) => {
+ if (dep) {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ dep.trigger({
+ target,
+ type,
+ key,
+ newValue,
+ oldValue,
+ oldTarget
+ });
+ } else {
+ dep.trigger();
+ }
+ }
+ };
+ startBatch();
+ if (type === "clear") {
+ depsMap.forEach(run);
+ } else {
+ const targetIsArray = isArray(target);
+ const isArrayIndex = targetIsArray && isIntegerKey(key);
+ if (targetIsArray && key === "length") {
+ const newLength = Number(newValue);
+ depsMap.forEach((dep, key2) => {
+ if (key2 === "length" || key2 === ARRAY_ITERATE_KEY || !isSymbol(key2) && key2 >= newLength) {
+ run(dep);
+ }
+ });
+ } else {
+ if (key !== void 0 || depsMap.has(void 0)) {
+ run(depsMap.get(key));
+ }
+ if (isArrayIndex) {
+ run(depsMap.get(ARRAY_ITERATE_KEY));
+ }
+ switch (type) {
+ case "add":
+ if (!targetIsArray) {
+ run(depsMap.get(ITERATE_KEY));
+ if (isMap(target)) {
+ run(depsMap.get(MAP_KEY_ITERATE_KEY));
+ }
+ } else if (isArrayIndex) {
+ run(depsMap.get("length"));
+ }
+ break;
+ case "delete":
+ if (!targetIsArray) {
+ run(depsMap.get(ITERATE_KEY));
+ if (isMap(target)) {
+ run(depsMap.get(MAP_KEY_ITERATE_KEY));
+ }
+ }
+ break;
+ case "set":
+ if (isMap(target)) {
+ run(depsMap.get(ITERATE_KEY));
+ }
+ break;
+ }
+ }
+ }
+ endBatch();
+}
+function reactiveReadArray(array) {
+ const raw = toRaw(array);
+ if (raw === array) return raw;
+ track(raw, "iterate", ARRAY_ITERATE_KEY);
+ return isShallow(array) ? raw : raw.map(toReactive);
+}
+function shallowReadArray(arr) {
+ track(arr = toRaw(arr), "iterate", ARRAY_ITERATE_KEY);
+ return arr;
+}
+const arrayInstrumentations = {
+ __proto__: null,
+ [Symbol.iterator]() {
+ return iterator(this, Symbol.iterator, toReactive);
+ },
+ concat(...args) {
+ return reactiveReadArray(this).concat(
+ ...args.map((x) => isArray(x) ? reactiveReadArray(x) : x)
+ );
+ },
+ entries() {
+ return iterator(this, "entries", (value) => {
+ value[1] = toReactive(value[1]);
+ return value;
+ });
+ },
+ every(fn, thisArg) {
+ return apply(this, "every", fn, thisArg, void 0, arguments);
+ },
+ filter(fn, thisArg) {
+ return apply(this, "filter", fn, thisArg, (v) => v.map(toReactive), arguments);
+ },
+ find(fn, thisArg) {
+ return apply(this, "find", fn, thisArg, toReactive, arguments);
+ },
+ findIndex(fn, thisArg) {
+ return apply(this, "findIndex", fn, thisArg, void 0, arguments);
+ },
+ findLast(fn, thisArg) {
+ return apply(this, "findLast", fn, thisArg, toReactive, arguments);
+ },
+ findLastIndex(fn, thisArg) {
+ return apply(this, "findLastIndex", fn, thisArg, void 0, arguments);
+ },
+ // flat, flatMap could benefit from ARRAY_ITERATE but are not straight-forward to implement
+ forEach(fn, thisArg) {
+ return apply(this, "forEach", fn, thisArg, void 0, arguments);
+ },
+ includes(...args) {
+ return searchProxy(this, "includes", args);
+ },
+ indexOf(...args) {
+ return searchProxy(this, "indexOf", args);
+ },
+ join(separator) {
+ return reactiveReadArray(this).join(separator);
+ },
+ // keys() iterator only reads `length`, no optimisation required
+ lastIndexOf(...args) {
+ return searchProxy(this, "lastIndexOf", args);
+ },
+ map(fn, thisArg) {
+ return apply(this, "map", fn, thisArg, void 0, arguments);
+ },
+ pop() {
+ return noTracking(this, "pop");
+ },
+ push(...args) {
+ return noTracking(this, "push", args);
+ },
+ reduce(fn, ...args) {
+ return reduce(this, "reduce", fn, args);
+ },
+ reduceRight(fn, ...args) {
+ return reduce(this, "reduceRight", fn, args);
+ },
+ shift() {
+ return noTracking(this, "shift");
+ },
+ // slice could use ARRAY_ITERATE but also seems to beg for range tracking
+ some(fn, thisArg) {
+ return apply(this, "some", fn, thisArg, void 0, arguments);
+ },
+ splice(...args) {
+ return noTracking(this, "splice", args);
+ },
+ toReversed() {
+ return reactiveReadArray(this).toReversed();
+ },
+ toSorted(comparer) {
+ return reactiveReadArray(this).toSorted(comparer);
+ },
+ toSpliced(...args) {
+ return reactiveReadArray(this).toSpliced(...args);
+ },
+ unshift(...args) {
+ return noTracking(this, "unshift", args);
+ },
+ values() {
+ return iterator(this, "values", toReactive);
+ }
+};
+function iterator(self2, method, wrapValue) {
+ const arr = shallowReadArray(self2);
+ const iter = arr[method]();
+ if (arr !== self2 && !isShallow(self2)) {
+ iter._next = iter.next;
+ iter.next = () => {
+ const result = iter._next();
+ if (result.value) {
+ result.value = wrapValue(result.value);
+ }
+ return result;
+ };
+ }
+ return iter;
+}
+const arrayProto = Array.prototype;
+function apply(self2, method, fn, thisArg, wrappedRetFn, args) {
+ const arr = shallowReadArray(self2);
+ const needsWrap = arr !== self2 && !isShallow(self2);
+ const methodFn = arr[method];
+ if (methodFn !== arrayProto[method]) {
+ const result2 = methodFn.apply(self2, args);
+ return needsWrap ? toReactive(result2) : result2;
+ }
+ let wrappedFn = fn;
+ if (arr !== self2) {
+ if (needsWrap) {
+ wrappedFn = function(item, index) {
+ return fn.call(this, toReactive(item), index, self2);
+ };
+ } else if (fn.length > 2) {
+ wrappedFn = function(item, index) {
+ return fn.call(this, item, index, self2);
+ };
+ }
+ }
+ const result = methodFn.call(arr, wrappedFn, thisArg);
+ return needsWrap && wrappedRetFn ? wrappedRetFn(result) : result;
+}
+function reduce(self2, method, fn, args) {
+ const arr = shallowReadArray(self2);
+ let wrappedFn = fn;
+ if (arr !== self2) {
+ if (!isShallow(self2)) {
+ wrappedFn = function(acc, item, index) {
+ return fn.call(this, acc, toReactive(item), index, self2);
+ };
+ } else if (fn.length > 3) {
+ wrappedFn = function(acc, item, index) {
+ return fn.call(this, acc, item, index, self2);
+ };
+ }
+ }
+ return arr[method](wrappedFn, ...args);
+}
+function searchProxy(self2, method, args) {
+ const arr = toRaw(self2);
+ track(arr, "iterate", ARRAY_ITERATE_KEY);
+ const res = arr[method](...args);
+ if ((res === -1 || res === false) && isProxy(args[0])) {
+ args[0] = toRaw(args[0]);
+ return arr[method](...args);
+ }
+ return res;
+}
+function noTracking(self2, method, args = []) {
+ pauseTracking();
+ startBatch();
+ const res = toRaw(self2)[method].apply(self2, args);
+ endBatch();
+ resetTracking();
+ return res;
+}
+const isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`);
+const builtInSymbols = new Set(
+ /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol)
+);
+function hasOwnProperty(key) {
+ if (!isSymbol(key)) key = String(key);
+ const obj = toRaw(this);
+ track(obj, "has", key);
+ return obj.hasOwnProperty(key);
+}
+class BaseReactiveHandler {
+ constructor(_isReadonly = false, _isShallow = false) {
+ this._isReadonly = _isReadonly;
+ this._isShallow = _isShallow;
+ }
+ get(target, key, receiver) {
+ if (key === "__v_skip") return target["__v_skip"];
+ const isReadonly2 = this._isReadonly, isShallow2 = this._isShallow;
+ if (key === "__v_isReactive") {
+ return !isReadonly2;
+ } else if (key === "__v_isReadonly") {
+ return isReadonly2;
+ } else if (key === "__v_isShallow") {
+ return isShallow2;
+ } else if (key === "__v_raw") {
+ if (receiver === (isReadonly2 ? isShallow2 ? shallowReadonlyMap : readonlyMap : isShallow2 ? shallowReactiveMap : reactiveMap).get(target) || // receiver is not the reactive proxy, but has the same prototype
+ // this means the receiver is a user proxy of the reactive proxy
+ Object.getPrototypeOf(target) === Object.getPrototypeOf(receiver)) {
+ return target;
+ }
+ return;
+ }
+ const targetIsArray = isArray(target);
+ if (!isReadonly2) {
+ let fn;
+ if (targetIsArray && (fn = arrayInstrumentations[key])) {
+ return fn;
+ }
+ if (key === "hasOwnProperty") {
+ return hasOwnProperty;
+ }
+ }
+ const res = Reflect.get(
+ target,
+ key,
+ // if this is a proxy wrapping a ref, return methods using the raw ref
+ // as receiver so that we don't have to call `toRaw` on the ref in all
+ // its class methods
+ isRef(target) ? target : receiver
+ );
+ if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
+ return res;
+ }
+ if (!isReadonly2) {
+ track(target, "get", key);
+ }
+ if (isShallow2) {
+ return res;
+ }
+ if (isRef(res)) {
+ return targetIsArray && isIntegerKey(key) ? res : res.value;
+ }
+ if (isObject(res)) {
+ return isReadonly2 ? readonly(res) : reactive(res);
+ }
+ return res;
+ }
+}
+class MutableReactiveHandler extends BaseReactiveHandler {
+ constructor(isShallow2 = false) {
+ super(false, isShallow2);
+ }
+ set(target, key, value, receiver) {
+ let oldValue = target[key];
+ if (!this._isShallow) {
+ const isOldValueReadonly = isReadonly(oldValue);
+ if (!isShallow(value) && !isReadonly(value)) {
+ oldValue = toRaw(oldValue);
+ value = toRaw(value);
+ }
+ if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
+ if (isOldValueReadonly) {
+ return false;
+ } else {
+ oldValue.value = value;
+ return true;
+ }
+ }
+ }
+ const hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key);
+ const result = Reflect.set(
+ target,
+ key,
+ value,
+ isRef(target) ? target : receiver
+ );
+ if (target === toRaw(receiver)) {
+ if (!hadKey) {
+ trigger(target, "add", key, value);
+ } else if (hasChanged(value, oldValue)) {
+ trigger(target, "set", key, value, oldValue);
+ }
+ }
+ return result;
+ }
+ deleteProperty(target, key) {
+ const hadKey = hasOwn(target, key);
+ const oldValue = target[key];
+ const result = Reflect.deleteProperty(target, key);
+ if (result && hadKey) {
+ trigger(target, "delete", key, void 0, oldValue);
+ }
+ return result;
+ }
+ has(target, key) {
+ const result = Reflect.has(target, key);
+ if (!isSymbol(key) || !builtInSymbols.has(key)) {
+ track(target, "has", key);
+ }
+ return result;
+ }
+ ownKeys(target) {
+ track(
+ target,
+ "iterate",
+ isArray(target) ? "length" : ITERATE_KEY
+ );
+ return Reflect.ownKeys(target);
+ }
+}
+class ReadonlyReactiveHandler extends BaseReactiveHandler {
+ constructor(isShallow2 = false) {
+ super(true, isShallow2);
+ }
+ set(target, key) {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ warn(
+ `Set operation on key "${String(key)}" failed: target is readonly.`,
+ target
+ );
+ }
+ return true;
+ }
+ deleteProperty(target, key) {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ warn(
+ `Delete operation on key "${String(key)}" failed: target is readonly.`,
+ target
+ );
+ }
+ return true;
+ }
+}
+const mutableHandlers = /* @__PURE__ */ new MutableReactiveHandler();
+const readonlyHandlers = /* @__PURE__ */ new ReadonlyReactiveHandler();
+const shallowReactiveHandlers = /* @__PURE__ */ new MutableReactiveHandler(true);
+const shallowReadonlyHandlers = /* @__PURE__ */ new ReadonlyReactiveHandler(true);
+const toShallow = (value) => value;
+const getProto = (v) => Reflect.getPrototypeOf(v);
+function createIterableMethod(method, isReadonly2, isShallow2) {
+ return function(...args) {
+ const target = this["__v_raw"];
+ const rawTarget = toRaw(target);
+ const targetIsMap = isMap(rawTarget);
+ const isPair = method === "entries" || method === Symbol.iterator && targetIsMap;
+ const isKeyOnly = method === "keys" && targetIsMap;
+ const innerIterator = target[method](...args);
+ const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive;
+ !isReadonly2 && track(
+ rawTarget,
+ "iterate",
+ isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY
+ );
+ return {
+ // iterator protocol
+ next() {
+ const { value, done } = innerIterator.next();
+ return done ? { value, done } : {
+ value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
+ done
+ };
+ },
+ // iterable protocol
+ [Symbol.iterator]() {
+ return this;
+ }
+ };
+ };
+}
+function createReadonlyMethod(type) {
+ return function(...args) {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ const key = args[0] ? `on key "${args[0]}" ` : ``;
+ warn(
+ `${capitalize(type)} operation ${key}failed: target is readonly.`,
+ toRaw(this)
+ );
+ }
+ return type === "delete" ? false : type === "clear" ? void 0 : this;
+ };
+}
+function createInstrumentations(readonly2, shallow) {
+ const instrumentations = {
+ get(key) {
+ const target = this["__v_raw"];
+ const rawTarget = toRaw(target);
+ const rawKey = toRaw(key);
+ if (!readonly2) {
+ if (hasChanged(key, rawKey)) {
+ track(rawTarget, "get", key);
+ }
+ track(rawTarget, "get", rawKey);
+ }
+ const { has } = getProto(rawTarget);
+ const wrap = shallow ? toShallow : readonly2 ? toReadonly : toReactive;
+ if (has.call(rawTarget, key)) {
+ return wrap(target.get(key));
+ } else if (has.call(rawTarget, rawKey)) {
+ return wrap(target.get(rawKey));
+ } else if (target !== rawTarget) {
+ target.get(key);
+ }
+ },
+ get size() {
+ const target = this["__v_raw"];
+ !readonly2 && track(toRaw(target), "iterate", ITERATE_KEY);
+ return Reflect.get(target, "size", target);
+ },
+ has(key) {
+ const target = this["__v_raw"];
+ const rawTarget = toRaw(target);
+ const rawKey = toRaw(key);
+ if (!readonly2) {
+ if (hasChanged(key, rawKey)) {
+ track(rawTarget, "has", key);
+ }
+ track(rawTarget, "has", rawKey);
+ }
+ return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey);
+ },
+ forEach(callback, thisArg) {
+ const observed = this;
+ const target = observed["__v_raw"];
+ const rawTarget = toRaw(target);
+ const wrap = shallow ? toShallow : readonly2 ? toReadonly : toReactive;
+ !readonly2 && track(rawTarget, "iterate", ITERATE_KEY);
+ return target.forEach((value, key) => {
+ return callback.call(thisArg, wrap(value), wrap(key), observed);
+ });
+ }
+ };
+ extend(
+ instrumentations,
+ readonly2 ? {
+ add: createReadonlyMethod("add"),
+ set: createReadonlyMethod("set"),
+ delete: createReadonlyMethod("delete"),
+ clear: createReadonlyMethod("clear")
+ } : {
+ add(value) {
+ if (!shallow && !isShallow(value) && !isReadonly(value)) {
+ value = toRaw(value);
+ }
+ const target = toRaw(this);
+ const proto = getProto(target);
+ const hadKey = proto.has.call(target, value);
+ if (!hadKey) {
+ target.add(value);
+ trigger(target, "add", value, value);
+ }
+ return this;
+ },
+ set(key, value) {
+ if (!shallow && !isShallow(value) && !isReadonly(value)) {
+ value = toRaw(value);
+ }
+ const target = toRaw(this);
+ const { has, get } = getProto(target);
+ let hadKey = has.call(target, key);
+ if (!hadKey) {
+ key = toRaw(key);
+ hadKey = has.call(target, key);
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ checkIdentityKeys(target, has, key);
+ }
+ const oldValue = get.call(target, key);
+ target.set(key, value);
+ if (!hadKey) {
+ trigger(target, "add", key, value);
+ } else if (hasChanged(value, oldValue)) {
+ trigger(target, "set", key, value, oldValue);
+ }
+ return this;
+ },
+ delete(key) {
+ const target = toRaw(this);
+ const { has, get } = getProto(target);
+ let hadKey = has.call(target, key);
+ if (!hadKey) {
+ key = toRaw(key);
+ hadKey = has.call(target, key);
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ checkIdentityKeys(target, has, key);
+ }
+ const oldValue = get ? get.call(target, key) : void 0;
+ const result = target.delete(key);
+ if (hadKey) {
+ trigger(target, "delete", key, void 0, oldValue);
+ }
+ return result;
+ },
+ clear() {
+ const target = toRaw(this);
+ const hadItems = target.size !== 0;
+ const oldTarget = !!(process.env.NODE_ENV !== "production") ? isMap(target) ? new Map(target) : new Set(target) : void 0;
+ const result = target.clear();
+ if (hadItems) {
+ trigger(
+ target,
+ "clear",
+ void 0,
+ void 0,
+ oldTarget
+ );
+ }
+ return result;
+ }
+ }
+ );
+ const iteratorMethods = [
+ "keys",
+ "values",
+ "entries",
+ Symbol.iterator
+ ];
+ iteratorMethods.forEach((method) => {
+ instrumentations[method] = createIterableMethod(method, readonly2, shallow);
+ });
+ return instrumentations;
+}
+function createInstrumentationGetter(isReadonly2, shallow) {
+ const instrumentations = createInstrumentations(isReadonly2, shallow);
+ return (target, key, receiver) => {
+ if (key === "__v_isReactive") {
+ return !isReadonly2;
+ } else if (key === "__v_isReadonly") {
+ return isReadonly2;
+ } else if (key === "__v_raw") {
+ return target;
+ }
+ return Reflect.get(
+ hasOwn(instrumentations, key) && key in target ? instrumentations : target,
+ key,
+ receiver
+ );
+ };
+}
+const mutableCollectionHandlers = {
+ get: /* @__PURE__ */ createInstrumentationGetter(false, false)
+};
+const shallowCollectionHandlers = {
+ get: /* @__PURE__ */ createInstrumentationGetter(false, true)
+};
+const readonlyCollectionHandlers = {
+ get: /* @__PURE__ */ createInstrumentationGetter(true, false)
+};
+const shallowReadonlyCollectionHandlers = {
+ get: /* @__PURE__ */ createInstrumentationGetter(true, true)
+};
+function checkIdentityKeys(target, has, key) {
+ const rawKey = toRaw(key);
+ if (rawKey !== key && has.call(target, rawKey)) {
+ const type = toRawType(target);
+ warn(
+ `Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`
+ );
+ }
+}
+const reactiveMap = /* @__PURE__ */ new WeakMap();
+const shallowReactiveMap = /* @__PURE__ */ new WeakMap();
+const readonlyMap = /* @__PURE__ */ new WeakMap();
+const shallowReadonlyMap = /* @__PURE__ */ new WeakMap();
+function targetTypeMap(rawType) {
+ switch (rawType) {
+ case "Object":
+ case "Array":
+ return 1;
+ case "Map":
+ case "Set":
+ case "WeakMap":
+ case "WeakSet":
+ return 2;
+ default:
+ return 0;
+ }
+}
+function getTargetType(value) {
+ return value["__v_skip"] || !Object.isExtensible(value) ? 0 : targetTypeMap(toRawType(value));
+}
+function reactive(target) {
+ if (isReadonly(target)) {
+ return target;
+ }
+ return createReactiveObject(
+ target,
+ false,
+ mutableHandlers,
+ mutableCollectionHandlers,
+ reactiveMap
+ );
+}
+function shallowReactive(target) {
+ return createReactiveObject(
+ target,
+ false,
+ shallowReactiveHandlers,
+ shallowCollectionHandlers,
+ shallowReactiveMap
+ );
+}
+function readonly(target) {
+ return createReactiveObject(
+ target,
+ true,
+ readonlyHandlers,
+ readonlyCollectionHandlers,
+ readonlyMap
+ );
+}
+function shallowReadonly(target) {
+ return createReactiveObject(
+ target,
+ true,
+ shallowReadonlyHandlers,
+ shallowReadonlyCollectionHandlers,
+ shallowReadonlyMap
+ );
+}
+function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) {
+ if (!isObject(target)) {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ warn(
+ `value cannot be made ${isReadonly2 ? "readonly" : "reactive"}: ${String(
+ target
+ )}`
+ );
+ }
+ return target;
+ }
+ if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) {
+ return target;
+ }
+ const targetType = getTargetType(target);
+ if (targetType === 0) {
+ return target;
+ }
+ const existingProxy = proxyMap.get(target);
+ if (existingProxy) {
+ return existingProxy;
+ }
+ const proxy = new Proxy(
+ target,
+ targetType === 2 ? collectionHandlers : baseHandlers
+ );
+ proxyMap.set(target, proxy);
+ return proxy;
+}
+function isReactive(value) {
+ if (isReadonly(value)) {
+ return isReactive(value["__v_raw"]);
+ }
+ return !!(value && value["__v_isReactive"]);
+}
+function isReadonly(value) {
+ return !!(value && value["__v_isReadonly"]);
+}
+function isShallow(value) {
+ return !!(value && value["__v_isShallow"]);
+}
+function isProxy(value) {
+ return value ? !!value["__v_raw"] : false;
+}
+function toRaw(observed) {
+ const raw = observed && observed["__v_raw"];
+ return raw ? toRaw(raw) : observed;
+}
+function markRaw(value) {
+ if (!hasOwn(value, "__v_skip") && Object.isExtensible(value)) {
+ def(value, "__v_skip", true);
+ }
+ return value;
+}
+const toReactive = (value) => isObject(value) ? reactive(value) : value;
+const toReadonly = (value) => isObject(value) ? readonly(value) : value;
+function isRef(r2) {
+ return r2 ? r2["__v_isRef"] === true : false;
+}
+function unref(ref2) {
+ return isRef(ref2) ? ref2.value : ref2;
+}
+const shallowUnwrapHandlers = {
+ get: (target, key, receiver) => key === "__v_raw" ? target : unref(Reflect.get(target, key, receiver)),
+ set: (target, key, value, receiver) => {
+ const oldValue = target[key];
+ if (isRef(oldValue) && !isRef(value)) {
+ oldValue.value = value;
+ return true;
+ } else {
+ return Reflect.set(target, key, value, receiver);
+ }
+ }
+};
+function proxyRefs(objectWithRefs) {
+ return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers);
+}
+class ComputedRefImpl {
+ constructor(fn, setter, isSSR) {
+ this.fn = fn;
+ this.setter = setter;
+ this._value = void 0;
+ this.dep = new Dep(this);
+ this.__v_isRef = true;
+ this.deps = void 0;
+ this.depsTail = void 0;
+ this.flags = 16;
+ this.globalVersion = globalVersion - 1;
+ this.next = void 0;
+ this.effect = this;
+ this["__v_isReadonly"] = !setter;
+ this.isSSR = isSSR;
+ }
+ /**
+ * @internal
+ */
+ notify() {
+ this.flags |= 16;
+ if (!(this.flags & 8) && // avoid infinite self recursion
+ activeSub !== this) {
+ batch(this, true);
+ return true;
+ } else if (!!(process.env.NODE_ENV !== "production")) ;
+ }
+ get value() {
+ const link = !!(process.env.NODE_ENV !== "production") ? this.dep.track({
+ target: this,
+ type: "get",
+ key: "value"
+ }) : this.dep.track();
+ refreshComputed(this);
+ if (link) {
+ link.version = this.dep.version;
+ }
+ return this._value;
+ }
+ set value(newValue) {
+ if (this.setter) {
+ this.setter(newValue);
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ warn("Write operation failed: computed value is readonly");
+ }
+ }
+}
+function computed$1(getterOrOptions, debugOptions, isSSR = false) {
+ let getter;
+ let setter;
+ if (isFunction(getterOrOptions)) {
+ getter = getterOrOptions;
+ } else {
+ getter = getterOrOptions.get;
+ setter = getterOrOptions.set;
+ }
+ const cRef = new ComputedRefImpl(getter, setter, isSSR);
+ if (!!(process.env.NODE_ENV !== "production") && debugOptions) ;
+ return cRef;
+}
+const INITIAL_WATCHER_VALUE = {};
+const cleanupMap = /* @__PURE__ */ new WeakMap();
+let activeWatcher = void 0;
+function onWatcherCleanup(cleanupFn, failSilently = false, owner = activeWatcher) {
+ if (owner) {
+ let cleanups = cleanupMap.get(owner);
+ if (!cleanups) cleanupMap.set(owner, cleanups = []);
+ cleanups.push(cleanupFn);
+ } else if (!!(process.env.NODE_ENV !== "production") && !failSilently) {
+ warn(
+ `onWatcherCleanup() was called when there was no active watcher to associate with.`
+ );
+ }
+}
+function watch$1(source, cb, options = EMPTY_OBJ) {
+ const { immediate, deep, once, scheduler, augmentJob, call } = options;
+ const warnInvalidSource = (s2) => {
+ (options.onWarn || warn)(
+ `Invalid watch source: `,
+ s2,
+ `A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.`
+ );
+ };
+ const reactiveGetter = (source2) => {
+ if (deep) return source2;
+ if (isShallow(source2) || deep === false || deep === 0)
+ return traverse(source2, 1);
+ return traverse(source2);
+ };
+ let effect;
+ let getter;
+ let cleanup;
+ let boundCleanup;
+ let forceTrigger = false;
+ let isMultiSource = false;
+ if (isRef(source)) {
+ getter = () => source.value;
+ forceTrigger = isShallow(source);
+ } else if (isReactive(source)) {
+ getter = () => reactiveGetter(source);
+ forceTrigger = true;
+ } else if (isArray(source)) {
+ isMultiSource = true;
+ forceTrigger = source.some((s2) => isReactive(s2) || isShallow(s2));
+ getter = () => source.map((s2) => {
+ if (isRef(s2)) {
+ return s2.value;
+ } else if (isReactive(s2)) {
+ return reactiveGetter(s2);
+ } else if (isFunction(s2)) {
+ return call ? call(s2, 2) : s2();
+ } else {
+ !!(process.env.NODE_ENV !== "production") && warnInvalidSource(s2);
+ }
+ });
+ } else if (isFunction(source)) {
+ if (cb) {
+ getter = call ? () => call(source, 2) : source;
+ } else {
+ getter = () => {
+ if (cleanup) {
+ pauseTracking();
+ try {
+ cleanup();
+ } finally {
+ resetTracking();
+ }
+ }
+ const currentEffect = activeWatcher;
+ activeWatcher = effect;
+ try {
+ return call ? call(source, 3, [boundCleanup]) : source(boundCleanup);
+ } finally {
+ activeWatcher = currentEffect;
+ }
+ };
+ }
+ } else {
+ getter = NOOP;
+ !!(process.env.NODE_ENV !== "production") && warnInvalidSource(source);
+ }
+ if (cb && deep) {
+ const baseGetter = getter;
+ const depth = deep === true ? Infinity : deep;
+ getter = () => traverse(baseGetter(), depth);
+ }
+ const scope = getCurrentScope();
+ const watchHandle = () => {
+ effect.stop();
+ if (scope && scope.active) {
+ remove(scope.effects, effect);
+ }
+ };
+ if (once && cb) {
+ const _cb = cb;
+ cb = (...args) => {
+ _cb(...args);
+ watchHandle();
+ };
+ }
+ let oldValue = isMultiSource ? new Array(source.length).fill(INITIAL_WATCHER_VALUE) : INITIAL_WATCHER_VALUE;
+ const job = (immediateFirstRun) => {
+ if (!(effect.flags & 1) || !effect.dirty && !immediateFirstRun) {
+ return;
+ }
+ if (cb) {
+ const newValue = effect.run();
+ if (deep || forceTrigger || (isMultiSource ? newValue.some((v, i2) => hasChanged(v, oldValue[i2])) : hasChanged(newValue, oldValue))) {
+ if (cleanup) {
+ cleanup();
+ }
+ const currentWatcher = activeWatcher;
+ activeWatcher = effect;
+ try {
+ const args = [
+ newValue,
+ // pass undefined as the old value when it's changed for the first time
+ oldValue === INITIAL_WATCHER_VALUE ? void 0 : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE ? [] : oldValue,
+ boundCleanup
+ ];
+ oldValue = newValue;
+ call ? call(cb, 3, args) : (
+ // @ts-expect-error
+ cb(...args)
+ );
+ } finally {
+ activeWatcher = currentWatcher;
+ }
+ }
+ } else {
+ effect.run();
+ }
+ };
+ if (augmentJob) {
+ augmentJob(job);
+ }
+ effect = new ReactiveEffect(getter);
+ effect.scheduler = scheduler ? () => scheduler(job, false) : job;
+ boundCleanup = (fn) => onWatcherCleanup(fn, false, effect);
+ cleanup = effect.onStop = () => {
+ const cleanups = cleanupMap.get(effect);
+ if (cleanups) {
+ if (call) {
+ call(cleanups, 4);
+ } else {
+ for (const cleanup2 of cleanups) cleanup2();
+ }
+ cleanupMap.delete(effect);
+ }
+ };
+ if (!!(process.env.NODE_ENV !== "production")) {
+ effect.onTrack = options.onTrack;
+ effect.onTrigger = options.onTrigger;
+ }
+ if (cb) {
+ if (immediate) {
+ job(true);
+ } else {
+ oldValue = effect.run();
+ }
+ } else if (scheduler) {
+ scheduler(job.bind(null, true), true);
+ } else {
+ effect.run();
+ }
+ watchHandle.pause = effect.pause.bind(effect);
+ watchHandle.resume = effect.resume.bind(effect);
+ watchHandle.stop = watchHandle;
+ return watchHandle;
+}
+function traverse(value, depth = Infinity, seen) {
+ if (depth <= 0 || !isObject(value) || value["__v_skip"]) {
+ return value;
+ }
+ seen = seen || /* @__PURE__ */ new Set();
+ if (seen.has(value)) {
+ return value;
+ }
+ seen.add(value);
+ depth--;
+ if (isRef(value)) {
+ traverse(value.value, depth, seen);
+ } else if (isArray(value)) {
+ for (let i2 = 0; i2 < value.length; i2++) {
+ traverse(value[i2], depth, seen);
+ }
+ } else if (isSet(value) || isMap(value)) {
+ value.forEach((v) => {
+ traverse(v, depth, seen);
+ });
+ } else if (isPlainObject(value)) {
+ for (const key in value) {
+ traverse(value[key], depth, seen);
+ }
+ for (const key of Object.getOwnPropertySymbols(value)) {
+ if (Object.prototype.propertyIsEnumerable.call(value, key)) {
+ traverse(value[key], depth, seen);
+ }
+ }
+ }
+ return value;
+}
+/**
+* @vue/runtime-core v3.5.17
+* (c) 2018-present Yuxi (Evan) You and Vue contributors
+* @license MIT
+**/
+const stack = [];
+function pushWarningContext(vnode) {
+ stack.push(vnode);
+}
+function popWarningContext() {
+ stack.pop();
+}
+let isWarning = false;
+function warn$1(msg, ...args) {
+ if (isWarning) return;
+ isWarning = true;
+ pauseTracking();
+ const instance = stack.length ? stack[stack.length - 1].component : null;
+ const appWarnHandler = instance && instance.appContext.config.warnHandler;
+ const trace = getComponentTrace();
+ if (appWarnHandler) {
+ callWithErrorHandling(
+ appWarnHandler,
+ instance,
+ 11,
+ [
+ // eslint-disable-next-line no-restricted-syntax
+ msg + args.map((a2) => {
+ var _a, _b;
+ return (_b = (_a = a2.toString) == null ? void 0 : _a.call(a2)) != null ? _b : JSON.stringify(a2);
+ }).join(""),
+ instance && instance.proxy,
+ trace.map(
+ ({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`
+ ).join("\n"),
+ trace
+ ]
+ );
+ } else {
+ const warnArgs = [`[Vue warn]: ${msg}`, ...args];
+ if (trace.length && // avoid spamming console during tests
+ true) {
+ warnArgs.push(`
+`, ...formatTrace(trace));
+ }
+ console.warn(...warnArgs);
+ }
+ resetTracking();
+ isWarning = false;
+}
+function getComponentTrace() {
+ let currentVNode = stack[stack.length - 1];
+ if (!currentVNode) {
+ return [];
+ }
+ const normalizedStack = [];
+ while (currentVNode) {
+ const last = normalizedStack[0];
+ if (last && last.vnode === currentVNode) {
+ last.recurseCount++;
+ } else {
+ normalizedStack.push({
+ vnode: currentVNode,
+ recurseCount: 0
+ });
+ }
+ const parentInstance = currentVNode.component && currentVNode.component.parent;
+ currentVNode = parentInstance && parentInstance.vnode;
+ }
+ return normalizedStack;
+}
+function formatTrace(trace) {
+ const logs = [];
+ trace.forEach((entry, i2) => {
+ logs.push(...i2 === 0 ? [] : [`
+`], ...formatTraceEntry(entry));
+ });
+ return logs;
+}
+function formatTraceEntry({ vnode, recurseCount }) {
+ const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
+ const isRoot = vnode.component ? vnode.component.parent == null : false;
+ const open = ` at <${formatComponentName(
+ vnode.component,
+ vnode.type,
+ isRoot
+ )}`;
+ const close = `>` + postfix;
+ return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close];
+}
+function formatProps(props) {
+ const res = [];
+ const keys = Object.keys(props);
+ keys.slice(0, 3).forEach((key) => {
+ res.push(...formatProp(key, props[key]));
+ });
+ if (keys.length > 3) {
+ res.push(` ...`);
+ }
+ return res;
+}
+function formatProp(key, value, raw) {
+ if (isString(value)) {
+ value = JSON.stringify(value);
+ return raw ? value : [`${key}=${value}`];
+ } else if (typeof value === "number" || typeof value === "boolean" || value == null) {
+ return raw ? value : [`${key}=${value}`];
+ } else if (isRef(value)) {
+ value = formatProp(key, toRaw(value.value), true);
+ return raw ? value : [`${key}=Ref<`, value, `>`];
+ } else if (isFunction(value)) {
+ return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
+ } else {
+ value = toRaw(value);
+ return raw ? value : [`${key}=`, value];
+ }
+}
+const ErrorTypeStrings$1 = {
+ ["sp"]: "serverPrefetch hook",
+ ["bc"]: "beforeCreate hook",
+ ["c"]: "created hook",
+ ["bm"]: "beforeMount hook",
+ ["m"]: "mounted hook",
+ ["bu"]: "beforeUpdate hook",
+ ["u"]: "updated",
+ ["bum"]: "beforeUnmount hook",
+ ["um"]: "unmounted hook",
+ ["a"]: "activated hook",
+ ["da"]: "deactivated hook",
+ ["ec"]: "errorCaptured hook",
+ ["rtc"]: "renderTracked hook",
+ ["rtg"]: "renderTriggered hook",
+ [0]: "setup function",
+ [1]: "render function",
+ [2]: "watcher getter",
+ [3]: "watcher callback",
+ [4]: "watcher cleanup function",
+ [5]: "native event handler",
+ [6]: "component event handler",
+ [7]: "vnode hook",
+ [8]: "directive hook",
+ [9]: "transition hook",
+ [10]: "app errorHandler",
+ [11]: "app warnHandler",
+ [12]: "ref function",
+ [13]: "async component loader",
+ [14]: "scheduler flush",
+ [15]: "component update",
+ [16]: "app unmount cleanup function"
+};
+function callWithErrorHandling(fn, instance, type, args) {
+ try {
+ return args ? fn(...args) : fn();
+ } catch (err) {
+ handleError(err, instance, type);
+ }
+}
+function callWithAsyncErrorHandling(fn, instance, type, args) {
+ if (isFunction(fn)) {
+ const res = callWithErrorHandling(fn, instance, type, args);
+ if (res && isPromise(res)) {
+ res.catch((err) => {
+ handleError(err, instance, type);
+ });
+ }
+ return res;
+ }
+ if (isArray(fn)) {
+ const values = [];
+ for (let i2 = 0; i2 < fn.length; i2++) {
+ values.push(callWithAsyncErrorHandling(fn[i2], instance, type, args));
+ }
+ return values;
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ warn$1(
+ `Invalid value type passed to callWithAsyncErrorHandling(): ${typeof fn}`
+ );
+ }
+}
+function handleError(err, instance, type, throwInDev = true) {
+ const contextVNode = instance ? instance.vnode : null;
+ const { errorHandler, throwUnhandledErrorInProduction } = instance && instance.appContext.config || EMPTY_OBJ;
+ if (instance) {
+ let cur = instance.parent;
+ const exposedInstance = instance.proxy;
+ const errorInfo = !!(process.env.NODE_ENV !== "production") ? ErrorTypeStrings$1[type] : `https://vuejs.org/error-reference/#runtime-${type}`;
+ while (cur) {
+ const errorCapturedHooks = cur.ec;
+ if (errorCapturedHooks) {
+ for (let i2 = 0; i2 < errorCapturedHooks.length; i2++) {
+ if (errorCapturedHooks[i2](err, exposedInstance, errorInfo) === false) {
+ return;
+ }
+ }
+ }
+ cur = cur.parent;
+ }
+ if (errorHandler) {
+ pauseTracking();
+ callWithErrorHandling(errorHandler, null, 10, [
+ err,
+ exposedInstance,
+ errorInfo
+ ]);
+ resetTracking();
+ return;
+ }
+ }
+ logError(err, type, contextVNode, throwInDev, throwUnhandledErrorInProduction);
+}
+function logError(err, type, contextVNode, throwInDev = true, throwInProd = false) {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ const info = ErrorTypeStrings$1[type];
+ if (contextVNode) {
+ pushWarningContext(contextVNode);
+ }
+ warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
+ if (contextVNode) {
+ popWarningContext();
+ }
+ if (throwInDev) {
+ throw err;
+ } else {
+ console.error(err);
+ }
+ } else if (throwInProd) {
+ throw err;
+ } else {
+ console.error(err);
+ }
+}
+const queue = [];
+let flushIndex = -1;
+const pendingPostFlushCbs = [];
+let activePostFlushCbs = null;
+let postFlushIndex = 0;
+const resolvedPromise = /* @__PURE__ */ Promise.resolve();
+let currentFlushPromise = null;
+const RECURSION_LIMIT = 100;
+function nextTick(fn) {
+ const p = currentFlushPromise || resolvedPromise;
+ return fn ? p.then(this ? fn.bind(this) : fn) : p;
+}
+function findInsertionIndex(id) {
+ let start = flushIndex + 1;
+ let end = queue.length;
+ while (start < end) {
+ const middle = start + end >>> 1;
+ const middleJob = queue[middle];
+ const middleJobId = getId(middleJob);
+ if (middleJobId < id || middleJobId === id && middleJob.flags & 2) {
+ start = middle + 1;
+ } else {
+ end = middle;
+ }
+ }
+ return start;
+}
+function queueJob(job) {
+ if (!(job.flags & 1)) {
+ const jobId = getId(job);
+ const lastJob = queue[queue.length - 1];
+ if (!lastJob || // fast path when the job id is larger than the tail
+ !(job.flags & 2) && jobId >= getId(lastJob)) {
+ queue.push(job);
+ } else {
+ queue.splice(findInsertionIndex(jobId), 0, job);
+ }
+ job.flags |= 1;
+ queueFlush();
+ }
+}
+function queueFlush() {
+ if (!currentFlushPromise) {
+ currentFlushPromise = resolvedPromise.then(flushJobs);
+ }
+}
+function queuePostFlushCb(cb) {
+ if (!isArray(cb)) {
+ if (activePostFlushCbs && cb.id === -1) {
+ activePostFlushCbs.splice(postFlushIndex + 1, 0, cb);
+ } else if (!(cb.flags & 1)) {
+ pendingPostFlushCbs.push(cb);
+ cb.flags |= 1;
+ }
+ } else {
+ pendingPostFlushCbs.push(...cb);
+ }
+ queueFlush();
+}
+function flushPreFlushCbs(instance, seen, i2 = flushIndex + 1) {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ seen = seen || /* @__PURE__ */ new Map();
+ }
+ for (; i2 < queue.length; i2++) {
+ const cb = queue[i2];
+ if (cb && cb.flags & 2) {
+ if (instance && cb.id !== instance.uid) {
+ continue;
+ }
+ if (!!(process.env.NODE_ENV !== "production") && checkRecursiveUpdates(seen, cb)) {
+ continue;
+ }
+ queue.splice(i2, 1);
+ i2--;
+ if (cb.flags & 4) {
+ cb.flags &= -2;
+ }
+ cb();
+ if (!(cb.flags & 4)) {
+ cb.flags &= -2;
+ }
+ }
+ }
+}
+function flushPostFlushCbs(seen) {
+ if (pendingPostFlushCbs.length) {
+ const deduped = [...new Set(pendingPostFlushCbs)].sort(
+ (a2, b) => getId(a2) - getId(b)
+ );
+ pendingPostFlushCbs.length = 0;
+ if (activePostFlushCbs) {
+ activePostFlushCbs.push(...deduped);
+ return;
+ }
+ activePostFlushCbs = deduped;
+ if (!!(process.env.NODE_ENV !== "production")) {
+ seen = seen || /* @__PURE__ */ new Map();
+ }
+ for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
+ const cb = activePostFlushCbs[postFlushIndex];
+ if (!!(process.env.NODE_ENV !== "production") && checkRecursiveUpdates(seen, cb)) {
+ continue;
+ }
+ if (cb.flags & 4) {
+ cb.flags &= -2;
+ }
+ if (!(cb.flags & 8)) cb();
+ cb.flags &= -2;
+ }
+ activePostFlushCbs = null;
+ postFlushIndex = 0;
+ }
+}
+const getId = (job) => job.id == null ? job.flags & 2 ? -1 : Infinity : job.id;
+function flushJobs(seen) {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ seen = seen || /* @__PURE__ */ new Map();
+ }
+ const check = !!(process.env.NODE_ENV !== "production") ? (job) => checkRecursiveUpdates(seen, job) : NOOP;
+ try {
+ for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
+ const job = queue[flushIndex];
+ if (job && !(job.flags & 8)) {
+ if (!!(process.env.NODE_ENV !== "production") && check(job)) {
+ continue;
+ }
+ if (job.flags & 4) {
+ job.flags &= ~1;
+ }
+ callWithErrorHandling(
+ job,
+ job.i,
+ job.i ? 15 : 14
+ );
+ if (!(job.flags & 4)) {
+ job.flags &= ~1;
+ }
+ }
+ }
+ } finally {
+ for (; flushIndex < queue.length; flushIndex++) {
+ const job = queue[flushIndex];
+ if (job) {
+ job.flags &= -2;
+ }
+ }
+ flushIndex = -1;
+ queue.length = 0;
+ flushPostFlushCbs(seen);
+ currentFlushPromise = null;
+ if (queue.length || pendingPostFlushCbs.length) {
+ flushJobs(seen);
+ }
+ }
+}
+function checkRecursiveUpdates(seen, fn) {
+ const count = seen.get(fn) || 0;
+ if (count > RECURSION_LIMIT) {
+ const instance = fn.i;
+ const componentName = instance && getComponentName(instance.type);
+ handleError(
+ `Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.`,
+ null,
+ 10
+ );
+ return true;
+ }
+ seen.set(fn, count + 1);
+ return false;
+}
+let isHmrUpdating = false;
+const hmrDirtyComponents = /* @__PURE__ */ new Map();
+if (!!(process.env.NODE_ENV !== "production")) {
+ getGlobalThis().__VUE_HMR_RUNTIME__ = {
+ createRecord: tryWrap(createRecord),
+ rerender: tryWrap(rerender),
+ reload: tryWrap(reload)
+ };
+}
+const map = /* @__PURE__ */ new Map();
+function registerHMR(instance) {
+ const id = instance.type.__hmrId;
+ let record = map.get(id);
+ if (!record) {
+ createRecord(id, instance.type);
+ record = map.get(id);
+ }
+ record.instances.add(instance);
+}
+function unregisterHMR(instance) {
+ map.get(instance.type.__hmrId).instances.delete(instance);
+}
+function createRecord(id, initialDef) {
+ if (map.has(id)) {
+ return false;
+ }
+ map.set(id, {
+ initialDef: normalizeClassComponent(initialDef),
+ instances: /* @__PURE__ */ new Set()
+ });
+ return true;
+}
+function normalizeClassComponent(component) {
+ return isClassComponent(component) ? component.__vccOpts : component;
+}
+function rerender(id, newRender) {
+ const record = map.get(id);
+ if (!record) {
+ return;
+ }
+ record.initialDef.render = newRender;
+ [...record.instances].forEach((instance) => {
+ if (newRender) {
+ instance.render = newRender;
+ normalizeClassComponent(instance.type).render = newRender;
+ }
+ instance.renderCache = [];
+ isHmrUpdating = true;
+ instance.update();
+ isHmrUpdating = false;
+ });
+}
+function reload(id, newComp) {
+ const record = map.get(id);
+ if (!record) return;
+ newComp = normalizeClassComponent(newComp);
+ updateComponentDef(record.initialDef, newComp);
+ const instances = [...record.instances];
+ for (let i2 = 0; i2 < instances.length; i2++) {
+ const instance = instances[i2];
+ const oldComp = normalizeClassComponent(instance.type);
+ let dirtyInstances = hmrDirtyComponents.get(oldComp);
+ if (!dirtyInstances) {
+ if (oldComp !== record.initialDef) {
+ updateComponentDef(oldComp, newComp);
+ }
+ hmrDirtyComponents.set(oldComp, dirtyInstances = /* @__PURE__ */ new Set());
+ }
+ dirtyInstances.add(instance);
+ instance.appContext.propsCache.delete(instance.type);
+ instance.appContext.emitsCache.delete(instance.type);
+ instance.appContext.optionsCache.delete(instance.type);
+ if (instance.ceReload) {
+ dirtyInstances.add(instance);
+ instance.ceReload(newComp.styles);
+ dirtyInstances.delete(instance);
+ } else if (instance.parent) {
+ queueJob(() => {
+ isHmrUpdating = true;
+ instance.parent.update();
+ isHmrUpdating = false;
+ dirtyInstances.delete(instance);
+ });
+ } else if (instance.appContext.reload) {
+ instance.appContext.reload();
+ } else if (typeof window !== "undefined") {
+ window.location.reload();
+ } else {
+ console.warn(
+ "[HMR] Root or manually mounted instance modified. Full reload required."
+ );
+ }
+ if (instance.root.ce && instance !== instance.root) {
+ instance.root.ce._removeChildStyle(oldComp);
+ }
+ }
+ queuePostFlushCb(() => {
+ hmrDirtyComponents.clear();
+ });
+}
+function updateComponentDef(oldComp, newComp) {
+ extend(oldComp, newComp);
+ for (const key in oldComp) {
+ if (key !== "__file" && !(key in newComp)) {
+ delete oldComp[key];
+ }
+ }
+}
+function tryWrap(fn) {
+ return (id, arg) => {
+ try {
+ return fn(id, arg);
+ } catch (e2) {
+ console.error(e2);
+ console.warn(
+ `[HMR] Something went wrong during Vue component hot-reload. Full reload required.`
+ );
+ }
+ };
+}
+let devtools$1;
+let buffer = [];
+let devtoolsNotInstalled = false;
+function emit$1(event, ...args) {
+ if (devtools$1) {
+ devtools$1.emit(event, ...args);
+ } else if (!devtoolsNotInstalled) {
+ buffer.push({ event, args });
+ }
+}
+function setDevtoolsHook$1(hook, target) {
+ var _a, _b;
+ devtools$1 = hook;
+ if (devtools$1) {
+ devtools$1.enabled = true;
+ buffer.forEach(({ event, args }) => devtools$1.emit(event, ...args));
+ buffer = [];
+ } else if (
+ // handle late devtools injection - only do this if we are in an actual
+ // browser environment to avoid the timer handle stalling test runner exit
+ // (#4815)
+ typeof window !== "undefined" && // some envs mock window but not fully
+ window.HTMLElement && // also exclude jsdom
+ // eslint-disable-next-line no-restricted-syntax
+ !((_b = (_a = window.navigator) == null ? void 0 : _a.userAgent) == null ? void 0 : _b.includes("jsdom"))
+ ) {
+ const replay = target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || [];
+ replay.push((newHook) => {
+ setDevtoolsHook$1(newHook, target);
+ });
+ setTimeout(() => {
+ if (!devtools$1) {
+ target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;
+ devtoolsNotInstalled = true;
+ buffer = [];
+ }
+ }, 3e3);
+ } else {
+ devtoolsNotInstalled = true;
+ buffer = [];
+ }
+}
+function devtoolsInitApp(app, version2) {
+ emit$1("app:init", app, version2, {
+ Fragment,
+ Text,
+ Comment,
+ Static
+ });
+}
+function devtoolsUnmountApp(app) {
+ emit$1("app:unmount", app);
+}
+const devtoolsComponentAdded = /* @__PURE__ */ createDevtoolsComponentHook(
+ "component:added"
+ /* COMPONENT_ADDED */
+);
+const devtoolsComponentUpdated = /* @__PURE__ */ createDevtoolsComponentHook(
+ "component:updated"
+ /* COMPONENT_UPDATED */
+);
+const _devtoolsComponentRemoved = /* @__PURE__ */ createDevtoolsComponentHook(
+ "component:removed"
+ /* COMPONENT_REMOVED */
+);
+const devtoolsComponentRemoved = (component) => {
+ if (devtools$1 && typeof devtools$1.cleanupBuffer === "function" && // remove the component if it wasn't buffered
+ !devtools$1.cleanupBuffer(component)) {
+ _devtoolsComponentRemoved(component);
+ }
+};
+/*! #__NO_SIDE_EFFECTS__ */
+// @__NO_SIDE_EFFECTS__
+function createDevtoolsComponentHook(hook) {
+ return (component) => {
+ emit$1(
+ hook,
+ component.appContext.app,
+ component.uid,
+ component.parent ? component.parent.uid : void 0,
+ component
+ );
+ };
+}
+const devtoolsPerfStart = /* @__PURE__ */ createDevtoolsPerformanceHook(
+ "perf:start"
+ /* PERFORMANCE_START */
+);
+const devtoolsPerfEnd = /* @__PURE__ */ createDevtoolsPerformanceHook(
+ "perf:end"
+ /* PERFORMANCE_END */
+);
+function createDevtoolsPerformanceHook(hook) {
+ return (component, type, time) => {
+ emit$1(hook, component.appContext.app, component.uid, component, type, time);
+ };
+}
+function devtoolsComponentEmit(component, event, params) {
+ emit$1(
+ "component:emit",
+ component.appContext.app,
+ component,
+ event,
+ params
+ );
+}
+let currentRenderingInstance = null;
+let currentScopeId = null;
+function setCurrentRenderingInstance(instance) {
+ const prev = currentRenderingInstance;
+ currentRenderingInstance = instance;
+ currentScopeId = instance && instance.type.__scopeId || null;
+ return prev;
+}
+function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot) {
+ if (!ctx) return fn;
+ if (fn._n) {
+ return fn;
+ }
+ const renderFnWithContext = (...args) => {
+ if (renderFnWithContext._d) {
+ setBlockTracking(-1);
+ }
+ const prevInstance = setCurrentRenderingInstance(ctx);
+ let res;
+ try {
+ res = fn(...args);
+ } finally {
+ setCurrentRenderingInstance(prevInstance);
+ if (renderFnWithContext._d) {
+ setBlockTracking(1);
+ }
+ }
+ if (!!(process.env.NODE_ENV !== "production") || false) {
+ devtoolsComponentUpdated(ctx);
+ }
+ return res;
+ };
+ renderFnWithContext._n = true;
+ renderFnWithContext._c = true;
+ renderFnWithContext._d = true;
+ return renderFnWithContext;
+}
+function validateDirectiveName(name) {
+ if (isBuiltInDirective(name)) {
+ warn$1("Do not use built-in directive ids as custom directive id: " + name);
+ }
+}
+function invokeDirectiveHook(vnode, prevVNode, instance, name) {
+ const bindings = vnode.dirs;
+ const oldBindings = prevVNode && prevVNode.dirs;
+ for (let i2 = 0; i2 < bindings.length; i2++) {
+ const binding = bindings[i2];
+ if (oldBindings) {
+ binding.oldValue = oldBindings[i2].value;
+ }
+ let hook = binding.dir[name];
+ if (hook) {
+ pauseTracking();
+ callWithAsyncErrorHandling(hook, instance, 8, [
+ vnode.el,
+ binding,
+ vnode,
+ prevVNode
+ ]);
+ resetTracking();
+ }
+ }
+}
+const TeleportEndKey = Symbol("_vte");
+const isTeleport = (type) => type.__isTeleport;
+function setTransitionHooks(vnode, hooks) {
+ if (vnode.shapeFlag & 6 && vnode.component) {
+ vnode.transition = hooks;
+ setTransitionHooks(vnode.component.subTree, hooks);
+ } else if (vnode.shapeFlag & 128) {
+ vnode.ssContent.transition = hooks.clone(vnode.ssContent);
+ vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
+ } else {
+ vnode.transition = hooks;
+ }
+}
+function markAsyncBoundary(instance) {
+ instance.ids = [instance.ids[0] + instance.ids[2]++ + "-", 0, 0];
+}
+const knownTemplateRefs = /* @__PURE__ */ new WeakSet();
+function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
+ if (isArray(rawRef)) {
+ rawRef.forEach(
+ (r2, i2) => setRef(
+ r2,
+ oldRawRef && (isArray(oldRawRef) ? oldRawRef[i2] : oldRawRef),
+ parentSuspense,
+ vnode,
+ isUnmount
+ )
+ );
+ return;
+ }
+ if (isAsyncWrapper(vnode) && !isUnmount) {
+ if (vnode.shapeFlag & 512 && vnode.type.__asyncResolved && vnode.component.subTree.component) {
+ setRef(rawRef, oldRawRef, parentSuspense, vnode.component.subTree);
+ }
+ return;
+ }
+ const refValue = vnode.shapeFlag & 4 ? getComponentPublicInstance(vnode.component) : vnode.el;
+ const value = isUnmount ? null : refValue;
+ const { i: owner, r: ref3 } = rawRef;
+ if (!!(process.env.NODE_ENV !== "production") && !owner) {
+ warn$1(
+ `Missing ref owner context. ref cannot be used on hoisted vnodes. A vnode with ref must be created inside the render function.`
+ );
+ return;
+ }
+ const oldRef = oldRawRef && oldRawRef.r;
+ const refs = owner.refs === EMPTY_OBJ ? owner.refs = {} : owner.refs;
+ const setupState = owner.setupState;
+ const rawSetupState = toRaw(setupState);
+ const canSetSetupRef = setupState === EMPTY_OBJ ? () => false : (key) => {
+ if (!!(process.env.NODE_ENV !== "production")) {
+ if (hasOwn(rawSetupState, key) && !isRef(rawSetupState[key])) {
+ warn$1(
+ `Template ref "${key}" used on a non-ref value. It will not work in the production build.`
+ );
+ }
+ if (knownTemplateRefs.has(rawSetupState[key])) {
+ return false;
+ }
+ }
+ return hasOwn(rawSetupState, key);
+ };
+ if (oldRef != null && oldRef !== ref3) {
+ if (isString(oldRef)) {
+ refs[oldRef] = null;
+ if (canSetSetupRef(oldRef)) {
+ setupState[oldRef] = null;
+ }
+ } else if (isRef(oldRef)) {
+ oldRef.value = null;
+ }
+ }
+ if (isFunction(ref3)) {
+ callWithErrorHandling(ref3, owner, 12, [value, refs]);
+ } else {
+ const _isString = isString(ref3);
+ const _isRef = isRef(ref3);
+ if (_isString || _isRef) {
+ const doSet = () => {
+ if (rawRef.f) {
+ const existing = _isString ? canSetSetupRef(ref3) ? setupState[ref3] : refs[ref3] : ref3.value;
+ if (isUnmount) {
+ isArray(existing) && remove(existing, refValue);
+ } else {
+ if (!isArray(existing)) {
+ if (_isString) {
+ refs[ref3] = [refValue];
+ if (canSetSetupRef(ref3)) {
+ setupState[ref3] = refs[ref3];
+ }
+ } else {
+ ref3.value = [refValue];
+ if (rawRef.k) refs[rawRef.k] = ref3.value;
+ }
+ } else if (!existing.includes(refValue)) {
+ existing.push(refValue);
+ }
+ }
+ } else if (_isString) {
+ refs[ref3] = value;
+ if (canSetSetupRef(ref3)) {
+ setupState[ref3] = value;
+ }
+ } else if (_isRef) {
+ ref3.value = value;
+ if (rawRef.k) refs[rawRef.k] = value;
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ warn$1("Invalid template ref type:", ref3, `(${typeof ref3})`);
+ }
+ };
+ if (value) {
+ doSet.id = -1;
+ queuePostRenderEffect(doSet, parentSuspense);
+ } else {
+ doSet();
+ }
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ warn$1("Invalid template ref type:", ref3, `(${typeof ref3})`);
+ }
+ }
+}
+getGlobalThis().requestIdleCallback || ((cb) => setTimeout(cb, 1));
+getGlobalThis().cancelIdleCallback || ((id) => clearTimeout(id));
+const isAsyncWrapper = (i2) => !!i2.type.__asyncLoader;
+const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
+function onActivated(hook, target) {
+ registerKeepAliveHook(hook, "a", target);
+}
+function onDeactivated(hook, target) {
+ registerKeepAliveHook(hook, "da", target);
+}
+function registerKeepAliveHook(hook, type, target = currentInstance) {
+ const wrappedHook = hook.__wdc || (hook.__wdc = () => {
+ let current = target;
+ while (current) {
+ if (current.isDeactivated) {
+ return;
+ }
+ current = current.parent;
+ }
+ return hook();
+ });
+ injectHook(type, wrappedHook, target);
+ if (target) {
+ let current = target.parent;
+ while (current && current.parent) {
+ if (isKeepAlive(current.parent.vnode)) {
+ injectToKeepAliveRoot(wrappedHook, type, target, current);
+ }
+ current = current.parent;
+ }
+ }
+}
+function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
+ const injected = injectHook(
+ type,
+ hook,
+ keepAliveRoot,
+ true
+ /* prepend */
+ );
+ onUnmounted(() => {
+ remove(keepAliveRoot[type], injected);
+ }, target);
+}
+function injectHook(type, hook, target = currentInstance, prepend = false) {
+ if (target) {
+ const hooks = target[type] || (target[type] = []);
+ const wrappedHook = hook.__weh || (hook.__weh = (...args) => {
+ pauseTracking();
+ const reset = setCurrentInstance(target);
+ const res = callWithAsyncErrorHandling(hook, target, type, args);
+ reset();
+ resetTracking();
+ return res;
+ });
+ if (prepend) {
+ hooks.unshift(wrappedHook);
+ } else {
+ hooks.push(wrappedHook);
+ }
+ return wrappedHook;
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ const apiName = toHandlerKey(ErrorTypeStrings$1[type].replace(/ hook$/, ""));
+ warn$1(
+ `${apiName} is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.`
+ );
+ }
+}
+const createHook = (lifecycle) => (hook, target = currentInstance) => {
+ if (!isInSSRComponentSetup || lifecycle === "sp") {
+ injectHook(lifecycle, (...args) => hook(...args), target);
+ }
+};
+const onBeforeMount = createHook("bm");
+const onMounted = createHook("m");
+const onBeforeUpdate = createHook(
+ "bu"
+);
+const onUpdated = createHook("u");
+const onBeforeUnmount = createHook(
+ "bum"
+);
+const onUnmounted = createHook("um");
+const onServerPrefetch = createHook(
+ "sp"
+);
+const onRenderTriggered = createHook("rtg");
+const onRenderTracked = createHook("rtc");
+function onErrorCaptured(hook, target = currentInstance) {
+ injectHook("ec", hook, target);
+}
+const COMPONENTS = "components";
+function resolveComponent(name, maybeSelfReference) {
+ return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
+}
+const NULL_DYNAMIC_COMPONENT = Symbol.for("v-ndc");
+function resolveDynamicComponent(component) {
+ if (isString(component)) {
+ return resolveAsset(COMPONENTS, component, false) || component;
+ } else {
+ return component || NULL_DYNAMIC_COMPONENT;
+ }
+}
+function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
+ const instance = currentRenderingInstance || currentInstance;
+ if (instance) {
+ const Component = instance.type;
+ {
+ const selfName = getComponentName(
+ Component,
+ false
+ );
+ if (selfName && (selfName === name || selfName === camelize(name) || selfName === capitalize(camelize(name)))) {
+ return Component;
+ }
+ }
+ const res = (
+ // local registration
+ // check instance[type] first which is resolved for options API
+ resolve(instance[type] || Component[type], name) || // global registration
+ resolve(instance.appContext[type], name)
+ );
+ if (!res && maybeSelfReference) {
+ return Component;
+ }
+ if (!!(process.env.NODE_ENV !== "production") && warnMissing && !res) {
+ const extra = `
+If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.`;
+ warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);
+ }
+ return res;
+ } else if (!!(process.env.NODE_ENV !== "production")) {
+ warn$1(
+ `resolve${capitalize(type.slice(0, -1))} can only be used in render() or setup().`
+ );
+ }
+}
+function resolve(registry, name) {
+ return registry && (registry[name] || registry[camelize(name)] || registry[capitalize(camelize(name))]);
+}
+function renderList(source, renderItem, cache, index) {
+ let ret;
+ const cached = cache;
+ const sourceIsArray = isArray(source);
+ if (sourceIsArray || isString(source)) {
+ const sourceIsReactiveArray = sourceIsArray && isReactive(source);
+ let needsWrap = false;
+ let isReadonlySource = false;
+ if (sourceIsReactiveArray) {
+ needsWrap = !isShallow(source);
+ isReadonlySource = isReadonly(source);
+ source = shallowReadArray(source);
+ }
+ ret = new Array(source.length);
+ for (let i2 = 0, l = source.length; i2 < l; i2++) {
+ ret[i2] = renderItem(
+ needsWrap ? isReadonlySource ? toReadonly(toReactive(source[i2])) : toReactive(source[i2]) : source[i2],
+ i2,
+ void 0,
+ cached
+ );
+ }
+ } else if (typeof source === "number") {
+ if (!!(process.env.NODE_ENV !== "production") && !Number.isInteger(source)) {
+ warn$1(`The v-for range expect an integer value but got ${source}.`);
+ }
+ ret = new Array(source);
+ for (let i2 = 0; i2 < source; i2++) {
+ ret[i2] = renderItem(i2 + 1, i2, void 0, cached);
+ }
+ } else if (isObject(source)) {
+ if (source[Symbol.iterator]) {
+ ret = Array.from(
+ source,
+ (item, i2) => renderItem(item, i2, void 0, cached)
+ );
+ } else {
+ const keys = Object.keys(source);
+ ret = new Array(keys.length);
+ for (let i2 = 0, l = keys.length; i2 < l; i2++) {
+ const key = keys[i2];
+ ret[i2] = renderItem(source[key], key, i2, cached);
+ }
+ }
+ } else {
+ ret = [];
+ }
+ return ret;
+}
+const getPublicInstance = (i2) => {
+ if (!i2) return null;
+ if (isStatefulComponent(i2)) return getComponentPublicInstance(i2);
+ return getPublicInstance(i2.parent);
+};
+const publicPropertiesMap = (
+ // Move PURE marker to new line to workaround compiler discarding it
+ // due to type annotation
+ /* @__PURE__ */ extend(/* @__PURE__ */ Object.create(null), {
+ $: (i2) => i2,
+ $el: (i2) => i2.vnode.el,
+ $data: (i2) => i2.data,
+ $props: (i2) => !!(process.env.NODE_ENV !== "production") ? shallowReadonly(i2.props) : i2.props,
+ $attrs: (i2) => !!(process.env.NODE_ENV !== "production") ? shallowReadonly(i2.attrs) : i2.attrs,
+ $slots: (i2) => !!(process.env.NODE_ENV !== "production") ? shallowReadonly(i2.slots) : i2.slots,
+ $refs: (i2) => !!(process.env.NODE_ENV !== "production") ? shallowReadonly(i2.refs) : i2.refs,
+ $parent: (i2) => getPublicInstance(i2.parent),
+ $root: (i2) => getPublicInstance(i2.root),
+ $host: (i2) => i2.ce,
+ $emit: (i2) => i2.emit,
+ $options: (i2) => resolveMergedOptions(i2),
+ $forceUpdate: (i2) => i2.f || (i2.f = () => {
+ queueJob(i2.update);
+ }),
+ $nextTick: (i2) => i2.n || (i2.n = nextTick.bind(i2.proxy)),
+ $watch: (i2) => instanceWatch.bind(i2)
+ })
+);
+const isReservedPrefix = (key) => key === "_" || key === "$";
+const hasSetupBinding = (state, key) => state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn(state, key);
+const PublicInstanceProxyHandlers = {
+ get({ _: instance }, key) {
+ if (key === "__v_skip") {
+ return true;
+ }
+ const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
+ if (!!(process.env.NODE_ENV !== "production") && key === "__isVue") {
+ return true;
+ }
+ let normalizedProps;
+ if (key[0] !== "$") {
+ const n2 = accessCache[key];
+ if (n2 !== void 0) {
+ switch (n2) {
+ case 1:
+ return setupState[key];
+ case 2:
+ return data[key];
+ case 4:
+ return ctx[key];
+ case 3:
+ return props[key];
+ }
+ } else if (hasSetupBinding(setupState, key)) {
+ accessCache[key] = 1;
+ return setupState[key];
+ } else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
+ accessCache[key] = 2;
+ return data[key];
+ } else if (
+ // only cache other properties when instance has declared (thus stable)
+ // props
+ (normalizedProps = instance.propsOptions[0]) && hasOwn(normalizedProps, key)
+ ) {
+ accessCache[key] = 3;
+ return props[key];
+ } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
+ accessCache[key] = 4;
+ return ctx[key];
+ } else if (shouldCacheAccess) {
+ accessCache[key] = 0;
+ }
+ }
+ const publicGetter = publicPropertiesMap[key];
+ let cssModule, globalProperties;
+ if (publicGetter) {
+ if (key === "$attrs") {
+ track(instance.attrs, "get", "");
+ !!(process.env.NODE_ENV !== "production") && markAttrsAccessed();
+ } else if (!!(process.env.NODE_ENV !== "production") && key === "$slots") {
+ track(instance, "get", key);
+ }
+ return publicGetter(instance);
+ } else if (
+ // css module (injected by vue-loader)
+ (cssModule = type.__cssModules) && (cssModule = cssModule[key])
+ ) {
+ return cssModule;
+ } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
+ accessCache[key] = 4;
+ return ctx[key];
+ } else if (
+ // global properties
+ globalProperties = appContext.config.globalProperties, hasOwn(globalProperties, key)
+ ) {
+ {
+ return globalProperties[key];
+ }
+ } else if (!!(process.env.NODE_ENV !== "production") && currentRenderingInstance && (!isString(key) || // #1091 avoid internal isRef/isVNode checks on component instance leading
+ // to infinite warning loop
+ key.indexOf("__v") !== 0)) {
+ if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) {
+ warn$1(
+ `Property ${JSON.stringify(
+ key
+ )} must be accessed via $data because it starts with a reserved character ("$" or "_") and is not proxied on the render context.`
+ );
+ } else if (instance === currentRenderingInstance) {
+ warn$1(
+ `Property ${JSON.stringify(key)} was accessed during render but is not defined on instance.`
+ );
+ }
+ }
+ },
+ set({ _: instance }, key, value) {
+ const { data, setupState, ctx } = instance;
+ if (hasSetupBinding(setupState, key)) {
+ setupState[key] = value;
+ return true;
+ } else if (!!(process.env.NODE_ENV !== "production") && setupState.__isScriptSetup && hasOwn(setupState, key)) {
+ warn$1(`Cannot mutate \n\n.cover-center {\n text-align: center;\n}\n.cover-camp-wrapper {\n padding: 72pt 0 0;\n}\n.cover-camp-organizer {\n font-size: 18pt;\n font-weight: medium;\n}\n.cover-camp-title {\n font-size: 38pt;\n font-weight: semibold;\n margin: 40pt 0;\n}\n.cover-camp-motto {\n font-size: 28pt;\n font-weight: medium;\n}\n \n","\n \n {{ $t('print.cover.title') }} \n \n \n\n\n \n","\n \n {{ $tc('print.toc.title') }} \n \n \n\n\n \n","\n \n {{ $t('print.picasso.title', { period: period.description }) }} \n \n \n\n\n \n","/**\n * Filtering of schedule entries by various criteria.\n * Only the matcher function for matching a single scheduleEntry with\n * a set of filter criteria is implemented here, because this can be\n * used more flexibly in the application.\n */\nconst filterMatchScheduleEntry = (scheduleEntry, filter) => {\n if (!filter) return true\n return (\n // filter by period\n (filter.period === null ||\n filter.period === undefined ||\n scheduleEntry.period()._meta.self === filter.period) &&\n // filter by days: OR filter\n (filter.day === null ||\n filter.day === undefined ||\n filter.day.length === 0 ||\n filter.day.includes(\n scheduleEntry.day()._meta.self\n )) &&\n // filter by categories: OR filter\n (filter.category === null ||\n filter.category === undefined ||\n filter.category.length === 0 ||\n filter.category.includes(\n scheduleEntry.activity().category()._meta.self\n )) &&\n // filter by responsibles: AND filter\n (filter.responsible === null ||\n filter.responsible === undefined ||\n filter.responsible.length === 0 ||\n filter.responsible.every((responsible) => {\n return scheduleEntry\n .activity()\n .activityResponsibles()\n .items.map((responsible) => responsible.campCollaboration()._meta.self)\n .includes(responsible)\n }) ||\n (filter.responsible[0] === 'none' &&\n scheduleEntry.activity().activityResponsibles().items.length === 0)) &&\n (filter.progressLabel === null ||\n filter.progressLabel === undefined ||\n filter.progressLabel.length === 0 ||\n filter.progressLabel.includes(\n scheduleEntry.activity().progressLabel?.()._meta.self ?? 'none'\n ))\n )\n}\n\nexport { filterMatchScheduleEntry }\n","\n \n \n {{ period.description }} \n \n \n \n {{ scheduleEntry.category }}\n {{ scheduleEntry.number }}\n {{ scheduleEntry.title }}\n \n \n \n \n\n\n \n","\n \n \n\n\n \n","\n \n \n {{ scheduleEntry.category }}\n {{ scheduleEntry.number }}\n {{ scheduleEntry.title }}\n \n \n \n\n\n \n","\n","\n \n {{ $t('print.summary.safetyConsiderations.title') }}:\n {{ period.description }} \n \n \n\n","\n \n {{ $tc('print.summary.storycontext.title') }}: {{ period.description }} \n \n \n\n","\n \n {{\n $t('print.toc.title')\n }} \n \n \n \n {{ entry.type }} \n \n \n \n \n\n\n.toc-title {\n font-weight: semibold;\n font-size: 14pt;\n border-bottom: 2pt solid #aaaaaa;\n padding-bottom: 2pt;\n margin-bottom: 8pt;\n}\n.toc-entry {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n color: black;\n text-decoration: none;\n}\n.toc-sub-entry {\n margin-left: 10pt;\n}\n \n","\n \n \n \n \n\n\n.ys-logo-path {\n fill: #e92d35;\n fill-rule: evenodd;\n stroke: none;\n}\n \n","import maxBy from 'lodash-es/maxBy.js'\n\nexport default function longestTime(times, dayjs) {\n return dayjs()\n .hour(0)\n .minute(findLongestText(times)[0] * 60)\n .second(0)\n .format('LT')\n}\n\nfunction findLongestText(times) {\n return maxBy(times, (time) => ((time[0] - 1) % 24) + 1)\n}\n","\n \n {{\n longestTime\n }} \n \n \n\n\n.picasso-time-column-spacer {\n margin-top: 0;\n margin-bottom: 0;\n}\n.picasso-time-column-spacer-text {\n opacity: 0;\n}\n \n","/**\n * Returns a display name for a user\n */\nexport default function (user) {\n return user.displayName || ''\n}\n","import userDisplayName from './userDisplayName.js'\n\n/**\n * Returns a display name for a camp collaboration based on its status\n */\nexport default function (campCollaboration, tc, indicateInactive = true) {\n if (!campCollaboration) {\n return ''\n }\n\n let text =\n typeof campCollaboration.user === 'function'\n ? userDisplayName(campCollaboration.user())\n : campCollaboration.inviteEmail || ''\n\n if (campCollaboration.status === 'inactive' && indicateInactive) {\n text += ' (' + tc('entity.campCollaboration.status.inactive') + ')'\n }\n\n return text\n}\n","import campCollaborationDisplayName from './campCollaborationDisplayName.js'\n\n/**\n * Local filtering of dayResponsibles by day\n * (avoids separate network request for each day)\n */\nconst filterDayResponsiblesByDay = (day) => {\n if (!day) return []\n\n return day\n .period()\n .dayResponsibles()\n .items.filter((dayResponsible) => dayResponsible.day()._meta.self === day._meta.self)\n}\n\nconst dayResponsiblesCommaSeparated = (day, tc) => {\n if (!day) return ''\n\n return filterDayResponsiblesByDay(day)\n .map((dayResponsible) =>\n campCollaborationDisplayName(dayResponsible.campCollaboration(), tc)\n )\n .join(', ')\n}\n\nexport { filterDayResponsiblesByDay, dayResponsiblesCommaSeparated }\n","\n \n \n \n {{ dayResponsibles }} \n \n \n \n\n\n.picasso-day-header-text {\n font-size: 8pt;\n font-weight: bold;\n margin: 0 auto 2pt;\n}\n.picasso-day-responsibles {\n font-size: 8pt;\n margin: 3pt auto 0;\n line-height: 1.3;\n}\n.picasso-day-responsibles-text {\n padding-bottom: 5pt;\n}\n \n","\n \n \n \n {{ time }} \n \n \n \n \n\n\n.picasso-time-column-container {\n /*\n Wrapping the time column in this absolutely positioned View is necessary, because otherwise the text\n in the time column breaks layouting of the texts inside the schedule entries.\n */\n position: absolute;\n top: -6;\n bottom: 6;\n left: 0;\n right: 0;\n}\n.picasso-time-column-row {\n padding-horizontal: 2pt;\n /* this should match the height of the borders on the day grid rows. 0 means no borders */\n flex-basis: 0;\n}\n \n","import Color from 'colorjs.io'\n\n/**\n * @param color {string} CSS compatible string color\n * @returns {string} colorblack or white depending on input color\n */\nfunction contrastColor(color) {\n const input = new Color(color)\n const black = new Color('#000')\n const white = new Color('#fff')\n const blackContrast = Math.abs(input.contrast(black, 'APCA'))\n const whiteContrast = Math.abs(input.contrast(white, 'APCA'))\n return blackContrast > whiteContrast\n ? black.toString({ format: 'hex' })\n : white.toString({ format: 'hex' })\n}\n\n/**\n * @param id {string} generated id\n * @param inactive {boolean} status\n * @returns {string} hsl color\n */\nfunction idToColor(id, inactive = false) {\n if (!id) {\n return new Color('HSL', [0, 0, 30]).to('srgb').toString({ format: 'hex' })\n }\n return new Color('HSL', [parseInt(id, 16) % 360 || 0, inactive ? 0 : 100, 30])\n .to('srgb')\n .toString({ format: 'hex' })\n}\n\n/**\n * @returns {string}\n */\nfunction defaultColor() {\n return new Color('HSL', [0, 0, 10]).toString({\n format: 'hex',\n })\n}\n\n/**\n * @returns {string} color for a user based on their id\n */\nfunction userColor(user, inactive = user._meta?.loading) {\n if (user.color && !inactive) {\n return user.color\n }\n return idToColor(user.id, inactive)\n}\n\n/**\n * @returns {string} color for a camp collaboration based on its user id and status\n */\nfunction campCollaborationColor(campCollaboration) {\n if (!campCollaboration) {\n return idToColor('', true)\n }\n\n const inactive =\n campCollaboration._meta?.loading || campCollaboration.status === 'inactive'\n\n if (campCollaboration?.color && !inactive) {\n return campCollaboration.color\n }\n\n if (typeof campCollaboration.user === 'function') {\n return userColor(\n campCollaboration.user(),\n inactive || campCollaboration.user()._meta?.loading\n )\n } else {\n return idToColor(campCollaboration.id, inactive)\n }\n}\n\nexport { contrastColor, defaultColor, userColor, campCollaborationColor, idToColor }\n","/**\n * Returns a display name for a user\n */\nexport default function (user) {\n return user.displayName || ''\n}\n","import runes from 'runes'\n\n/**\n * Returns two characters to display for a display name\n */\nexport default function (displayName) {\n if (!displayName) return ''\n\n let items = displayName.split(' ', 2)\n if (items.length === 1) {\n items = items.shift().split(/[,._-]/, 2)\n }\n if (items.length === 1) {\n return runes.substr(displayName, 0, 2).toUpperCase()\n } else {\n return (\n runes.substr(items[0], 0, 1).toUpperCase() +\n runes.substr(items[1], 0, 1).toUpperCase()\n )\n }\n}\n","import userDisplayName from './userDisplayName.js'\nimport initials from './initials.js'\n\n/**\n * Returns two characters to display for a camp collaboration based on its user\n */\nexport default function (campCollaboration) {\n if (!campCollaboration) {\n return ''\n }\n\n if (campCollaboration?.abbreviation) {\n return campCollaboration.abbreviation\n }\n\n if (typeof campCollaboration.user === 'function') {\n if (campCollaboration.user().abbreviation) {\n return campCollaboration.user().abbreviation\n }\n return initials(userDisplayName(campCollaboration.user()))\n }\n\n return initials(campCollaboration.inviteEmail || '')\n}\n","\n \n \n \n {{ initialsFor(activityResponsible) }}\n \n \n \n \n {{ responsible\n }}, \n \n \n\n\n.responsibles-avatars {\n display: flex;\n flex-direction: row;\n align-items: flex-end;\n}\n.responsibles-avatar {\n border-radius: 6pt;\n width: 12pt;\n height: 12pt;\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n.responsibles-avatar-overlap {\n margin-right: -2pt;\n}\n.responsibles-initials {\n font-size: 6pt;\n text-align: center;\n line-height: 1.2;\n}\n \n","import Color from 'colorjs.io'\n\n/**\n * @param color {string} CSS compatible string color\n * @returns {string} colorblack or white depending on input color\n */\nfunction contrastColor(color) {\n const input = new Color(color)\n const black = new Color('#000')\n const white = new Color('#fff')\n const blackContrast = Math.abs(input.contrast(black, 'APCA'))\n const whiteContrast = Math.abs(input.contrast(white, 'APCA'))\n return blackContrast > whiteContrast\n ? black.toString({ format: 'hex' })\n : white.toString({ format: 'hex' })\n}\n\n/**\n * @param id {string} generated id\n * @param inactive {boolean} status\n * @returns {string} hsl color\n */\nfunction idToColor(id, inactive = false) {\n if (!id) {\n return new Color('HSL', [0, 0, 30]).to('srgb').toString({ format: 'hex' })\n }\n return new Color('HSL', [parseInt(id, 16) % 360 || 0, inactive ? 0 : 100, 30])\n .to('srgb')\n .toString({ format: 'hex' })\n}\n\n/**\n * @returns {string}\n */\nfunction defaultColor() {\n return new Color('HSL', [0, 0, 10]).toString({\n format: 'hex',\n })\n}\n\n/**\n * @returns {string} color for a user based on their id\n */\nfunction userColor(user, inactive = user._meta?.loading) {\n if (user.color && !inactive) {\n return user.color\n }\n return idToColor(user.id, inactive)\n}\n\n/**\n * @returns {string} color for a camp collaboration based on its user id and status\n */\nfunction campCollaborationColor(campCollaboration) {\n if (!campCollaboration) {\n return idToColor('', true)\n }\n\n const inactive =\n campCollaboration._meta?.loading || campCollaboration.status === 'inactive'\n\n if (campCollaboration?.color && !inactive) {\n return campCollaboration.color\n }\n\n if (typeof campCollaboration.user === 'function') {\n return userColor(\n campCollaboration.user(),\n inactive || campCollaboration.user()._meta?.loading\n )\n } else {\n return idToColor(campCollaboration.id, inactive)\n }\n}\n\nexport { contrastColor, defaultColor, userColor, campCollaborationColor, idToColor }\n","\n \n \n \n \n {{ category }} {{ scheduleEntry.number }} {{ title }}\n \n \n \n \n \n \n \n \n \n \n\n\n.picasso-schedule-entry-link {\n text-decoration: none;\n color: black;\n}\n.picasso-schedule-entry {\n position: absolute;\n padding: 0 4pt;\n flex-direction: column;\n justify-content: flex-start;\n}\n.picasso-schedule-entry-spacer {\n height: 0;\n max-height: 4pt;\n flex-grow: 1;\n}\n.picasso-schedule-entry-title {\n height: 16pt;\n line-height: 1;\n flex-grow: 1;\n}\n.picasso-schedule-entry-responsibles-container {\n position: absolute;\n top: 0;\n bottom: 0;\n right: 0;\n left: 0;\n flex-direction: column;\n align-items: flex-end;\n justify-content: flex-end;\n padding: 0 4pt;\n}\n \n","// This file contains an algorithm for automatically arranging schedule entries in terms\n// of horizontal placement, such that they do not overlap with each other.\n// Taken and adapted from Vuetify 2's v-calendar event overlap logic:\n// https://github.com/vuetifyjs/vuetify/blob/v2-stable/packages/vuetify/src/components/VCalendar/modes/column.ts\n\nimport dayjs from './dayjs.js'\n\nconst FULL_WIDTH = 100\n\nfunction getVisuals(events) {\n const visuals = events.map((event) => ({\n id: event.id,\n columnCount: 0,\n column: 0,\n left: 0,\n width: 100,\n startTimestamp: dayjs.utc(event.start).unix(),\n endTimestamp: dayjs.utc(event.end).unix(),\n }))\n\n visuals.sort((a, b) => {\n return a.startTimestamp - b.startTimestamp || b.endTimestamp - a.endTimestamp\n })\n\n return visuals\n}\n\nfunction hasOverlap(s0, e0, s1, e1) {\n return !(s0 >= e1 || e0 <= s1)\n}\n\nfunction setColumnCount(groups) {\n groups.forEach((group) => {\n group.visuals.forEach((groupVisual) => {\n groupVisual.columnCount = groups.length\n groupVisual.left = (groupVisual.column * FULL_WIDTH) / groupVisual.columnCount\n groupVisual.width = FULL_WIDTH / groupVisual.columnCount\n })\n })\n}\n\nfunction getOpenGroup(groups, eventStart, eventEnd) {\n for (let i = 0; i < groups.length; i++) {\n const group = groups[i]\n let intersected = false\n\n if (hasOverlap(eventStart, eventEnd, group.start, group.end)) {\n for (let k = 0; k < group.visuals.length; k++) {\n const groupVisual = group.visuals[k]\n const groupStart = groupVisual.startTimestamp\n const groupEnd = groupVisual.endTimestamp\n\n if (hasOverlap(eventStart, eventEnd, groupStart, groupEnd)) {\n intersected = true\n break\n }\n }\n }\n\n if (!intersected) {\n return i\n }\n }\n\n return -1\n}\n\n/**\n * Calculates left and width for each schedule entry, such that no two schedule entries overlap visually.\n * For this, schedule entries are sorted by ascending start ascendingly (and descending end time for ties),\n * and any sets of overlapping schedule entries are divided into groups. The groups can then be displayed\n * besides each other, because the groups are chosen such that no two schedule entries in the same group overlap.\n * @param scheduleEntries list of schedule entries to arrange\n * @returns list of objects with information about the spatial arrangement\n */\nexport function arrange(scheduleEntries) {\n let groups = []\n let min = -1\n let max = -1\n const visuals = getVisuals(scheduleEntries)\n\n visuals.forEach((visual) => {\n const eventStart = visual.startTimestamp\n const eventEnd = visual.endTimestamp\n\n if (groups.length > 0 && !hasOverlap(eventStart, eventEnd, min, max)) {\n setColumnCount(groups)\n groups = []\n min = max = -1\n }\n\n let targetGroup = getOpenGroup(groups, eventStart, eventEnd)\n\n if (targetGroup === -1) {\n targetGroup = groups.length\n\n groups.push({ start: eventStart, end: eventEnd, visuals: [] })\n }\n\n const target = groups[targetGroup]\n target.visuals.push(visual)\n target.start = Math.min(target.start, eventStart)\n target.end = Math.max(target.end, eventEnd)\n\n visual.column = targetGroup\n\n if (min === -1) {\n min = eventStart\n max = eventEnd\n } else {\n min = Math.min(min, eventStart)\n max = Math.max(max, eventEnd)\n }\n })\n\n setColumnCount(groups)\n\n return visuals\n}\n","import minBy from 'lodash-es/minBy.js'\nimport maxBy from 'lodash-es/maxBy.js'\nimport sortBy from 'lodash-es/sortBy.js'\nimport keyBy from 'lodash-es/keyBy.js'\nimport dayjs from './dayjs.js'\nimport { arrange } from './scheduleEntryLayout.js'\n\n/**\n * @typedef {import('./dayjs.js').dayjs} Dayjs\n */\n\n/**\n * Splits a set of days into pages, such that all pages contain a similar number of days.\n *\n * @param days {array} set of days to split into pages\n * @param maxDaysPerPage {number} maximum number of days to put on one page\n * @returns {array} list of pages, each containing a list of the days on the page\n */\nexport function splitDaysIntoPages(days, maxDaysPerPage) {\n if (!maxDaysPerPage) return []\n const numberOfDays = days.length\n const numberOfPages = Math.ceil(numberOfDays / maxDaysPerPage)\n const daysPerPage = Math.floor(numberOfDays / numberOfPages)\n const numLargerPages = numberOfDays % numberOfPages\n let nextUnassignedDayIndex = 0\n\n return [...Array(numberOfPages).keys()].map((i) => {\n const isLargerPage = i < numLargerPages\n const numDaysOnCurrentPage = daysPerPage + (isLargerPage ? 1 : 0)\n const firstDayIndex = nextUnassignedDayIndex\n nextUnassignedDayIndex = firstDayIndex + numDaysOnCurrentPage\n\n return days.filter((day, index) => {\n return index >= firstDayIndex && index < nextUnassignedDayIndex\n })\n })\n}\n\n/**\n * Finds the largest consecutive time period during the night, in which no schedule entries start or end.\n * This time period can be treated as the common \"bedtime\" in the camp, during which\n * the people in the camp are not active. This time period can be safely hidden on the picasso.\n *\n * @param scheduleEntries set of schedule entries to consider\n * @param dayjs a dayjs helper object, needed to do time calculations\n * @param firstDayStart dayjs object describing the start of the first day displayed. Is used to make sure that schedule\n * entries starting on this day may not be assigned to the preceding day, because that would mean they would become\n * invisible on the picasso\n * @param lastDayEnd dayjs object describing the end of the last day displayed. Is used to make sure that schedule\n * entries ending on this day may not be assigned to the following day, because that would mean they would become\n * invisible on the picasso\n * @param timeBucketSize size of the time buckets into which the schedule entry boundaries are quantized, in hours\n * @returns {{bedtime: number, getUpTime: number}}\n */\nexport function calculateBedtime(\n scheduleEntries,\n dayjs,\n firstDayStart,\n lastDayEnd,\n timeBucketSize = 1\n) {\n const scheduleEntryBounds = getScheduleEntryBounds(\n scheduleEntries,\n dayjs,\n firstDayStart.unix(),\n lastDayEnd.unix()\n )\n if (!scheduleEntryBounds.length) return { bedtime: 24, getUpTime: 0 }\n\n const gaps = scheduleEntryBounds.reduce((gaps, current, index) => {\n if (index === 0) return gaps\n const previous = scheduleEntryBounds[index - 1]\n const duration = current.hours - previous.hours\n if (duration === 0) return gaps\n gaps.push({\n start: previous.hours,\n end: current.hours,\n duration,\n })\n return gaps\n }, [])\n\n // The first and last day on our picasso impose some constraints on the range of bedtimes we can choose.\n const { earliestBedtime, latestGetUpTime } = bedtimeConstraintsFromFirstAndLastDay(\n scheduleEntryBounds,\n firstDayStart,\n lastDayEnd,\n dayjs,\n timeBucketSize\n )\n\n const largestBedtimeGap = maxBy(\n gaps.filter((gap) => {\n // Prevent bedtimes which would hide some schedule entry on the first or last day\n if (gap.start < earliestBedtime || gap.end > latestGetUpTime) return false\n // Prevent bedtimes which are not during the night\n if (gap.start > 30 || gap.end < 24) return false\n return true\n }),\n (gap) => gap.duration\n )\n\n return {\n bedtime: optimalBedtime(largestBedtimeGap, scheduleEntryBounds, timeBucketSize),\n getUpTime:\n optimalGetUpTime(largestBedtimeGap, scheduleEntryBounds, timeBucketSize) - 24,\n }\n}\n\nfunction getScheduleEntryBounds(\n scheduleEntries,\n dayjs,\n firstDayStartTimestamp,\n lastDayEndTimestamp\n) {\n const bounds = scheduleEntries\n .flatMap((scheduleEntry) => {\n const start = dayjs.utc(scheduleEntry.start)\n const end = dayjs.utc(scheduleEntry.end)\n const startHours = start.hour() + start.minute() / 60\n const endHours = end.hour() + end.minute() / 60\n const duration = end.diff(start, 'minute') / 60\n return [\n { hours: startHours, time: start, type: 'start', duration },\n { hours: endHours, time: end, type: 'end', duration },\n ]\n })\n .filter(\n (bound) =>\n bound.time.unix() >= firstDayStartTimestamp &&\n bound.time.unix() <= lastDayEndTimestamp\n )\n // Add a copy of all bounds 24 hours later, to simplify working with the circular characteristics of daytimes\n const shifted = bounds.map((bound) => ({\n ...bound,\n hours: bound.hours + 24,\n time: bound.time.add(24, 'hours'),\n }))\n return sortBy([...bounds, ...shifted], (bound) => bound.hours)\n}\n\nfunction bedtimeConstraintsFromFirstAndLastDay(\n scheduleEntryBounds,\n firstDayStart,\n lastDayEnd\n) {\n // The start of the very first schedule entry on the first day (if any) must always be displayed on the first day.\n // We must make sure that our calculated \"get up time\" lies before this, so we do not accidentally hide a\n // schedule entry.\n const latestGetUpTime = earliestScheduleEntryBoundOnFirstDay(\n scheduleEntryBounds,\n firstDayStart\n )\n\n // Similarly, the end of the very last schedule entry end must always be displayed on the last day.\n // So we must make sure that our calculated \"go to bed time\" lies after this.\n const earliestBedtime = latestScheduleEntryBoundOnLastDay(\n scheduleEntryBounds,\n lastDayEnd.subtract(1, 'second')\n )\n\n return {\n earliestBedtime: earliestBedtime === undefined ? 0 : earliestBedtime,\n latestGetUpTime: latestGetUpTime === undefined ? 48 : latestGetUpTime + 24,\n }\n}\n\nfunction earliestScheduleEntryBoundOnFirstDay(scheduleEntryBounds, firstDayStart) {\n const earliestBound = minBy(scheduleEntryBounds, (bound) => bound.time.unix())\n if (\n earliestBound.hours < 24 &&\n earliestBound.time.diff(firstDayStart, 'minute') / 60 < 24\n ) {\n return earliestBound.hours\n }\n return undefined\n}\n\nfunction latestScheduleEntryBoundOnLastDay(scheduleEntryBounds, lastDayEnd) {\n const latestBound = maxBy(scheduleEntryBounds, (bound) => bound.time.unix())\n if (latestBound.hours < 24 && lastDayEnd.diff(latestBound.time, 'minute') / 60 < 24) {\n return latestBound.hours\n }\n return undefined\n}\n\nfunction optimalBedtime(gap, scheduleEntryBounds, timeBucketSize) {\n const bedtime = Math.ceil(gap.start / timeBucketSize) * timeBucketSize\n if (\n scheduleEntryBounds.some(\n (bound) =>\n bound.type === 'start' &&\n bound.hours <= bedtime &&\n bound.hours > bedtime - timeBucketSize / 2 &&\n bound.duration > bedtime - bound.hours\n )\n ) {\n // There exists a schedule entry which starts at the bedtime or less than half a time bucket before it.\n // Move the bedtime later, so that this schedule entry is still clearly visible.\n return bedtime + timeBucketSize\n }\n // There is already a large enough margin, or there are no schedule entries starting around the bedtime.\n return bedtime\n}\n\nfunction optimalGetUpTime(gap, scheduleEntryBounds, timeBucketSize) {\n const getUpTime = Math.floor(gap.end / timeBucketSize) * timeBucketSize\n if (\n scheduleEntryBounds.some(\n (bound) =>\n bound.type === 'end' &&\n bound.hours >= getUpTime &&\n bound.hours < getUpTime + timeBucketSize / 2 &&\n bound.duration > bound.hours - getUpTime\n )\n ) {\n // There exists a schedule entry which ends at the getUpTime or less than half a time bucket after it.\n // Move the getUpTime later, so that this schedule entry is still clearly visible.\n return getUpTime - timeBucketSize\n }\n // There is already a large enough margin, or there are no schedule entries ending around the getUpTime.\n return getUpTime\n}\n\n/**\n * Generates an array of time row descriptions, used for labeling the vertical axis of the picasso.\n * Format of each array element: [hour, weight] where weight determines how tall the time row is rendered.\n *\n * @typedef {*[[hour: number, weight: number]]} TimeWeights\n * @returns TimeWeights\n */\nexport function times(getUpTime, bedTime, timeStep) {\n const times = [[getUpTime - timeStep / 2, 0.5]]\n for (let i = 0; getUpTime + i * timeStep < bedTime; i++) {\n // TODO The weight could also be generated depending on the schedule entries present in the camp:\n // e.g. give less weight to hours that contain no schedule entries.\n const weight = 1\n times.push([getUpTime + i * timeStep, weight])\n }\n times.push([bedTime, 0.5])\n // this last hour is only needed for defining the length of the day. The weight should be 0.\n times.push([bedTime + timeStep / 2, 0])\n\n return times\n}\n\n/**\n * Returns the total sum of weights in the times array (with times format as generated by times() function)\n */\nexport function timesWeightsSum(times) {\n return times.reduce((sum, [_, weight]) => sum + weight, 0)\n}\n\n/**\n * Calculates the relative positioning in percentage of \"milliseconds\" within the times array\n */\nexport function positionPercentage(milliseconds, times) {\n const hours = milliseconds / (3600.0 * 1000)\n let matchingTimeIndex = times.findIndex(([time, _]) => time > hours) - 1\n matchingTimeIndex = Math.min(\n Math.max(matchingTimeIndex === -2 ? times.length : matchingTimeIndex, 0),\n times.length - 1\n )\n const remainder =\n times[matchingTimeIndex][1] !== 0\n ? (hours - times[matchingTimeIndex][0]) / times[matchingTimeIndex][1]\n : 0 // avoid division by zero, in case the schedule entry ends on a later day\n const positionWeightsSum =\n timesWeightsSum(times.slice(0, matchingTimeIndex)) +\n remainder * times[Math.min(matchingTimeIndex, times.length)][1]\n const totalWeightsSum = timesWeightsSum(times)\n if (totalWeightsSum === 0) {\n return 0\n }\n const result = (positionWeightsSum * 100.0) / totalWeightsSum\n return Math.max(0, Math.min(100, result))\n}\n\nexport function filterScheduleEntriesByDay(scheduleEntries, day, times) {\n return scheduleEntries.filter((scheduleEntry) => {\n return (\n dayjs.utc(scheduleEntry.start).isBefore(dayEnd(day, times)) &&\n dayjs.utc(scheduleEntry.end).isAfter(dayStart(day, times))\n )\n })\n}\n\n/**\n * @param day a day object of the api\n * @param offset {number} the offset hour of the day\n * @returns {Dayjs}\n */\nfunction dayOffset(day, offset) {\n return dayjs.utc(day.start).add(offset, 'hour')\n}\n\n/**\n * Calculates the day start dayjs object according to times\n *\n * @param day a day object of the api\n * @param times {TimeWeights}\n * @returns {Dayjs}\n */\nexport function dayStart(day, times) {\n const dayStart = times[0][0]\n return dayOffset(day, dayStart)\n}\n\n/**\n * Calculates the day end dayjs object according to times\n *\n * @param day a day object of the api\n * @param times {TimeWeights}\n * @returns {Dayjs}\n */\nexport function dayEnd(day, times) {\n const dayEnd = times[times.length - 1][0]\n return dayOffset(day, dayEnd)\n}\n\nfunction leftAndWith(scheduleEntries) {\n return keyBy(arrange(scheduleEntries), 'id')\n}\n\n/**\n * Calculates the positions styles (in percentages) for all scheduleEntries\n */\nexport function positionStyles(scheduleEntries, day, times) {\n const leftAndWidth = leftAndWith(scheduleEntries)\n\n return keyBy(\n scheduleEntries.map((scheduleEntry) => {\n const left = leftAndWidth[scheduleEntry.id]?.left || 0\n const width = leftAndWidth[scheduleEntry.id]?.width || 0\n const top = positionPercentage(\n dayjs.utc(scheduleEntry.start).valueOf() - dayjs.utc(day.start).valueOf(),\n times\n )\n const bottom =\n 100 -\n positionPercentage(\n dayjs.utc(scheduleEntry.end).valueOf() - dayjs.utc(day.start).valueOf(),\n times\n )\n return {\n id: scheduleEntry.id,\n top: top + '%',\n bottom: bottom + '%',\n left: left + '%',\n right: 100 - width - left + '%',\n percentageHeight: 100 - bottom - top,\n }\n }),\n 'id'\n )\n}\n","\n \n \n \n \n \n \n \n \n \n\n\n.picasso-day-column {\n flex-basis: 0;\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n position: relative;\n}\n.picasso-day-column-grid {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n position: relative;\n}\n.picasso-day-column-grid-row {\n display: flex;\n flex-basis: 0;\n}\n.picasso-day-column-grid-row-grey {\n background-color: lightgrey;\n}\n.picasso-day-column-schedule-entry-container {\n margin: 0 2pt;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n}\n \n","\n \n {{ category.short }}\n \n \n\n\n.category-label {\n padding: 2pt 8pt;\n border-radius: 18pt;\n align-self: center;\n}\n \n","\n \n \n \n {{ category.name }} \n \n \n \n\n\n.picasso-categories {\n font-size: 9pt;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n margin: 2pt 0 0;\n}\n.picasso-category {\n flex-direction: row;\n align-items: center;\n gap: 2pt;\n margin-right: 6pt;\n margin-bottom: 3pt;\n}\n \n","/**\n * Returns the legal name for a user\n */\nexport default function (user) {\n if (!user || !user.profile() || user.profile()._meta.loading) return ''\n return user.profile().legalName || ''\n}\n","import userLegalName from './userLegalName.js'\n\n/**\n * Returns a legal name for a camp collaboration based on its status\n */\nexport default function (campCollaboration) {\n if (!campCollaboration) {\n return ''\n }\n\n return typeof campCollaboration.user === 'function'\n ? userLegalName(campCollaboration.user())\n : ''\n}\n","\n \n \n\n\n.picasso-footer {\n width: 100%;\n font-size: 9pt;\n display: flex;\n flex-direction: row;\n margin-top: 6pt;\n border: 1pt solid grey;\n padding: 0 0 3pt;\n justify-content: space-between;\n}\n.picasso-footer-column {\n max-width: 33%;\n align-items: flex-start;\n justify-content: flex-start;\n gap: 6pt;\n line-height: 0.5;\n padding: 2pt 3pt 3pt;\n}\n.picasso-footer-field {\n margin-bottom: 6pt;\n}\n \n","\n \n \n \n \n {{ $t('print.picasso.title', { period: period.description }) }}\n \n {{ period.camp().organizer }} \n \n \n \n \n \n \n \n \n \n \n \n\n\n.picasso-title-container {\n display: flex;\n flex-direction: row;\n margin-top: -4pt;\n margin-bottom: 4pt;\n align-items: center;\n gap: 8pt;\n}\n.picasso-title {\n flex-grow: 1;\n font-weight: bold;\n font-size: 14pt;\n}\n.picasso-organizer {\n font-size: 10pt;\n}\n.picasso-ys-logo {\n align-self: flex-end;\n margin-top: 3pt;\n size: 20;\n}\n.picasso-calendar-header-container {\n border-left: 1pt solid white;\n border-right: 1pt solid white;\n flex-grow: 1;\n display: flex;\n flex-direction: row;\n line-height: 0.8;\n}\n.picasso-calendar-container {\n border: 1pt solid grey;\n flex-grow: 1;\n display: flex;\n flex-direction: row;\n}\n.picasso-day-header {\n border-right: 1pt solid white;\n flex-basis: 0;\n flex-grow: 1;\n overflow: hidden;\n padding: 4pt 0 5pt;\n display: flex;\n flex-direction: column;\n}\n.picasso-day-header-left-border {\n border-left: 1pt solid white;\n}\n.picasso-time-column {\n flex-grow: 0;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n}\n.picasso-time-column-text {\n font-size: 8pt;\n}\n.picasso-day-column-left-border {\n border-left: 1pt solid grey;\n}\n \n","\n \n \n\n\n \n","\n \n \n\n\n \n","import dayjs from './dayjs.js'\n\nfunction dateShort(dateTimeString, tc) {\n return dayjs.utc(dateTimeString).format(tc('global.datetime.dateShort'))\n}\n\nfunction dateLong(dateTimeString, tc) {\n return dayjs.utc(dateTimeString).format(tc('global.datetime.dateLong'))\n}\n\nfunction hourShort(dateTimeString, tc) {\n return dayjs.utc(dateTimeString).format(tc('global.datetime.hourShort'))\n}\n\nfunction hourLong(dateTimeString, tc) {\n return dayjs.utc(dateTimeString).format(tc('global.datetime.hourLong'))\n}\n\nfunction timeDurationShort(start, end, tc) {\n const startTime = dayjs.utc(start)\n const endTime = dayjs.utc(end)\n const duration = dayjs.duration(endTime.diff(startTime))\n\n return tc(\n duration.asDays() >= 1\n ? duration.hours() === 0\n ? duration.minutes() === 0\n ? 'global.datetime.duration.daysOnly'\n : 'global.datetime.duration.daysAndMinutes'\n : duration.minutes() === 0\n ? 'global.datetime.duration.daysAndHours'\n : 'global.datetime.duration.daysAndHoursAndMinutes'\n : duration.asMinutes() < 60\n ? 'global.datetime.duration.minutesOnly'\n : duration.minutes() === 0\n ? 'global.datetime.duration.hoursOnly'\n : 'global.datetime.duration.hoursAndMinutes',\n 0,\n {\n days: Math.floor(duration.asDays()),\n hours: duration.hours(),\n minutes: duration.minutes(),\n }\n )\n}\n\n// short format of dateTime range\n// doesn't show any date\nfunction rangeTime(start, end, tc) {\n return hourShort(start, tc) + ' - ' + hourShort(end, tc)\n}\n\n// short format of dateTime range\n// doesn't repeat end date if on the same day\nfunction rangeShort(start, end, tc) {\n let result = ''\n\n result += dateShort(start, tc)\n result += ' '\n result += hourShort(start, tc)\n\n result += ' - '\n\n if (dateShort(start, tc) !== dateShort(end, tc)) {\n result += dateShort(end, tc)\n result += ' '\n }\n\n result += hourShort(end, tc)\n\n return result\n}\n\n// long end part of dateTime range format\n// doesn't repeat end date if on the same day\nfunction rangeLongEnd(start, end, tc) {\n let result = ''\n\n result += hourLong(start, tc)\n\n result += ' - '\n\n if (dateShort(start, tc) !== dateShort(end, tc)) {\n result += dateShort(end, tc)\n result += ' '\n }\n\n result += hourLong(end, tc)\n\n return result\n}\n\n// format of date range\nfunction dateRange(start, end, tc) {\n if (dateLong(start, tc) === dateLong(end, tc)) {\n return dateLong(start, tc)\n }\n return `${dateShort(start, tc)} - ${dateLong(end, tc)}`\n}\n\nexport {\n dateShort,\n dateLong,\n timeDurationShort,\n hourShort,\n hourLong,\n dateRange,\n rangeTime,\n rangeShort,\n rangeLongEnd,\n}\n","/**\n * This file automatically generated from `pre-publish.js`.\n * Do not manually edit.\n */\n\nmodule.exports = {\n \"area\": true,\n \"base\": true,\n \"br\": true,\n \"col\": true,\n \"embed\": true,\n \"hr\": true,\n \"img\": true,\n \"input\": true,\n \"link\": true,\n \"meta\": true,\n \"param\": true,\n \"source\": true,\n \"track\": true,\n \"wbr\": true\n};\n","import e from\"void-elements\";var t=/\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\".*?\"|'.*?')/g;function n(n){var r={type:\"tag\",name:\"\",voidElement:!1,attrs:{},children:[]},i=n.match(/<\\/?([^\\s]+?)[/\\s>]/);if(i&&(r.name=i[1],(e[i[1]]||\"/\"===n.charAt(n.length-2))&&(r.voidElement=!0),r.name.startsWith(\"!--\"))){var s=n.indexOf(\"--\\x3e\");return{type:\"comment\",comment:-1!==s?n.slice(4,s):\"\"}}for(var a=new RegExp(t),c=null;null!==(c=a.exec(n));)if(c[0].trim())if(c[1]){var o=c[1].trim(),l=[o,\"\"];o.indexOf(\"=\")>-1&&(l=o.split(\"=\")),r.attrs[l[0]]=l[1],a.lastIndex--}else c[2]&&(r.attrs[c[2]]=c[3].trim().substring(1,c[3].length-1));return r}var r=/<[a-zA-Z0-9\\-\\!\\/](?:\"[^\"]*\"|'[^']*'|[^'\">])*>/g,i=/^\\s*$/,s=Object.create(null);function a(e,t){switch(t.type){case\"text\":return e+t.content;case\"tag\":return e+=\"<\"+t.name+(t.attrs?function(e){var t=[];for(var n in e)t.push(n+'=\"'+e[n]+'\"');return t.length?\" \"+t.join(\" \"):\"\"}(t.attrs):\"\")+(t.voidElement?\"/>\":\">\"),t.voidElement?e:e+t.children.reduce(a,\"\")+\"\"+t.name+\">\";case\"comment\":return e+\"\\x3c!--\"+t.comment+\"--\\x3e\"}}var c={parse:function(e,t){t||(t={}),t.components||(t.components=s);var a,c=[],o=[],l=-1,m=!1;if(0!==e.indexOf(\"<\")){var u=e.indexOf(\"<\");c.push({type:\"text\",content:-1===u?e:e.substring(0,u)})}return e.replace(r,function(r,s){if(m){if(r!==\"\"+a.name+\">\")return;m=!1}var u,f=\"/\"!==r.charAt(1),h=r.startsWith(\"\\x3c!--\"),p=s+r.length,d=e.charAt(p);if(h){var v=n(r);return l<0?(c.push(v),c):((u=o[l]).children.push(v),c)}if(f&&(l++,\"tag\"===(a=n(r)).type&&t.components[a.name]&&(a.type=\"component\",m=!0),a.voidElement||m||!d||\"<\"===d||a.children.push({type:\"text\",content:e.slice(p,e.indexOf(\"<\",p))}),0===l&&c.push(a),(u=o[l-1])&&u.children.push(a),o[l]=a),(!f||a.voidElement)&&(l>-1&&(a.voidElement||a.name===r.slice(2,-1))&&(l--,a=-1===l?c:o[l]),!m&&\"<\"!==d&&d)){u=-1===l?c:o[l].children;var x=e.indexOf(\"<\",p),g=e.slice(p,-1===x?void 0:x);i.test(g)&&(g=\" \"),(x>-1&&l+u.length>=0||\" \"!==g)&&u.push({type:\"text\",content:g})}}),c},stringify:function(e){return e.reduce(function(e,t){return e+a(\"\",t)},\"\")}};export default c;\n//# sourceMappingURL=html-parse-stringify.module.js.map\n","var __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\n// This file is autogenerated by tools/process-named-references.ts\nvar pairDivider = \"~\";\nvar blockDivider = \"~~\";\nfunction generateNamedReferences(input, prev) {\n var entities = {};\n var characters = {};\n var blocks = input.split(blockDivider);\n var isOptionalBlock = false;\n for (var i = 0; blocks.length > i; i++) {\n var entries = blocks[i].split(pairDivider);\n for (var j = 0; j < entries.length; j += 2) {\n var entity = entries[j];\n var character = entries[j + 1];\n var fullEntity = '&' + entity + ';';\n entities[fullEntity] = character;\n if (isOptionalBlock) {\n entities['&' + entity] = character;\n }\n characters[character] = fullEntity;\n }\n isOptionalBlock = true;\n }\n return prev ?\n { entities: __assign(__assign({}, entities), prev.entities), characters: __assign(__assign({}, characters), prev.characters) } :\n { entities: entities, characters: characters };\n}\nexport var bodyRegExps = {\n xml: /&(?:#\\d+|#[xX][\\da-fA-F]+|[0-9a-zA-Z]+);?/g,\n html4: /∉|&(?:nbsp|iexcl|cent|pound|curren|yen|brvbar|sect|uml|copy|ordf|laquo|not|shy|reg|macr|deg|plusmn|sup2|sup3|acute|micro|para|middot|cedil|sup1|ordm|raquo|frac14|frac12|frac34|iquest|Agrave|Aacute|Acirc|Atilde|Auml|Aring|AElig|Ccedil|Egrave|Eacute|Ecirc|Euml|Igrave|Iacute|Icirc|Iuml|ETH|Ntilde|Ograve|Oacute|Ocirc|Otilde|Ouml|times|Oslash|Ugrave|Uacute|Ucirc|Uuml|Yacute|THORN|szlig|agrave|aacute|acirc|atilde|auml|aring|aelig|ccedil|egrave|eacute|ecirc|euml|igrave|iacute|icirc|iuml|eth|ntilde|ograve|oacute|ocirc|otilde|ouml|divide|oslash|ugrave|uacute|ucirc|uuml|yacute|thorn|yuml|quot|amp|lt|gt|#\\d+|#[xX][\\da-fA-F]+|[0-9a-zA-Z]+);?/g,\n html5: /·|℗|⋇|⪧|⩺|⋗|⦕|⩼|⪆|⥸|⋗|⋛|⪌|≷|≳|⪦|⩹|⋖|⋋|⋉|⥶|⩻|⦖|◃|⊴|◂|∉|⋹̸|⋵̸|∉|⋷|⋶|∌|∌|⋾|⋽|∥|⊠|⨱|⨰|&(?:AElig|AMP|Aacute|Acirc|Agrave|Aring|Atilde|Auml|COPY|Ccedil|ETH|Eacute|Ecirc|Egrave|Euml|GT|Iacute|Icirc|Igrave|Iuml|LT|Ntilde|Oacute|Ocirc|Ograve|Oslash|Otilde|Ouml|QUOT|REG|THORN|Uacute|Ucirc|Ugrave|Uuml|Yacute|aacute|acirc|acute|aelig|agrave|amp|aring|atilde|auml|brvbar|ccedil|cedil|cent|copy|curren|deg|divide|eacute|ecirc|egrave|eth|euml|frac12|frac14|frac34|gt|iacute|icirc|iexcl|igrave|iquest|iuml|laquo|lt|macr|micro|middot|nbsp|not|ntilde|oacute|ocirc|ograve|ordf|ordm|oslash|otilde|ouml|para|plusmn|pound|quot|raquo|reg|sect|shy|sup1|sup2|sup3|szlig|thorn|times|uacute|ucirc|ugrave|uml|uuml|yacute|yen|yuml|#\\d+|#[xX][\\da-fA-F]+|[0-9a-zA-Z]+);?/g\n};\nexport var namedReferences = {};\nnamedReferences['xml'] = generateNamedReferences(\"lt~<~gt~>~quot~\\\"~apos~'~amp~&\");\nnamedReferences['html4'] = generateNamedReferences(\"apos~'~OElig~Œ~oelig~œ~Scaron~Š~scaron~š~Yuml~Ÿ~circ~ˆ~tilde~˜~ensp~ ~emsp~ ~thinsp~ ~zwnj~~zwj~~lrm~~rlm~~ndash~–~mdash~—~lsquo~‘~rsquo~’~sbquo~‚~ldquo~“~rdquo~”~bdquo~„~dagger~†~Dagger~‡~permil~‰~lsaquo~‹~rsaquo~›~euro~€~fnof~ƒ~Alpha~Α~Beta~Β~Gamma~Γ~Delta~Δ~Epsilon~Ε~Zeta~Ζ~Eta~Η~Theta~Θ~Iota~Ι~Kappa~Κ~Lambda~Λ~Mu~Μ~Nu~Ν~Xi~Ξ~Omicron~Ο~Pi~Π~Rho~Ρ~Sigma~Σ~Tau~Τ~Upsilon~Υ~Phi~Φ~Chi~Χ~Psi~Ψ~Omega~Ω~alpha~α~beta~β~gamma~γ~delta~δ~epsilon~ε~zeta~ζ~eta~η~theta~θ~iota~ι~kappa~κ~lambda~λ~mu~μ~nu~ν~xi~ξ~omicron~ο~pi~π~rho~ρ~sigmaf~ς~sigma~σ~tau~τ~upsilon~υ~phi~φ~chi~χ~psi~ψ~omega~ω~thetasym~ϑ~upsih~ϒ~piv~ϖ~bull~•~hellip~…~prime~′~Prime~″~oline~‾~frasl~⁄~weierp~℘~image~ℑ~real~ℜ~trade~™~alefsym~ℵ~larr~←~uarr~↑~rarr~→~darr~↓~harr~↔~crarr~↵~lArr~⇐~uArr~⇑~rArr~⇒~dArr~⇓~hArr~⇔~forall~∀~part~∂~exist~∃~empty~∅~nabla~∇~isin~∈~notin~∉~ni~∋~prod~∏~sum~∑~minus~−~lowast~∗~radic~√~prop~∝~infin~∞~ang~∠~and~∧~or~∨~cap~∩~cup~∪~int~∫~there4~∴~sim~∼~cong~≅~asymp~≈~ne~≠~equiv~≡~le~≤~ge~≥~sub~⊂~sup~⊃~nsub~⊄~sube~⊆~supe~⊇~oplus~⊕~otimes~⊗~perp~⊥~sdot~⋅~lceil~⌈~rceil~⌉~lfloor~⌊~rfloor~⌋~lang~〈~rang~〉~loz~◊~spades~♠~clubs~♣~hearts~♥~diams~♦~~nbsp~ ~iexcl~¡~cent~¢~pound~£~curren~¤~yen~¥~brvbar~¦~sect~§~uml~¨~copy~©~ordf~ª~laquo~«~not~¬~shy~~reg~®~macr~¯~deg~°~plusmn~±~sup2~²~sup3~³~acute~´~micro~µ~para~¶~middot~·~cedil~¸~sup1~¹~ordm~º~raquo~»~frac14~¼~frac12~½~frac34~¾~iquest~¿~Agrave~À~Aacute~Á~Acirc~Â~Atilde~Ã~Auml~Ä~Aring~Å~AElig~Æ~Ccedil~Ç~Egrave~È~Eacute~É~Ecirc~Ê~Euml~Ë~Igrave~Ì~Iacute~Í~Icirc~Î~Iuml~Ï~ETH~Ð~Ntilde~Ñ~Ograve~Ò~Oacute~Ó~Ocirc~Ô~Otilde~Õ~Ouml~Ö~times~×~Oslash~Ø~Ugrave~Ù~Uacute~Ú~Ucirc~Û~Uuml~Ü~Yacute~Ý~THORN~Þ~szlig~ß~agrave~à~aacute~á~acirc~â~atilde~ã~auml~ä~aring~å~aelig~æ~ccedil~ç~egrave~è~eacute~é~ecirc~ê~euml~ë~igrave~ì~iacute~í~icirc~î~iuml~ï~eth~ð~ntilde~ñ~ograve~ò~oacute~ó~ocirc~ô~otilde~õ~ouml~ö~divide~÷~oslash~ø~ugrave~ù~uacute~ú~ucirc~û~uuml~ü~yacute~ý~thorn~þ~yuml~ÿ~quot~\\\"~amp~&~lt~<~gt~>\");\nnamedReferences['html5'] = generateNamedReferences(\"Abreve~Ă~Acy~А~Afr~𝔄~Amacr~Ā~And~⩓~Aogon~Ą~Aopf~𝔸~ApplyFunction~~Ascr~𝒜~Assign~≔~Backslash~∖~Barv~⫧~Barwed~⌆~Bcy~Б~Because~∵~Bernoullis~ℬ~Bfr~𝔅~Bopf~𝔹~Breve~˘~Bscr~ℬ~Bumpeq~≎~CHcy~Ч~Cacute~Ć~Cap~⋒~CapitalDifferentialD~ⅅ~Cayleys~ℭ~Ccaron~Č~Ccirc~Ĉ~Cconint~∰~Cdot~Ċ~Cedilla~¸~CenterDot~·~Cfr~ℭ~CircleDot~⊙~CircleMinus~⊖~CirclePlus~⊕~CircleTimes~⊗~ClockwiseContourIntegral~∲~CloseCurlyDoubleQuote~”~CloseCurlyQuote~’~Colon~∷~Colone~⩴~Congruent~≡~Conint~∯~ContourIntegral~∮~Copf~ℂ~Coproduct~∐~CounterClockwiseContourIntegral~∳~Cross~⨯~Cscr~𝒞~Cup~⋓~CupCap~≍~DD~ⅅ~DDotrahd~⤑~DJcy~Ђ~DScy~Ѕ~DZcy~Џ~Darr~↡~Dashv~⫤~Dcaron~Ď~Dcy~Д~Del~∇~Dfr~𝔇~DiacriticalAcute~´~DiacriticalDot~˙~DiacriticalDoubleAcute~˝~DiacriticalGrave~`~DiacriticalTilde~˜~Diamond~⋄~DifferentialD~ⅆ~Dopf~𝔻~Dot~¨~DotDot~⃜~DotEqual~≐~DoubleContourIntegral~∯~DoubleDot~¨~DoubleDownArrow~⇓~DoubleLeftArrow~⇐~DoubleLeftRightArrow~⇔~DoubleLeftTee~⫤~DoubleLongLeftArrow~⟸~DoubleLongLeftRightArrow~⟺~DoubleLongRightArrow~⟹~DoubleRightArrow~⇒~DoubleRightTee~⊨~DoubleUpArrow~⇑~DoubleUpDownArrow~⇕~DoubleVerticalBar~∥~DownArrow~↓~DownArrowBar~⤓~DownArrowUpArrow~⇵~DownBreve~̑~DownLeftRightVector~⥐~DownLeftTeeVector~⥞~DownLeftVector~↽~DownLeftVectorBar~⥖~DownRightTeeVector~⥟~DownRightVector~⇁~DownRightVectorBar~⥗~DownTee~⊤~DownTeeArrow~↧~Downarrow~⇓~Dscr~𝒟~Dstrok~Đ~ENG~Ŋ~Ecaron~Ě~Ecy~Э~Edot~Ė~Efr~𝔈~Element~∈~Emacr~Ē~EmptySmallSquare~◻~EmptyVerySmallSquare~▫~Eogon~Ę~Eopf~𝔼~Equal~⩵~EqualTilde~≂~Equilibrium~⇌~Escr~ℰ~Esim~⩳~Exists~∃~ExponentialE~ⅇ~Fcy~Ф~Ffr~𝔉~FilledSmallSquare~◼~FilledVerySmallSquare~▪~Fopf~𝔽~ForAll~∀~Fouriertrf~ℱ~Fscr~ℱ~GJcy~Ѓ~Gammad~Ϝ~Gbreve~Ğ~Gcedil~Ģ~Gcirc~Ĝ~Gcy~Г~Gdot~Ġ~Gfr~𝔊~Gg~⋙~Gopf~𝔾~GreaterEqual~≥~GreaterEqualLess~⋛~GreaterFullEqual~≧~GreaterGreater~⪢~GreaterLess~≷~GreaterSlantEqual~⩾~GreaterTilde~≳~Gscr~𝒢~Gt~≫~HARDcy~Ъ~Hacek~ˇ~Hat~^~Hcirc~Ĥ~Hfr~ℌ~HilbertSpace~ℋ~Hopf~ℍ~HorizontalLine~─~Hscr~ℋ~Hstrok~Ħ~HumpDownHump~≎~HumpEqual~≏~IEcy~Е~IJlig~IJ~IOcy~Ё~Icy~И~Idot~İ~Ifr~ℑ~Im~ℑ~Imacr~Ī~ImaginaryI~ⅈ~Implies~⇒~Int~∬~Integral~∫~Intersection~⋂~InvisibleComma~~InvisibleTimes~~Iogon~Į~Iopf~𝕀~Iscr~ℐ~Itilde~Ĩ~Iukcy~І~Jcirc~Ĵ~Jcy~Й~Jfr~𝔍~Jopf~𝕁~Jscr~𝒥~Jsercy~Ј~Jukcy~Є~KHcy~Х~KJcy~Ќ~Kcedil~Ķ~Kcy~К~Kfr~𝔎~Kopf~𝕂~Kscr~𝒦~LJcy~Љ~Lacute~Ĺ~Lang~⟪~Laplacetrf~ℒ~Larr~↞~Lcaron~Ľ~Lcedil~Ļ~Lcy~Л~LeftAngleBracket~⟨~LeftArrow~←~LeftArrowBar~⇤~LeftArrowRightArrow~⇆~LeftCeiling~⌈~LeftDoubleBracket~⟦~LeftDownTeeVector~⥡~LeftDownVector~⇃~LeftDownVectorBar~⥙~LeftFloor~⌊~LeftRightArrow~↔~LeftRightVector~⥎~LeftTee~⊣~LeftTeeArrow~↤~LeftTeeVector~⥚~LeftTriangle~⊲~LeftTriangleBar~⧏~LeftTriangleEqual~⊴~LeftUpDownVector~⥑~LeftUpTeeVector~⥠~LeftUpVector~↿~LeftUpVectorBar~⥘~LeftVector~↼~LeftVectorBar~⥒~Leftarrow~⇐~Leftrightarrow~⇔~LessEqualGreater~⋚~LessFullEqual~≦~LessGreater~≶~LessLess~⪡~LessSlantEqual~⩽~LessTilde~≲~Lfr~𝔏~Ll~⋘~Lleftarrow~⇚~Lmidot~Ŀ~LongLeftArrow~⟵~LongLeftRightArrow~⟷~LongRightArrow~⟶~Longleftarrow~⟸~Longleftrightarrow~⟺~Longrightarrow~⟹~Lopf~𝕃~LowerLeftArrow~↙~LowerRightArrow~↘~Lscr~ℒ~Lsh~↰~Lstrok~Ł~Lt~≪~Map~⤅~Mcy~М~MediumSpace~ ~Mellintrf~ℳ~Mfr~𝔐~MinusPlus~∓~Mopf~𝕄~Mscr~ℳ~NJcy~Њ~Nacute~Ń~Ncaron~Ň~Ncedil~Ņ~Ncy~Н~NegativeMediumSpace~~NegativeThickSpace~~NegativeThinSpace~~NegativeVeryThinSpace~~NestedGreaterGreater~≫~NestedLessLess~≪~NewLine~\\n~Nfr~𝔑~NoBreak~~NonBreakingSpace~ ~Nopf~ℕ~Not~⫬~NotCongruent~≢~NotCupCap~≭~NotDoubleVerticalBar~∦~NotElement~∉~NotEqual~≠~NotEqualTilde~≂̸~NotExists~∄~NotGreater~≯~NotGreaterEqual~≱~NotGreaterFullEqual~≧̸~NotGreaterGreater~≫̸~NotGreaterLess~≹~NotGreaterSlantEqual~⩾̸~NotGreaterTilde~≵~NotHumpDownHump~≎̸~NotHumpEqual~≏̸~NotLeftTriangle~⋪~NotLeftTriangleBar~⧏̸~NotLeftTriangleEqual~⋬~NotLess~≮~NotLessEqual~≰~NotLessGreater~≸~NotLessLess~≪̸~NotLessSlantEqual~⩽̸~NotLessTilde~≴~NotNestedGreaterGreater~⪢̸~NotNestedLessLess~⪡̸~NotPrecedes~⊀~NotPrecedesEqual~⪯̸~NotPrecedesSlantEqual~⋠~NotReverseElement~∌~NotRightTriangle~⋫~NotRightTriangleBar~⧐̸~NotRightTriangleEqual~⋭~NotSquareSubset~⊏̸~NotSquareSubsetEqual~⋢~NotSquareSuperset~⊐̸~NotSquareSupersetEqual~⋣~NotSubset~⊂⃒~NotSubsetEqual~⊈~NotSucceeds~⊁~NotSucceedsEqual~⪰̸~NotSucceedsSlantEqual~⋡~NotSucceedsTilde~≿̸~NotSuperset~⊃⃒~NotSupersetEqual~⊉~NotTilde~≁~NotTildeEqual~≄~NotTildeFullEqual~≇~NotTildeTilde~≉~NotVerticalBar~∤~Nscr~𝒩~Ocy~О~Odblac~Ő~Ofr~𝔒~Omacr~Ō~Oopf~𝕆~OpenCurlyDoubleQuote~“~OpenCurlyQuote~‘~Or~⩔~Oscr~𝒪~Otimes~⨷~OverBar~‾~OverBrace~⏞~OverBracket~⎴~OverParenthesis~⏜~PartialD~∂~Pcy~П~Pfr~𝔓~PlusMinus~±~Poincareplane~ℌ~Popf~ℙ~Pr~⪻~Precedes~≺~PrecedesEqual~⪯~PrecedesSlantEqual~≼~PrecedesTilde~≾~Product~∏~Proportion~∷~Proportional~∝~Pscr~𝒫~Qfr~𝔔~Qopf~ℚ~Qscr~𝒬~RBarr~⤐~Racute~Ŕ~Rang~⟫~Rarr~↠~Rarrtl~⤖~Rcaron~Ř~Rcedil~Ŗ~Rcy~Р~Re~ℜ~ReverseElement~∋~ReverseEquilibrium~⇋~ReverseUpEquilibrium~⥯~Rfr~ℜ~RightAngleBracket~⟩~RightArrow~→~RightArrowBar~⇥~RightArrowLeftArrow~⇄~RightCeiling~⌉~RightDoubleBracket~⟧~RightDownTeeVector~⥝~RightDownVector~⇂~RightDownVectorBar~⥕~RightFloor~⌋~RightTee~⊢~RightTeeArrow~↦~RightTeeVector~⥛~RightTriangle~⊳~RightTriangleBar~⧐~RightTriangleEqual~⊵~RightUpDownVector~⥏~RightUpTeeVector~⥜~RightUpVector~↾~RightUpVectorBar~⥔~RightVector~⇀~RightVectorBar~⥓~Rightarrow~⇒~Ropf~ℝ~RoundImplies~⥰~Rrightarrow~⇛~Rscr~ℛ~Rsh~↱~RuleDelayed~⧴~SHCHcy~Щ~SHcy~Ш~SOFTcy~Ь~Sacute~Ś~Sc~⪼~Scedil~Ş~Scirc~Ŝ~Scy~С~Sfr~𝔖~ShortDownArrow~↓~ShortLeftArrow~←~ShortRightArrow~→~ShortUpArrow~↑~SmallCircle~∘~Sopf~𝕊~Sqrt~√~Square~□~SquareIntersection~⊓~SquareSubset~⊏~SquareSubsetEqual~⊑~SquareSuperset~⊐~SquareSupersetEqual~⊒~SquareUnion~⊔~Sscr~𝒮~Star~⋆~Sub~⋐~Subset~⋐~SubsetEqual~⊆~Succeeds~≻~SucceedsEqual~⪰~SucceedsSlantEqual~≽~SucceedsTilde~≿~SuchThat~∋~Sum~∑~Sup~⋑~Superset~⊃~SupersetEqual~⊇~Supset~⋑~TRADE~™~TSHcy~Ћ~TScy~Ц~Tab~\\t~Tcaron~Ť~Tcedil~Ţ~Tcy~Т~Tfr~𝔗~Therefore~∴~ThickSpace~ ~ThinSpace~ ~Tilde~∼~TildeEqual~≃~TildeFullEqual~≅~TildeTilde~≈~Topf~𝕋~TripleDot~⃛~Tscr~𝒯~Tstrok~Ŧ~Uarr~↟~Uarrocir~⥉~Ubrcy~Ў~Ubreve~Ŭ~Ucy~У~Udblac~Ű~Ufr~𝔘~Umacr~Ū~UnderBar~_~UnderBrace~⏟~UnderBracket~⎵~UnderParenthesis~⏝~Union~⋃~UnionPlus~⊎~Uogon~Ų~Uopf~𝕌~UpArrow~↑~UpArrowBar~⤒~UpArrowDownArrow~⇅~UpDownArrow~↕~UpEquilibrium~⥮~UpTee~⊥~UpTeeArrow~↥~Uparrow~⇑~Updownarrow~⇕~UpperLeftArrow~↖~UpperRightArrow~↗~Upsi~ϒ~Uring~Ů~Uscr~𝒰~Utilde~Ũ~VDash~⊫~Vbar~⫫~Vcy~В~Vdash~⊩~Vdashl~⫦~Vee~⋁~Verbar~‖~Vert~‖~VerticalBar~∣~VerticalLine~|~VerticalSeparator~❘~VerticalTilde~≀~VeryThinSpace~ ~Vfr~𝔙~Vopf~𝕍~Vscr~𝒱~Vvdash~⊪~Wcirc~Ŵ~Wedge~⋀~Wfr~𝔚~Wopf~𝕎~Wscr~𝒲~Xfr~𝔛~Xopf~𝕏~Xscr~𝒳~YAcy~Я~YIcy~Ї~YUcy~Ю~Ycirc~Ŷ~Ycy~Ы~Yfr~𝔜~Yopf~𝕐~Yscr~𝒴~ZHcy~Ж~Zacute~Ź~Zcaron~Ž~Zcy~З~Zdot~Ż~ZeroWidthSpace~~Zfr~ℨ~Zopf~ℤ~Zscr~𝒵~abreve~ă~ac~∾~acE~∾̳~acd~∿~acy~а~af~~afr~𝔞~aleph~ℵ~amacr~ā~amalg~⨿~andand~⩕~andd~⩜~andslope~⩘~andv~⩚~ange~⦤~angle~∠~angmsd~∡~angmsdaa~⦨~angmsdab~⦩~angmsdac~⦪~angmsdad~⦫~angmsdae~⦬~angmsdaf~⦭~angmsdag~⦮~angmsdah~⦯~angrt~∟~angrtvb~⊾~angrtvbd~⦝~angsph~∢~angst~Å~angzarr~⍼~aogon~ą~aopf~𝕒~ap~≈~apE~⩰~apacir~⩯~ape~≊~apid~≋~approx~≈~approxeq~≊~ascr~𝒶~ast~*~asympeq~≍~awconint~∳~awint~⨑~bNot~⫭~backcong~≌~backepsilon~϶~backprime~‵~backsim~∽~backsimeq~⋍~barvee~⊽~barwed~⌅~barwedge~⌅~bbrk~⎵~bbrktbrk~⎶~bcong~≌~bcy~б~becaus~∵~because~∵~bemptyv~⦰~bepsi~϶~bernou~ℬ~beth~ℶ~between~≬~bfr~𝔟~bigcap~⋂~bigcirc~◯~bigcup~⋃~bigodot~⨀~bigoplus~⨁~bigotimes~⨂~bigsqcup~⨆~bigstar~★~bigtriangledown~▽~bigtriangleup~△~biguplus~⨄~bigvee~⋁~bigwedge~⋀~bkarow~⤍~blacklozenge~⧫~blacksquare~▪~blacktriangle~▴~blacktriangledown~▾~blacktriangleleft~◂~blacktriangleright~▸~blank~␣~blk12~▒~blk14~░~blk34~▓~block~█~bne~=⃥~bnequiv~≡⃥~bnot~⌐~bopf~𝕓~bot~⊥~bottom~⊥~bowtie~⋈~boxDL~╗~boxDR~╔~boxDl~╖~boxDr~╓~boxH~═~boxHD~╦~boxHU~╩~boxHd~╤~boxHu~╧~boxUL~╝~boxUR~╚~boxUl~╜~boxUr~╙~boxV~║~boxVH~╬~boxVL~╣~boxVR~╠~boxVh~╫~boxVl~╢~boxVr~╟~boxbox~⧉~boxdL~╕~boxdR~╒~boxdl~┐~boxdr~┌~boxh~─~boxhD~╥~boxhU~╨~boxhd~┬~boxhu~┴~boxminus~⊟~boxplus~⊞~boxtimes~⊠~boxuL~╛~boxuR~╘~boxul~┘~boxur~└~boxv~│~boxvH~╪~boxvL~╡~boxvR~╞~boxvh~┼~boxvl~┤~boxvr~├~bprime~‵~breve~˘~bscr~𝒷~bsemi~⁏~bsim~∽~bsime~⋍~bsol~\\\\~bsolb~⧅~bsolhsub~⟈~bullet~•~bump~≎~bumpE~⪮~bumpe~≏~bumpeq~≏~cacute~ć~capand~⩄~capbrcup~⩉~capcap~⩋~capcup~⩇~capdot~⩀~caps~∩︀~caret~⁁~caron~ˇ~ccaps~⩍~ccaron~č~ccirc~ĉ~ccups~⩌~ccupssm~⩐~cdot~ċ~cemptyv~⦲~centerdot~·~cfr~𝔠~chcy~ч~check~✓~checkmark~✓~cir~○~cirE~⧃~circeq~≗~circlearrowleft~↺~circlearrowright~↻~circledR~®~circledS~Ⓢ~circledast~⊛~circledcirc~⊚~circleddash~⊝~cire~≗~cirfnint~⨐~cirmid~⫯~cirscir~⧂~clubsuit~♣~colon~:~colone~≔~coloneq~≔~comma~,~commat~@~comp~∁~compfn~∘~complement~∁~complexes~ℂ~congdot~⩭~conint~∮~copf~𝕔~coprod~∐~copysr~℗~cross~✗~cscr~𝒸~csub~⫏~csube~⫑~csup~⫐~csupe~⫒~ctdot~⋯~cudarrl~⤸~cudarrr~⤵~cuepr~⋞~cuesc~⋟~cularr~↶~cularrp~⤽~cupbrcap~⩈~cupcap~⩆~cupcup~⩊~cupdot~⊍~cupor~⩅~cups~∪︀~curarr~↷~curarrm~⤼~curlyeqprec~⋞~curlyeqsucc~⋟~curlyvee~⋎~curlywedge~⋏~curvearrowleft~↶~curvearrowright~↷~cuvee~⋎~cuwed~⋏~cwconint~∲~cwint~∱~cylcty~⌭~dHar~⥥~daleth~ℸ~dash~‐~dashv~⊣~dbkarow~⤏~dblac~˝~dcaron~ď~dcy~д~dd~ⅆ~ddagger~‡~ddarr~⇊~ddotseq~⩷~demptyv~⦱~dfisht~⥿~dfr~𝔡~dharl~⇃~dharr~⇂~diam~⋄~diamond~⋄~diamondsuit~♦~die~¨~digamma~ϝ~disin~⋲~div~÷~divideontimes~⋇~divonx~⋇~djcy~ђ~dlcorn~⌞~dlcrop~⌍~dollar~$~dopf~𝕕~dot~˙~doteq~≐~doteqdot~≑~dotminus~∸~dotplus~∔~dotsquare~⊡~doublebarwedge~⌆~downarrow~↓~downdownarrows~⇊~downharpoonleft~⇃~downharpoonright~⇂~drbkarow~⤐~drcorn~⌟~drcrop~⌌~dscr~𝒹~dscy~ѕ~dsol~⧶~dstrok~đ~dtdot~⋱~dtri~▿~dtrif~▾~duarr~⇵~duhar~⥯~dwangle~⦦~dzcy~џ~dzigrarr~⟿~eDDot~⩷~eDot~≑~easter~⩮~ecaron~ě~ecir~≖~ecolon~≕~ecy~э~edot~ė~ee~ⅇ~efDot~≒~efr~𝔢~eg~⪚~egs~⪖~egsdot~⪘~el~⪙~elinters~⏧~ell~ℓ~els~⪕~elsdot~⪗~emacr~ē~emptyset~∅~emptyv~∅~emsp13~ ~emsp14~ ~eng~ŋ~eogon~ę~eopf~𝕖~epar~⋕~eparsl~⧣~eplus~⩱~epsi~ε~epsiv~ϵ~eqcirc~≖~eqcolon~≕~eqsim~≂~eqslantgtr~⪖~eqslantless~⪕~equals~=~equest~≟~equivDD~⩸~eqvparsl~⧥~erDot~≓~erarr~⥱~escr~ℯ~esdot~≐~esim~≂~excl~!~expectation~ℰ~exponentiale~ⅇ~fallingdotseq~≒~fcy~ф~female~♀~ffilig~ffi~fflig~ff~ffllig~ffl~ffr~𝔣~filig~fi~fjlig~fj~flat~♭~fllig~fl~fltns~▱~fopf~𝕗~fork~⋔~forkv~⫙~fpartint~⨍~frac13~⅓~frac15~⅕~frac16~⅙~frac18~⅛~frac23~⅔~frac25~⅖~frac35~⅗~frac38~⅜~frac45~⅘~frac56~⅚~frac58~⅝~frac78~⅞~frown~⌢~fscr~𝒻~gE~≧~gEl~⪌~gacute~ǵ~gammad~ϝ~gap~⪆~gbreve~ğ~gcirc~ĝ~gcy~г~gdot~ġ~gel~⋛~geq~≥~geqq~≧~geqslant~⩾~ges~⩾~gescc~⪩~gesdot~⪀~gesdoto~⪂~gesdotol~⪄~gesl~⋛︀~gesles~⪔~gfr~𝔤~gg~≫~ggg~⋙~gimel~ℷ~gjcy~ѓ~gl~≷~glE~⪒~gla~⪥~glj~⪤~gnE~≩~gnap~⪊~gnapprox~⪊~gne~⪈~gneq~⪈~gneqq~≩~gnsim~⋧~gopf~𝕘~grave~`~gscr~ℊ~gsim~≳~gsime~⪎~gsiml~⪐~gtcc~⪧~gtcir~⩺~gtdot~⋗~gtlPar~⦕~gtquest~⩼~gtrapprox~⪆~gtrarr~⥸~gtrdot~⋗~gtreqless~⋛~gtreqqless~⪌~gtrless~≷~gtrsim~≳~gvertneqq~≩︀~gvnE~≩︀~hairsp~ ~half~½~hamilt~ℋ~hardcy~ъ~harrcir~⥈~harrw~↭~hbar~ℏ~hcirc~ĥ~heartsuit~♥~hercon~⊹~hfr~𝔥~hksearow~⤥~hkswarow~⤦~hoarr~⇿~homtht~∻~hookleftarrow~↩~hookrightarrow~↪~hopf~𝕙~horbar~―~hscr~𝒽~hslash~ℏ~hstrok~ħ~hybull~⁃~hyphen~‐~ic~~icy~и~iecy~е~iff~⇔~ifr~𝔦~ii~ⅈ~iiiint~⨌~iiint~∭~iinfin~⧜~iiota~℩~ijlig~ij~imacr~ī~imagline~ℐ~imagpart~ℑ~imath~ı~imof~⊷~imped~Ƶ~in~∈~incare~℅~infintie~⧝~inodot~ı~intcal~⊺~integers~ℤ~intercal~⊺~intlarhk~⨗~intprod~⨼~iocy~ё~iogon~į~iopf~𝕚~iprod~⨼~iscr~𝒾~isinE~⋹~isindot~⋵~isins~⋴~isinsv~⋳~isinv~∈~it~~itilde~ĩ~iukcy~і~jcirc~ĵ~jcy~й~jfr~𝔧~jmath~ȷ~jopf~𝕛~jscr~𝒿~jsercy~ј~jukcy~є~kappav~ϰ~kcedil~ķ~kcy~к~kfr~𝔨~kgreen~ĸ~khcy~х~kjcy~ќ~kopf~𝕜~kscr~𝓀~lAarr~⇚~lAtail~⤛~lBarr~⤎~lE~≦~lEg~⪋~lHar~⥢~lacute~ĺ~laemptyv~⦴~lagran~ℒ~langd~⦑~langle~⟨~lap~⪅~larrb~⇤~larrbfs~⤟~larrfs~⤝~larrhk~↩~larrlp~↫~larrpl~⤹~larrsim~⥳~larrtl~↢~lat~⪫~latail~⤙~late~⪭~lates~⪭︀~lbarr~⤌~lbbrk~❲~lbrace~{~lbrack~[~lbrke~⦋~lbrksld~⦏~lbrkslu~⦍~lcaron~ľ~lcedil~ļ~lcub~{~lcy~л~ldca~⤶~ldquor~„~ldrdhar~⥧~ldrushar~⥋~ldsh~↲~leftarrow~←~leftarrowtail~↢~leftharpoondown~↽~leftharpoonup~↼~leftleftarrows~⇇~leftrightarrow~↔~leftrightarrows~⇆~leftrightharpoons~⇋~leftrightsquigarrow~↭~leftthreetimes~⋋~leg~⋚~leq~≤~leqq~≦~leqslant~⩽~les~⩽~lescc~⪨~lesdot~⩿~lesdoto~⪁~lesdotor~⪃~lesg~⋚︀~lesges~⪓~lessapprox~⪅~lessdot~⋖~lesseqgtr~⋚~lesseqqgtr~⪋~lessgtr~≶~lesssim~≲~lfisht~⥼~lfr~𝔩~lg~≶~lgE~⪑~lhard~↽~lharu~↼~lharul~⥪~lhblk~▄~ljcy~љ~ll~≪~llarr~⇇~llcorner~⌞~llhard~⥫~lltri~◺~lmidot~ŀ~lmoust~⎰~lmoustache~⎰~lnE~≨~lnap~⪉~lnapprox~⪉~lne~⪇~lneq~⪇~lneqq~≨~lnsim~⋦~loang~⟬~loarr~⇽~lobrk~⟦~longleftarrow~⟵~longleftrightarrow~⟷~longmapsto~⟼~longrightarrow~⟶~looparrowleft~↫~looparrowright~↬~lopar~⦅~lopf~𝕝~loplus~⨭~lotimes~⨴~lowbar~_~lozenge~◊~lozf~⧫~lpar~(~lparlt~⦓~lrarr~⇆~lrcorner~⌟~lrhar~⇋~lrhard~⥭~lrtri~⊿~lscr~𝓁~lsh~↰~lsim~≲~lsime~⪍~lsimg~⪏~lsqb~[~lsquor~‚~lstrok~ł~ltcc~⪦~ltcir~⩹~ltdot~⋖~lthree~⋋~ltimes~⋉~ltlarr~⥶~ltquest~⩻~ltrPar~⦖~ltri~◃~ltrie~⊴~ltrif~◂~lurdshar~⥊~luruhar~⥦~lvertneqq~≨︀~lvnE~≨︀~mDDot~∺~male~♂~malt~✠~maltese~✠~map~↦~mapsto~↦~mapstodown~↧~mapstoleft~↤~mapstoup~↥~marker~▮~mcomma~⨩~mcy~м~measuredangle~∡~mfr~𝔪~mho~℧~mid~∣~midast~*~midcir~⫰~minusb~⊟~minusd~∸~minusdu~⨪~mlcp~⫛~mldr~…~mnplus~∓~models~⊧~mopf~𝕞~mp~∓~mscr~𝓂~mstpos~∾~multimap~⊸~mumap~⊸~nGg~⋙̸~nGt~≫⃒~nGtv~≫̸~nLeftarrow~⇍~nLeftrightarrow~⇎~nLl~⋘̸~nLt~≪⃒~nLtv~≪̸~nRightarrow~⇏~nVDash~⊯~nVdash~⊮~nacute~ń~nang~∠⃒~nap~≉~napE~⩰̸~napid~≋̸~napos~ʼn~napprox~≉~natur~♮~natural~♮~naturals~ℕ~nbump~≎̸~nbumpe~≏̸~ncap~⩃~ncaron~ň~ncedil~ņ~ncong~≇~ncongdot~⩭̸~ncup~⩂~ncy~н~neArr~⇗~nearhk~⤤~nearr~↗~nearrow~↗~nedot~≐̸~nequiv~≢~nesear~⤨~nesim~≂̸~nexist~∄~nexists~∄~nfr~𝔫~ngE~≧̸~nge~≱~ngeq~≱~ngeqq~≧̸~ngeqslant~⩾̸~nges~⩾̸~ngsim~≵~ngt~≯~ngtr~≯~nhArr~⇎~nharr~↮~nhpar~⫲~nis~⋼~nisd~⋺~niv~∋~njcy~њ~nlArr~⇍~nlE~≦̸~nlarr~↚~nldr~‥~nle~≰~nleftarrow~↚~nleftrightarrow~↮~nleq~≰~nleqq~≦̸~nleqslant~⩽̸~nles~⩽̸~nless~≮~nlsim~≴~nlt~≮~nltri~⋪~nltrie~⋬~nmid~∤~nopf~𝕟~notinE~⋹̸~notindot~⋵̸~notinva~∉~notinvb~⋷~notinvc~⋶~notni~∌~notniva~∌~notnivb~⋾~notnivc~⋽~npar~∦~nparallel~∦~nparsl~⫽⃥~npart~∂̸~npolint~⨔~npr~⊀~nprcue~⋠~npre~⪯̸~nprec~⊀~npreceq~⪯̸~nrArr~⇏~nrarr~↛~nrarrc~⤳̸~nrarrw~↝̸~nrightarrow~↛~nrtri~⋫~nrtrie~⋭~nsc~⊁~nsccue~⋡~nsce~⪰̸~nscr~𝓃~nshortmid~∤~nshortparallel~∦~nsim~≁~nsime~≄~nsimeq~≄~nsmid~∤~nspar~∦~nsqsube~⋢~nsqsupe~⋣~nsubE~⫅̸~nsube~⊈~nsubset~⊂⃒~nsubseteq~⊈~nsubseteqq~⫅̸~nsucc~⊁~nsucceq~⪰̸~nsup~⊅~nsupE~⫆̸~nsupe~⊉~nsupset~⊃⃒~nsupseteq~⊉~nsupseteqq~⫆̸~ntgl~≹~ntlg~≸~ntriangleleft~⋪~ntrianglelefteq~⋬~ntriangleright~⋫~ntrianglerighteq~⋭~num~#~numero~№~numsp~ ~nvDash~⊭~nvHarr~⤄~nvap~≍⃒~nvdash~⊬~nvge~≥⃒~nvgt~>⃒~nvinfin~⧞~nvlArr~⤂~nvle~≤⃒~nvlt~<⃒~nvltrie~⊴⃒~nvrArr~⤃~nvrtrie~⊵⃒~nvsim~∼⃒~nwArr~⇖~nwarhk~⤣~nwarr~↖~nwarrow~↖~nwnear~⤧~oS~Ⓢ~oast~⊛~ocir~⊚~ocy~о~odash~⊝~odblac~ő~odiv~⨸~odot~⊙~odsold~⦼~ofcir~⦿~ofr~𝔬~ogon~˛~ogt~⧁~ohbar~⦵~ohm~Ω~oint~∮~olarr~↺~olcir~⦾~olcross~⦻~olt~⧀~omacr~ō~omid~⦶~ominus~⊖~oopf~𝕠~opar~⦷~operp~⦹~orarr~↻~ord~⩝~order~ℴ~orderof~ℴ~origof~⊶~oror~⩖~orslope~⩗~orv~⩛~oscr~ℴ~osol~⊘~otimesas~⨶~ovbar~⌽~par~∥~parallel~∥~parsim~⫳~parsl~⫽~pcy~п~percnt~%~period~.~pertenk~‱~pfr~𝔭~phiv~ϕ~phmmat~ℳ~phone~☎~pitchfork~⋔~planck~ℏ~planckh~ℎ~plankv~ℏ~plus~+~plusacir~⨣~plusb~⊞~pluscir~⨢~plusdo~∔~plusdu~⨥~pluse~⩲~plussim~⨦~plustwo~⨧~pm~±~pointint~⨕~popf~𝕡~pr~≺~prE~⪳~prap~⪷~prcue~≼~pre~⪯~prec~≺~precapprox~⪷~preccurlyeq~≼~preceq~⪯~precnapprox~⪹~precneqq~⪵~precnsim~⋨~precsim~≾~primes~ℙ~prnE~⪵~prnap~⪹~prnsim~⋨~profalar~⌮~profline~⌒~profsurf~⌓~propto~∝~prsim~≾~prurel~⊰~pscr~𝓅~puncsp~ ~qfr~𝔮~qint~⨌~qopf~𝕢~qprime~⁗~qscr~𝓆~quaternions~ℍ~quatint~⨖~quest~?~questeq~≟~rAarr~⇛~rAtail~⤜~rBarr~⤏~rHar~⥤~race~∽̱~racute~ŕ~raemptyv~⦳~rangd~⦒~range~⦥~rangle~⟩~rarrap~⥵~rarrb~⇥~rarrbfs~⤠~rarrc~⤳~rarrfs~⤞~rarrhk~↪~rarrlp~↬~rarrpl~⥅~rarrsim~⥴~rarrtl~↣~rarrw~↝~ratail~⤚~ratio~∶~rationals~ℚ~rbarr~⤍~rbbrk~❳~rbrace~}~rbrack~]~rbrke~⦌~rbrksld~⦎~rbrkslu~⦐~rcaron~ř~rcedil~ŗ~rcub~}~rcy~р~rdca~⤷~rdldhar~⥩~rdquor~”~rdsh~↳~realine~ℛ~realpart~ℜ~reals~ℝ~rect~▭~rfisht~⥽~rfr~𝔯~rhard~⇁~rharu~⇀~rharul~⥬~rhov~ϱ~rightarrow~→~rightarrowtail~↣~rightharpoondown~⇁~rightharpoonup~⇀~rightleftarrows~⇄~rightleftharpoons~⇌~rightrightarrows~⇉~rightsquigarrow~↝~rightthreetimes~⋌~ring~˚~risingdotseq~≓~rlarr~⇄~rlhar~⇌~rmoust~⎱~rmoustache~⎱~rnmid~⫮~roang~⟭~roarr~⇾~robrk~⟧~ropar~⦆~ropf~𝕣~roplus~⨮~rotimes~⨵~rpar~)~rpargt~⦔~rppolint~⨒~rrarr~⇉~rscr~𝓇~rsh~↱~rsqb~]~rsquor~’~rthree~⋌~rtimes~⋊~rtri~▹~rtrie~⊵~rtrif~▸~rtriltri~⧎~ruluhar~⥨~rx~℞~sacute~ś~sc~≻~scE~⪴~scap~⪸~sccue~≽~sce~⪰~scedil~ş~scirc~ŝ~scnE~⪶~scnap~⪺~scnsim~⋩~scpolint~⨓~scsim~≿~scy~с~sdotb~⊡~sdote~⩦~seArr~⇘~searhk~⤥~searr~↘~searrow~↘~semi~;~seswar~⤩~setminus~∖~setmn~∖~sext~✶~sfr~𝔰~sfrown~⌢~sharp~♯~shchcy~щ~shcy~ш~shortmid~∣~shortparallel~∥~sigmav~ς~simdot~⩪~sime~≃~simeq~≃~simg~⪞~simgE~⪠~siml~⪝~simlE~⪟~simne~≆~simplus~⨤~simrarr~⥲~slarr~←~smallsetminus~∖~smashp~⨳~smeparsl~⧤~smid~∣~smile~⌣~smt~⪪~smte~⪬~smtes~⪬︀~softcy~ь~sol~/~solb~⧄~solbar~⌿~sopf~𝕤~spadesuit~♠~spar~∥~sqcap~⊓~sqcaps~⊓︀~sqcup~⊔~sqcups~⊔︀~sqsub~⊏~sqsube~⊑~sqsubset~⊏~sqsubseteq~⊑~sqsup~⊐~sqsupe~⊒~sqsupset~⊐~sqsupseteq~⊒~squ~□~square~□~squarf~▪~squf~▪~srarr~→~sscr~𝓈~ssetmn~∖~ssmile~⌣~sstarf~⋆~star~☆~starf~★~straightepsilon~ϵ~straightphi~ϕ~strns~¯~subE~⫅~subdot~⪽~subedot~⫃~submult~⫁~subnE~⫋~subne~⊊~subplus~⪿~subrarr~⥹~subset~⊂~subseteq~⊆~subseteqq~⫅~subsetneq~⊊~subsetneqq~⫋~subsim~⫇~subsub~⫕~subsup~⫓~succ~≻~succapprox~⪸~succcurlyeq~≽~succeq~⪰~succnapprox~⪺~succneqq~⪶~succnsim~⋩~succsim~≿~sung~♪~supE~⫆~supdot~⪾~supdsub~⫘~supedot~⫄~suphsol~⟉~suphsub~⫗~suplarr~⥻~supmult~⫂~supnE~⫌~supne~⊋~supplus~⫀~supset~⊃~supseteq~⊇~supseteqq~⫆~supsetneq~⊋~supsetneqq~⫌~supsim~⫈~supsub~⫔~supsup~⫖~swArr~⇙~swarhk~⤦~swarr~↙~swarrow~↙~swnwar~⤪~target~⌖~tbrk~⎴~tcaron~ť~tcedil~ţ~tcy~т~tdot~⃛~telrec~⌕~tfr~𝔱~therefore~∴~thetav~ϑ~thickapprox~≈~thicksim~∼~thkap~≈~thksim~∼~timesb~⊠~timesbar~⨱~timesd~⨰~tint~∭~toea~⤨~top~⊤~topbot~⌶~topcir~⫱~topf~𝕥~topfork~⫚~tosa~⤩~tprime~‴~triangle~▵~triangledown~▿~triangleleft~◃~trianglelefteq~⊴~triangleq~≜~triangleright~▹~trianglerighteq~⊵~tridot~◬~trie~≜~triminus~⨺~triplus~⨹~trisb~⧍~tritime~⨻~trpezium~⏢~tscr~𝓉~tscy~ц~tshcy~ћ~tstrok~ŧ~twixt~≬~twoheadleftarrow~↞~twoheadrightarrow~↠~uHar~⥣~ubrcy~ў~ubreve~ŭ~ucy~у~udarr~⇅~udblac~ű~udhar~⥮~ufisht~⥾~ufr~𝔲~uharl~↿~uharr~↾~uhblk~▀~ulcorn~⌜~ulcorner~⌜~ulcrop~⌏~ultri~◸~umacr~ū~uogon~ų~uopf~𝕦~uparrow~↑~updownarrow~↕~upharpoonleft~↿~upharpoonright~↾~uplus~⊎~upsi~υ~upuparrows~⇈~urcorn~⌝~urcorner~⌝~urcrop~⌎~uring~ů~urtri~◹~uscr~𝓊~utdot~⋰~utilde~ũ~utri~▵~utrif~▴~uuarr~⇈~uwangle~⦧~vArr~⇕~vBar~⫨~vBarv~⫩~vDash~⊨~vangrt~⦜~varepsilon~ϵ~varkappa~ϰ~varnothing~∅~varphi~ϕ~varpi~ϖ~varpropto~∝~varr~↕~varrho~ϱ~varsigma~ς~varsubsetneq~⊊︀~varsubsetneqq~⫋︀~varsupsetneq~⊋︀~varsupsetneqq~⫌︀~vartheta~ϑ~vartriangleleft~⊲~vartriangleright~⊳~vcy~в~vdash~⊢~vee~∨~veebar~⊻~veeeq~≚~vellip~⋮~verbar~|~vert~|~vfr~𝔳~vltri~⊲~vnsub~⊂⃒~vnsup~⊃⃒~vopf~𝕧~vprop~∝~vrtri~⊳~vscr~𝓋~vsubnE~⫋︀~vsubne~⊊︀~vsupnE~⫌︀~vsupne~⊋︀~vzigzag~⦚~wcirc~ŵ~wedbar~⩟~wedge~∧~wedgeq~≙~wfr~𝔴~wopf~𝕨~wp~℘~wr~≀~wreath~≀~wscr~𝓌~xcap~⋂~xcirc~◯~xcup~⋃~xdtri~▽~xfr~𝔵~xhArr~⟺~xharr~⟷~xlArr~⟸~xlarr~⟵~xmap~⟼~xnis~⋻~xodot~⨀~xopf~𝕩~xoplus~⨁~xotime~⨂~xrArr~⟹~xrarr~⟶~xscr~𝓍~xsqcup~⨆~xuplus~⨄~xutri~△~xvee~⋁~xwedge~⋀~yacy~я~ycirc~ŷ~ycy~ы~yfr~𝔶~yicy~ї~yopf~𝕪~yscr~𝓎~yucy~ю~zacute~ź~zcaron~ž~zcy~з~zdot~ż~zeetrf~ℨ~zfr~𝔷~zhcy~ж~zigrarr~⇝~zopf~𝕫~zscr~𝓏~~AMP~&~COPY~©~GT~>~LT~<~QUOT~\\\"~REG~®\", namedReferences['html4']);\n//# sourceMappingURL=named-references.js.map","export var numericUnicodeMap = {\n 0: 65533,\n 128: 8364,\n 130: 8218,\n 131: 402,\n 132: 8222,\n 133: 8230,\n 134: 8224,\n 135: 8225,\n 136: 710,\n 137: 8240,\n 138: 352,\n 139: 8249,\n 140: 338,\n 142: 381,\n 145: 8216,\n 146: 8217,\n 147: 8220,\n 148: 8221,\n 149: 8226,\n 150: 8211,\n 151: 8212,\n 152: 732,\n 153: 8482,\n 154: 353,\n 155: 8250,\n 156: 339,\n 158: 382,\n 159: 376\n};\n//# sourceMappingURL=numeric-unicode-map.js.map","export var fromCodePoint = String.fromCodePoint ||\n function (astralCodePoint) {\n return String.fromCharCode(Math.floor((astralCodePoint - 0x10000) / 0x400) + 0xd800, ((astralCodePoint - 0x10000) % 0x400) + 0xdc00);\n };\n// @ts-expect-error - String.prototype.codePointAt might not exist in older node versions\nexport var getCodePoint = String.prototype.codePointAt\n ? function (input, position) {\n return input.codePointAt(position);\n }\n : function (input, position) {\n return (input.charCodeAt(position) - 0xd800) * 0x400 + input.charCodeAt(position + 1) - 0xdc00 + 0x10000;\n };\nexport var highSurrogateFrom = 0xd800;\nexport var highSurrogateTo = 0xdbff;\n//# sourceMappingURL=surrogate-pairs.js.map","var __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nimport { bodyRegExps, namedReferences } from './named-references.js';\nimport { numericUnicodeMap } from './numeric-unicode-map.js';\nimport { fromCodePoint, getCodePoint } from './surrogate-pairs.js';\nvar allNamedReferences = __assign(__assign({}, namedReferences), { all: namedReferences.html5 });\nvar encodeRegExps = {\n specialChars: /[<>'\"&]/g,\n nonAscii: /[<>'\"&\\u0080-\\uD7FF\\uE000-\\uFFFF\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]?/g,\n nonAsciiPrintable: /[<>'\"&\\x01-\\x08\\x11-\\x15\\x17-\\x1F\\x7f-\\uD7FF\\uE000-\\uFFFF\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]?/g,\n nonAsciiPrintableOnly: /[\\x01-\\x08\\x11-\\x15\\x17-\\x1F\\x7f-\\uD7FF\\uE000-\\uFFFF\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]?/g,\n extensive: /[\\x01-\\x0c\\x0e-\\x1f\\x21-\\x2c\\x2e-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7d\\x7f-\\uD7FF\\uE000-\\uFFFF\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]?/g\n};\nvar defaultEncodeOptions = {\n mode: 'specialChars',\n level: 'all',\n numeric: 'decimal'\n};\n/** Encodes all the necessary (specified by `level`) characters in the text */\nexport function encode(text, _a) {\n var _b = _a === void 0 ? defaultEncodeOptions : _a, _c = _b.mode, mode = _c === void 0 ? 'specialChars' : _c, _d = _b.numeric, numeric = _d === void 0 ? 'decimal' : _d, _e = _b.level, level = _e === void 0 ? 'all' : _e;\n if (!text) {\n return '';\n }\n var encodeRegExp = encodeRegExps[mode];\n var references = allNamedReferences[level].characters;\n var isHex = numeric === 'hexadecimal';\n return String.prototype.replace.call(text, encodeRegExp, function (input) {\n var result = references[input];\n if (!result) {\n var code = input.length > 1 ? getCodePoint(input, 0) : input.charCodeAt(0);\n result = (isHex ? '' + code.toString(16) : '' + code) + ';';\n }\n return result;\n });\n}\nvar defaultDecodeOptions = {\n scope: 'body',\n level: 'all'\n};\nvar strict = /&(?:#\\d+|#[xX][\\da-fA-F]+|[0-9a-zA-Z]+);/g;\nvar attribute = /&(?:#\\d+|#[xX][\\da-fA-F]+|[0-9a-zA-Z]+)[;=]?/g;\nvar baseDecodeRegExps = {\n xml: {\n strict: strict,\n attribute: attribute,\n body: bodyRegExps.xml\n },\n html4: {\n strict: strict,\n attribute: attribute,\n body: bodyRegExps.html4\n },\n html5: {\n strict: strict,\n attribute: attribute,\n body: bodyRegExps.html5\n }\n};\nvar decodeRegExps = __assign(__assign({}, baseDecodeRegExps), { all: baseDecodeRegExps.html5 });\nvar fromCharCode = String.fromCharCode;\nvar outOfBoundsChar = fromCharCode(65533);\nvar defaultDecodeEntityOptions = {\n level: 'all'\n};\nfunction getDecodedEntity(entity, references, isAttribute, isStrict) {\n var decodeResult = entity;\n var decodeEntityLastChar = entity[entity.length - 1];\n if (isAttribute && decodeEntityLastChar === '=') {\n decodeResult = entity;\n }\n else if (isStrict && decodeEntityLastChar !== ';') {\n decodeResult = entity;\n }\n else {\n var decodeResultByReference = references[entity];\n if (decodeResultByReference) {\n decodeResult = decodeResultByReference;\n }\n else if (entity[0] === '&' && entity[1] === '#') {\n var decodeSecondChar = entity[2];\n var decodeCode = decodeSecondChar == 'x' || decodeSecondChar == 'X'\n ? parseInt(entity.substr(3), 16)\n : parseInt(entity.substr(2));\n decodeResult =\n decodeCode >= 0x10ffff\n ? outOfBoundsChar\n : decodeCode > 65535\n ? fromCodePoint(decodeCode)\n : fromCharCode(numericUnicodeMap[decodeCode] || decodeCode);\n }\n }\n return decodeResult;\n}\n/** Decodes a single entity */\nexport function decodeEntity(entity, _a) {\n var _b = _a === void 0 ? defaultDecodeEntityOptions : _a, _c = _b.level, level = _c === void 0 ? 'all' : _c;\n if (!entity) {\n return '';\n }\n return getDecodedEntity(entity, allNamedReferences[level].entities, false, false);\n}\n/** Decodes all entities in the text */\nexport function decode(text, _a) {\n var _b = _a === void 0 ? defaultDecodeOptions : _a, _c = _b.level, level = _c === void 0 ? 'all' : _c, _d = _b.scope, scope = _d === void 0 ? level === 'xml' ? 'strict' : 'body' : _d;\n if (!text) {\n return '';\n }\n var decodeRegExp = decodeRegExps[level][scope];\n var references = allNamedReferences[level].entities;\n var isAttribute = scope === 'attribute';\n var isStrict = scope === 'strict';\n return text.replace(decodeRegExp, function (entity) { return getDecodedEntity(entity, references, isAttribute, isStrict); });\n}\n//# sourceMappingURL=index.js.map","\n\n.p {\n margin-bottom: 2pt;\n}\n.bold {\n font-weight: bold;\n}\n.italic {\n font-style: italic;\n}\n.underlined {\n text-decoration: underline;\n}\n.strikethrough {\n text-decoration: line-through;\n}\n \n","export function isEmptyHtml(html) {\n if (html === null) {\n return true\n }\n\n return html.trim() === '' || html.trim() === '
'\n}\n","\n \n {{ $t('entity.day.name') }} {{ day.number }} \n {{ date }} \n \n \n \n \n \n \n {{ scheduleEntry.number }} {{ chapter.title }}\n \n \n \n \n \n \n \n \n\n\n.summary-day-title-container {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: baseline;\n border-bottom: 2pt solid #aaaaaa;\n padding-bottom: 2pt;\n margin-bottom: 1pt;\n}\n.summary-day-title {\n font-size: 14;\n font-weight: semibold;\n margin: 10pt 0 3pt;\n}\n.summary-day-date {\n font-size: 11pt;\n}\n.summary-chapter-title {\n display: flex;\n flex-direction: row;\n align-items: center;\n font-weight: bold;\n margin: 10pt 0 4.5pt;\n}\n \n","\n {{ title }}: {{ period.description }} \n \n \n\n\n.summary-period-title {\n font-size: 10pt;\n font-weight: bold;\n text-align: center;\n}\n \n","\n \n \n \n \n\n","\n \n \n \n \n\n","\n \n \n \n \n \n\n\n.schedule-entry-header-title {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: baseline;\n padding-bottom: 2pt;\n border-bottom: 2pt solid #aaaaaa;\n}\n.schedule-entry-title {\n flex-grow: 1;\n display: flex;\n flex-direction: row;\n font-size: 14;\n font-weight: semibold;\n}\n.schedule-entry-category-label {\n margin: 4pt 0;\n font-size: 12pt;\n}\n.schedule-entry-number-and-title {\n margin: 4pt 4pt;\n max-width: 345pt;\n}\n.schedule-entry-date {\n font-size: 11pt;\n}\n.schedule-entry-header {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n border-bottom: 0.5pt solid black;\n font-size: 10pt;\n margin-bottom: 10pt;\n}\n.schedule-entry-header-divider {\n border-left: 0.5pt solid black;\n margin-left: 3.5pt;\n padding-left: 5pt\n}\n.schedule-entry-header-metadata {\n width: 50%;\n padding: 2pt 0;\n}\n.schedule-entry-header-metadata-entry {\n flex-direction: row;\n align-items: flex-start;\n column-gap: 6pt;\n}\n.schedule-entry-header-metadata-label {\n font-weight: semibold;\n flex-shrink: 0;\n flex-grow: 0;\n}\n \n","\n \n \n \n \n \n \n \n \n\n\n.column-layout-container {\n display: flex;\n flex-direction: row;\n}\n \n","\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n\n.responsive-layout__container {\n display: flex;\n flex-direction: column;\n}\n.responsive-layout__flex {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n overflow: hidden;\n margin-left: -10pt;\n margin-right: -10pt;\n}\n.responsive-layout__flex_item {\n flex-grow: 1;\n flex-basis: 200pt;\n background-color: #fff;\n border-left: 0.75pt solid black;\n margin-left: -1pt;\n padding-left: 9pt;\n padding-right: 10pt;\n}\n \n","\n \n {{ instanceName }} \n {{\n contentTypeName\n }} \n \n \n\n\n.content-node-title {\n border-bottom: 1.5pt solid black;\n margin-bottom: 1pt;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: baseline;\n}\n.content-node-instance-name {\n flex-grow: 1;\n font-weight: bold;\n font-size: 11pt;\n padding-bottom: 3pt;\n}\n.content-type-name {\n font-size:8pt;\n font-weight:normal;\n color:grey;\n}\n \n","\n \n \n \n \n \n\n\n.checkmark {\n margin-top: 1.5pt;\n}\n \n","\n \n \n \n \n \n {{ translation(key) }} \n \n \n \n \n\n\n.la-thematic-area-entry {\n display: flex;\n flex-direction: row;\n align-items: top;\n}\n \n","\n \n \n \n \n \n \n \n\n\n \n","\n \n \n \n \n \n \n \n\n\n \n","\n \n \n \n \n \n {{ section.column1 }} \n \n \n \n \n \n {{ section.column3 }} \n \n \n \n \n\n\n.storyboard-container {\n display: flex;\n flex-direction: column;\n}\n.storyboard-header-row {\n display: flex;\n flex-direction: row;\n border-bottom: 0.75pt solid #94A3B8;\n}\n.storyboard-row {\n display: flex;\n flex-direction: row;\n}\n.storyboard-header-cell {\n line-height: 0.8;\n font-weight: semibold;\n}\n.storyboard-cell {\n line-height: 0.8;\n padding-top: 1pt;\n padding-bottom: 3pt;\n}\n.storyboard-column-1 {\n width: 28pt;\n flex-shrink: 0;\n flex-grow: 0;\n padding-right: 2pt;\n overflow: hidden;\n}\n.storyboard-column-2 {\n flex-basis: 0;\n flex-grow: 1;\n border-left: 0.75pt solid #94A3B8;\n padding-horizontal: 2pt;\n}\n.storyboard-column-3 {\n flex-basis: 40pt;\n flex-shrink: 0;\n flex-grow: 0;\n border-left: 0.75pt solid #94A3B8;\n padding-left: 2pt;\n overflow: hidden;\n}\n \n","\n \n \n \n \n \n \n \n\n\n \n","\n \n \n \n \n \n \n \n\n\n \n","\n \n \n \n \n {{ item.quantity }} {{ item.unit }} {{ item.article }} \n \n \n {{ item.materialList ? item.materialList()?.name : '' }} \n \n \n \n \n\n\n.material {\n display: flex;\n flex-direction: column;\n}\n.material-item {\n display: flex;\n flex-direction: row;\n}\n.material-item-column {\n flex-grow: 1;\n border-bottom: 0.3pt solid black;\n}\n.material-item-column-1 {\n flex-basis: 7000pt;\n padding-right: 2pt;\n}\n.material-item-column-2 {\n flex-basis: 3000pt;\n padding-left: 2pt;\n}\n \n","\n \n \n \n \n \n \n \n\n\n \n","\n \n \n\n \n {{ entry.checklist.name }} \n \n \n {{ item.number }} \n \n \n {{ item.text }} \n \n \n \n \n \n\n\n\n\n\n.checklist {\n display: flex;\n flex-direction: column;\n margin-bottom:8pt;\n}\n.checklist-title{\n font-weight:bold;\n margin-bottom:3pt;\n margin-top:2pt;\n}\n.checklist-item {\n display: flex;\n flex-direction: row;\n padding-bottom:5pt;\n}\n.checklist-item-column {\n flex-grow: 1;\n}\n.checklist-item-column-1 {\n flex-basis: 17pt;\n flex-shrink: 0;\n flex-grow: 0;\n padding-right: 2pt;\n font-variant-numeric: tabular-nums;\n}\n.checklist-item-column-2 {\n flex-basis: 0;\n flex-grow: 1;\n padding-left: 2pt;\n}\n \n","\n \n {{ contentTypeName }} \n \n\n\n.content-node {\n margin-bottom: 6pt;\n}\n \n","\n \n \n \n \n \n\n\n \n","\n {{ $t('print.program.title') }}: {{ period.description }} \n \n \n\n\n.program-period-title {\n font-size: 10pt;\n font-weight: bold;\n text-align: center;\n}\n \n","\n \n \n \n \n\n\n.program-page {\n font-size: 8pt;\n}\n \n","\n \n \n \n \n\n\n.activity-page {\n font-size: 8pt;\n}\n \n","\n \n\n \n \n \n \n\n\n \n","\n {{ title }}: {{ period.description }} \n \n \n\n\n.activity-list-period-title {\n font-size: 10pt;\n font-weight: bold;\n text-align: center;\n}\n \n","\n \n \n \n \n\n","\n \n \n \n \n \n \n\n\n.page {\n font-family: InterDisplay;\n padding: 30;\n font-size: 12;\n display: flex;\n flex-direction: column;\n}\n.h1 {\n font-size: 16;\n font-weight: semibold;\n margin: 12pt 0 3pt;\n}\n.h2 {\n font-size: 14;\n font-weight: semibold;\n margin: 10pt 0 3pt;\n}\n.h3 {\n font-size: 12;\n font-weight: semibold;\n margin: 8pt 0 3pt;\n}\n \n","import { pdf } from './renderer/index.js'\nimport CampPrint, { prepare } from './CampPrint.vue'\n\nconst render = (props = {}) => pdf(CampPrint, props)\nexport { render, prepare }\n"],"names":["key","remove","map","i","hasOwnProperty","c","s","n","isRef","e","computed","self","readonly","r","watch","a","version","ref","render","h","t","nextSibling","setScopeId","effect","remove2","isModelListener","emit","render2","app","resolve","rules","_sfc_main","_hoisted_2","_hoisted_4","_hoisted_5","_createElementBlock","_createElementVNode","_openBlock","_hoisted_3","_toDisplayString","_Fragment","_renderList","responsible","ProgramPeriod","_createBlock","Picasso","Program","Activity","SafetyConsiderations","Story","_hoisted_1","_resolveDynamicComponent","times","dayjs","userDisplayName","_normalizeStyle","contrastColor","_normalizeClass","_createVNode","gaps","dayStart","dayEnd","ScheduleEntry","_hoisted_6","_hoisted_9","_hoisted_10","_hoisted_7","_hoisted_8","_hoisted_11","u","__assign","rule","HTML","contentNodeComponent","setContentNodeComponent","setContentNodeComponentColumn","setContentNodeComponentDefault","Cover"],"mappings":"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","x_google_ignoreList":[2,3,4,9,49,50,51,52,53,54]}
\ No newline at end of file
diff --git a/frontend-vue3/src/pdf/prepareInMainThread.js b/frontend-vue3/src/pdf/prepareInMainThread.js
new file mode 100644
index 0000000000..32f8d8e756
--- /dev/null
+++ b/frontend-vue3/src/pdf/prepareInMainThread.js
@@ -0,0 +1,81 @@
+async function prepareInMainThread(config) {
+ const picassoData = (config2) => {
+ const camp = config2.apiGet(config2.camp);
+ return [
+ camp._meta.load,
+ camp.categories().$loadItems(),
+ camp.activities().$loadItems().then((activities) => {
+ return Promise.all(
+ activities.items.map((activity) => {
+ return activity.activityResponsibles().$loadItems();
+ })
+ );
+ }),
+ camp.campCollaborations().$loadItems().then((campCollaborations) => {
+ return Promise.all(
+ campCollaborations.items.map((campCollaboration) => {
+ return campCollaboration.user ? campCollaboration.user()._meta.load : Promise.resolve();
+ })
+ );
+ }),
+ camp.periods().$loadItems().then((periods) => {
+ return Promise.all(
+ periods.items.map((period) => {
+ return Promise.all([
+ period.scheduleEntries().$loadItems(),
+ period.contentNodes().$loadItems(),
+ period.days().$loadItems(),
+ period.dayResponsibles().$loadItems()
+ ]);
+ })
+ );
+ }),
+ camp.profiles().$loadItems()
+ ];
+ };
+ const activityData = (config2) => {
+ if (!config2.contents.some(
+ (c) => ["Program", "Activity", "ActivityList"].includes(c.type)
+ )) {
+ return [];
+ }
+ const camp = config2.apiGet(config2.camp);
+ return [
+ camp._meta.load,
+ camp.categories().$loadItems(),
+ camp.activities().$loadItems().then((activities) => {
+ return Promise.all(
+ activities.items.map((activity) => {
+ return activity.activityResponsibles().$loadItems();
+ })
+ );
+ }),
+ camp.campCollaborations().$loadItems().then((campCollaboration) => {
+ return campCollaboration.user ? campCollaboration.user()._meta.load : Promise.resolve();
+ }),
+ camp.periods().$loadItems().then((periods) => {
+ return Promise.all(
+ periods.items.map((period) => {
+ return Promise.all([
+ period.scheduleEntries().$loadItems(),
+ period.contentNodes().$loadItems()
+ ]);
+ })
+ );
+ }),
+ camp.materialLists().$loadItems(),
+ config2.apiGet().contentTypes().$loadItems(),
+ camp.checklists().$loadItems(),
+ config2.apiGet().checklistItems({
+ "checklist.camp": camp._meta.self
+ }).$loadItems()
+ ];
+ };
+ const loadData = async (config2) => {
+ return Promise.all([...picassoData(config2), ...activityData(config2)]);
+ };
+ return await loadData(config);
+}
+export {
+ prepareInMainThread
+};
diff --git a/frontend-vue3/src/pdf/prepareInMainThread.js.dist b/frontend-vue3/src/pdf/prepareInMainThread.js.dist
new file mode 100644
index 0000000000..0ac90f6697
--- /dev/null
+++ b/frontend-vue3/src/pdf/prepareInMainThread.js.dist
@@ -0,0 +1,8 @@
+// This file will be replaced with generated code by the pdf build service.
+
+async function prepareInMainThread(config) {
+ throw new Error('Clientside PDF generation code is not ready yet. Please ensure that @ecamp3/client-pdf has been built without any compiler errors.');
+}
+export {
+ prepareInMainThread
+};
diff --git a/frontend-vue3/src/pdf/prepareInMainThread.js.map b/frontend-vue3/src/pdf/prepareInMainThread.js.map
new file mode 100644
index 0000000000..06799768a3
--- /dev/null
+++ b/frontend-vue3/src/pdf/prepareInMainThread.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"prepareInMainThread.js","sources":["../src/prepareInMainThread.js"],"sourcesContent":["export async function prepareInMainThread(config) {\n const picassoData = (config) => {\n const camp = config.apiGet(config.camp)\n\n return [\n camp._meta.load,\n camp.categories().$loadItems(),\n camp\n .activities()\n .$loadItems()\n .then((activities) => {\n return Promise.all(\n activities.items.map((activity) => {\n return activity.activityResponsibles().$loadItems()\n })\n )\n }),\n camp\n .campCollaborations()\n .$loadItems()\n .then((campCollaborations) => {\n return Promise.all(\n campCollaborations.items.map((campCollaboration) => {\n return campCollaboration.user\n ? campCollaboration.user()._meta.load\n : Promise.resolve()\n })\n )\n }),\n camp\n .periods()\n .$loadItems()\n .then((periods) => {\n return Promise.all(\n periods.items.map((period) => {\n return Promise.all([\n period.scheduleEntries().$loadItems(),\n period.contentNodes().$loadItems(),\n period.days().$loadItems(),\n period.dayResponsibles().$loadItems(),\n ])\n })\n )\n }),\n camp.profiles().$loadItems(),\n ]\n }\n\n const activityData = (config) => {\n if (\n !config.contents.some((c) =>\n ['Program', 'Activity', 'ActivityList'].includes(c.type)\n )\n ) {\n return []\n }\n\n const camp = config.apiGet(config.camp)\n\n return [\n camp._meta.load,\n camp.categories().$loadItems(),\n camp\n .activities()\n .$loadItems()\n .then((activities) => {\n return Promise.all(\n activities.items.map((activity) => {\n return activity.activityResponsibles().$loadItems()\n })\n )\n }),\n camp\n .campCollaborations()\n .$loadItems()\n .then((campCollaboration) => {\n return campCollaboration.user\n ? campCollaboration.user()._meta.load\n : Promise.resolve()\n }),\n camp\n .periods()\n .$loadItems()\n .then((periods) => {\n return Promise.all(\n periods.items.map((period) => {\n return Promise.all([\n period.scheduleEntries().$loadItems(),\n period.contentNodes().$loadItems(),\n ])\n })\n )\n }),\n camp.materialLists().$loadItems(),\n config.apiGet().contentTypes().$loadItems(),\n camp.checklists().$loadItems(),\n config\n .apiGet()\n .checklistItems({\n 'checklist.camp': camp._meta.self,\n })\n .$loadItems(),\n ]\n }\n\n const loadData = async (config) => {\n // Load any data necessary based on the print config\n return Promise.all([...picassoData(config), ...activityData(config)])\n }\n\n return await loadData(config)\n}\n"],"names":["config"],"mappings":"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"}
\ No newline at end of file
diff --git a/frontend-vue3/src/plugins/__tests__/auth.spec.js b/frontend-vue3/src/plugins/__tests__/auth.spec.js
new file mode 100644
index 0000000000..f384e6deda
--- /dev/null
+++ b/frontend-vue3/src/plugins/__tests__/auth.spec.js
@@ -0,0 +1,420 @@
+import { describe, beforeEach, afterEach, vi, expect, it } from 'vitest'
+import Vue from 'vue'
+import { auth } from '@/plugins/auth'
+import Cookies from 'js-cookie'
+import cloneDeep from 'lodash-es/cloneDeep'
+import { getEnv } from '@/environment'
+
+const storePlugin = await vi.importActual('@/plugins/store')
+const storeLoader = storePlugin.default
+
+Vue.use(storeLoader)
+
+const store = storePlugin.store
+const apiStore = storePlugin.apiStore
+
+// expired on 01-01-1970
+const expiredJWTPayload =
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2MzMxMzM0MDksImV4cCI6MCwicm9sZXMiOlsiUk9MRV9VU0VSIl0sInVzZXJuYW1lIjoidGVzdC11c2VyIiwidXNlciI6Ii91c2Vycy8xYTJiM2M0ZCJ9'
+// {
+// "iat": 1633133409,
+// "exp": 0,
+// "roles": [
+// "ROLE_USER"
+// ],
+// "username": "test-user",
+// "user": "/users/1a2b3c4d"
+// }
+
+// expires on 01-01-3021, yes you read that right
+const validJWTPayload =
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2MzMxMzM0MDksImV4cCI6MzMxNjYzNjQ0MDAsInJvbGVzIjpbIlJPTEVfVVNFUiJdLCJ1c2VybmFtZSI6InRlc3QtdXNlciIsInVzZXIiOiIvdXNlcnMvMWEyYjNjNGQifQ'
+// {
+// "iat": 1633133409,
+// "exp": 33166364400,
+// "roles": [
+// "ROLE_USER"
+// ],
+// "username": "test-user",
+// "user": "/users/1a2b3c4d"
+// }
+
+const envBackup = cloneDeep(getEnv())
+
+expect.extend({
+ haveUri(actual, expectedUri) {
+ return {
+ pass: actual === expectedUri || actual._meta.self === expectedUri,
+ message: () => "expected to have the URI '" + expectedUri + "'",
+ }
+ },
+})
+
+vi.mock('@/router', async () => {
+ return {
+ default: {
+ push: () => Promise.resolve(),
+ resolve: () => ({
+ href: '/loginCallback',
+ }),
+ },
+ }
+})
+
+describe('authentication logic', () => {
+ afterEach(() => {
+ vi.restoreAllMocks()
+ Cookies.remove('localhost_jwt_hp')
+ window.environment = cloneDeep(envBackup)
+ })
+
+ describe('isLoggedIn()', () => {
+ it('returns true if JWT payload is not expired', () => {
+ // given
+ store.replaceState(createState())
+ Cookies.set('localhost_jwt_hp', validJWTPayload)
+
+ // when
+ const result = auth.isLoggedIn()
+
+ // then
+ expect(result).toBeTruthy()
+ })
+
+ it('returns false if JWT payload is expired', () => {
+ // given
+ store.replaceState(createState())
+ Cookies.set('localhost_jwt_hp', expiredJWTPayload)
+
+ // when
+ const result = auth.isLoggedIn()
+
+ // then
+ expect(result).toBeFalsy()
+ })
+
+ it('returns false if JWT cookie is missing', () => {
+ // given
+ store.replaceState(createState())
+ Cookies.set('localhost_jwt_hp', expiredJWTPayload)
+
+ // when
+ const result = auth.isLoggedIn()
+
+ // then
+ expect(result).toBeFalsy()
+ })
+ })
+
+ describe('register()', () => {
+ it('sends a POST request to the API', async () => {
+ // given
+ store.replaceState(createState())
+ vi.spyOn(apiStore, 'post').mockImplementation(async () => {})
+
+ // when
+ await auth.register({ email: 'bar', password: 'baz' })
+
+ // then
+ expect(apiStore.post).toHaveBeenCalledTimes(1)
+ expect(apiStore.post).toHaveBeenCalledWith('/users', {
+ email: 'bar',
+ password: 'baz',
+ })
+ })
+ })
+
+ describe('login()', () => {
+ it('resolves to true if the user successfully logs in', async () => {
+ // given
+ store.replaceState(createState())
+ vi.spyOn(apiStore, 'post').mockImplementation(async () => {
+ Cookies.set('localhost_jwt_hp', validJWTPayload)
+ })
+
+ // when
+ const result = await auth.login('foo', 'bar')
+
+ // then
+ expect(result).toBeTruthy()
+ expect(apiStore.post).toHaveBeenCalledTimes(1)
+ expect(apiStore.post).toHaveBeenCalledWith('/authentication_token', {
+ identifier: 'foo',
+ password: 'bar',
+ })
+ })
+
+ it('resolves to false if the login fails', async () => {
+ // given
+ vi.spyOn(apiStore, 'post').mockImplementation(async () => {
+ // login fails, no cookie added
+ })
+
+ // when
+ const result = await auth.login('foo', 'barrrr')
+
+ // then
+ expect(result).toBeFalsy()
+ expect(apiStore.post).toHaveBeenCalledTimes(1)
+ expect(apiStore.post).toHaveBeenCalledWith('/authentication_token', {
+ identifier: 'foo',
+ password: 'barrrr',
+ })
+ })
+ })
+
+ describe('loadUser()', () => {
+ it('resolves to null if not logged in', async () => {
+ // given
+ store.replaceState(createState())
+ vi.spyOn(apiStore, 'get')
+
+ // when
+ const result = await auth.loadUser()
+
+ // then
+ expect(result).toEqual(null)
+ expect(apiStore.get).toHaveBeenCalledTimes(0)
+ })
+
+ it('resolves to the user from the JWT token cookie', async () => {
+ // given
+ store.replaceState(createState())
+ Cookies.set('localhost_jwt_hp', validJWTPayload)
+ const rootEndpointGet = await apiStore.get()
+ vi.spyOn(rootEndpointGet, 'profiles')
+ vi.spyOn(apiStore, 'get').mockImplementation(() => rootEndpointGet)
+
+ // when
+ const result = await auth.loadUser()
+
+ // then
+ expect(result.id).toEqual('1a2b3c4d')
+ expect(rootEndpointGet.profiles).toHaveBeenCalledTimes(1)
+ expect(rootEndpointGet.profiles).toHaveBeenCalledWith({ user: '/users/1a2b3c4d' })
+ })
+
+ it.each([[401], [403], [404]])(
+ 'calls logout when fetching the user fails with status %s',
+ async (status) => {
+ // given
+ store.replaceState(createState())
+ Cookies.set('localhost_jwt_hp', validJWTPayload)
+
+ const rootEndpointGet = await apiStore.get()
+ vi.spyOn(rootEndpointGet, 'profiles').mockImplementation(() => ({
+ _meta: {
+ load: new Promise(() => {
+ const error = new Error('test error')
+ error.response = { status }
+ throw error
+ }),
+ },
+ }))
+ vi.spyOn(apiStore, 'get').mockImplementation(() => rootEndpointGet)
+ vi.spyOn(auth, 'logout')
+
+ // when
+ const result = await auth.loadUser()
+
+ // then
+ expect(result).toEqual(null)
+ expect(rootEndpointGet.profiles).toHaveBeenCalledTimes(1)
+ expect(rootEndpointGet.profiles).toHaveBeenCalledWith({ user: '/users/1a2b3c4d' })
+ expect(auth.logout).toHaveBeenCalledTimes(1)
+ }
+ )
+ })
+
+ describe('loginGoogle()', () => {
+ const { location } = window
+ beforeEach(() => {
+ delete window.location
+ window.location = {
+ origin: 'http://localhost',
+ href: 'http://localhost/login',
+ }
+ store.replaceState(createState())
+ })
+ afterEach(() => {
+ window.location = location
+ })
+
+ it('forwards to google authentication endpoint', async () => {
+ // when
+ await auth.loginGoogle()
+
+ // then
+ expect(window.location.href).toBe(
+ '/auth/google?callback=http%3A%2F%2Flocalhost%2FloginCallback'
+ )
+ })
+ })
+
+ describe('loginPbsMiData()', () => {
+ const { location } = window
+ beforeEach(() => {
+ delete window.location
+ window.location = {
+ origin: 'http://localhost',
+ href: 'http://localhost/login',
+ }
+ store.replaceState(createState())
+ })
+ afterEach(() => {
+ window.location = location
+ })
+
+ it('forwards to pbsmidata authentication endpoint', async () => {
+ // when
+ await auth.loginPbsMiData()
+
+ // then
+ expect(window.location.href).toBe(
+ '/auth/pbsmidata?callback=http%3A%2F%2Flocalhost%2FloginCallback'
+ )
+ })
+ })
+
+ describe('loginCeviDB()', () => {
+ const { location } = window
+ beforeEach(() => {
+ delete window.location
+ window.location = {
+ origin: 'http://localhost',
+ href: 'http://localhost/login',
+ }
+ store.replaceState(createState())
+ })
+ afterEach(() => {
+ window.location = location
+ })
+
+ it('forwards to cevidb authentication endpoint', async () => {
+ // when
+ await auth.loginCeviDB()
+
+ // then
+ expect(window.location.href).toBe(
+ '/auth/cevidb?callback=http%3A%2F%2Flocalhost%2FloginCallback'
+ )
+ })
+ })
+
+ describe('loginJublaDB()', () => {
+ const { location } = window
+ beforeEach(() => {
+ delete window.location
+ window.location = {
+ origin: 'http://localhost',
+ href: 'http://localhost/login',
+ }
+ store.replaceState(createState())
+ })
+ afterEach(() => {
+ window.location = location
+ })
+
+ it('forwards to jubladb authentication endpoint', async () => {
+ // when
+ await auth.loginJublaDB()
+
+ // then
+ expect(window.location.href).toBe(
+ '/auth/jubladb?callback=http%3A%2F%2Flocalhost%2FloginCallback'
+ )
+ })
+ })
+
+ describe('logout()', () => {
+ it('resolves to false if the user successfully logs out', async () => {
+ // given
+ Cookies.set('localhost_jwt_hp', validJWTPayload)
+
+ // when
+ const result = await auth.logout()
+
+ // then
+ expect(result).toBeFalsy()
+ })
+ })
+})
+
+function createState(authState = {}) {
+ return {
+ auth: {
+ user: null,
+ },
+ api: {
+ '': {
+ ...authState,
+ users: {
+ href: '/users',
+ },
+ login: {
+ href: '/authentication_token',
+ },
+ profiles: {
+ href: '/profiles{?user}',
+ templated: true,
+ },
+ oauthGoogle: {
+ href: '/auth/google{?callback}',
+ templated: true,
+ },
+ oauthPbsmidata: {
+ href: '/auth/pbsmidata{?callback}',
+ templated: true,
+ },
+ oauthCevidb: {
+ href: '/auth/cevidb{?callback}',
+ templated: true,
+ },
+ oauthJubladb: {
+ href: '/auth/jubladb{?callback}',
+ templated: true,
+ },
+ _meta: {
+ self: '',
+ },
+ },
+ '/users/1a2b3c4d': {
+ id: '1a2b3c4d',
+ profile: {
+ href: '/profile/5c6c7c8',
+ },
+ _meta: {
+ load: Promise.resolve({
+ id: '1a2b3c4d',
+ }),
+ },
+ },
+ '/profile/5c6c7c8': {
+ id: '5c6c7c8',
+ user: { href: '/users/1a2b3c4d' },
+ _meta: {
+ load: Promise.resolve({
+ id: '5c6c7c8',
+ user: { href: '/users/1a2b3c4d' },
+ }),
+ },
+ },
+ '/profiles?user=%2Fusers%2F1a2b3c4d': {
+ _meta: {
+ load: Promise.resolve({
+ items: [
+ {
+ href: '/profile/5c6c7c8',
+ },
+ ],
+ }),
+ },
+ items: [
+ {
+ href: '/profile/5c6c7c8',
+ },
+ ],
+ },
+ },
+ }
+}
diff --git a/frontend-vue3/src/plugins/__tests__/preferences.spec.js b/frontend-vue3/src/plugins/__tests__/preferences.spec.js
new file mode 100644
index 0000000000..607ef8253d
--- /dev/null
+++ b/frontend-vue3/src/plugins/__tests__/preferences.spec.js
@@ -0,0 +1,450 @@
+import { describe, beforeEach, afterEach, expect, it } from 'vitest'
+import { getters, loadFromLocalStorage, mutations } from '@/plugins/store/preferences'
+
+const CAMP_URI = '/camps/1a2b3c4d'
+
+let originalLocalStorage
+beforeEach(() => {
+ originalLocalStorage = window.localStorage
+ window.localStorage = (() => {
+ let store = {}
+
+ return {
+ getItem: (key) => store[key] ?? null,
+ setItem: (key, value) => {
+ store[key] = value?.toString() ?? 'undefined'
+ },
+ removeItem: (key) => {
+ delete store[key]
+ },
+ clear: () => {
+ store = {}
+ },
+ key: () => '',
+ length: Object.keys(store).length,
+ }
+ })()
+})
+
+afterEach(() => {
+ window.localStorage = originalLocalStorage
+})
+
+describe('reading state', () => {
+ it('loads saved picasso edit mode true', async () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:picassoEditMode`]: 'true',
+ })
+
+ // when
+ const result = getters.getPicassoEditMode(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeTruthy()
+ })
+
+ it('loads saved picasso edit mode false', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:picassoEditMode`]: 'false',
+ })
+
+ // when
+ const result = getters.getPicassoEditMode(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeFalsy()
+ })
+
+ it('falls back to false for picasso edit mode', () => {
+ // given
+ const state = loadFromLocalStorage({})
+
+ // when
+ const result = getters.getPicassoEditMode(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeFalsy()
+ })
+
+ it('handles invalid data for picasso edit mode', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:picassoEditMode`]: 'invalid json',
+ })
+
+ // when
+ const result = getters.getPicassoEditMode(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeFalsy()
+ })
+
+ it('loads saved story context edit mode true', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:storyContextEditMode`]: 'true',
+ })
+
+ // when
+ const result = getters.getStoryContextEditMode(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeTruthy()
+ })
+
+ it('loads saved story context edit mode false', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:storyContextEditMode`]: 'false',
+ })
+
+ // when
+ const result = getters.getStoryContextEditMode(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeFalsy()
+ })
+
+ it('falls back to false for story context edit mode', () => {
+ // given
+ const state = loadFromLocalStorage({})
+
+ // when
+ const result = getters.getStoryContextEditMode(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeFalsy()
+ })
+
+ it('handles invalid data for story context edit mode', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:storyContextEditMode`]: 'invalid json',
+ })
+
+ // when
+ const result = getters.getStoryContextEditMode(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeFalsy()
+ })
+
+ it('loads saved paper display size true', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:paperDisplaySize`]: 'true',
+ })
+
+ // when
+ const result = getters.getPaperDisplaySize(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeTruthy()
+ })
+
+ it('loads saved paper display size false', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:paperDisplaySize`]: 'false',
+ })
+
+ // when
+ const result = getters.getPaperDisplaySize(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeFalsy()
+ })
+
+ it('falls back to true for paper display size', () => {
+ // given
+ const state = loadFromLocalStorage({})
+
+ // when
+ const result = getters.getPaperDisplaySize(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeTruthy()
+ })
+
+ it('handles invalid data for paper display size', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:paperDisplaySize`]: 'invalid json',
+ })
+
+ // when
+ const result = getters.getPaperDisplaySize(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toBeTruthy()
+ })
+
+ it('loads saved print config undefined', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:lastPrintConfig`]: 'undefined',
+ })
+
+ // when
+ const result = getters.getLastPrintConfig(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toEqual({})
+ })
+
+ it('loads saved print config empty object', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:lastPrintConfig`]: '{}',
+ })
+
+ // when
+ const result = getters.getLastPrintConfig(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toEqual({})
+ })
+
+ it('loads saved print config with contents', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:lastPrintConfig`]: '{"lang":"de"}',
+ })
+
+ // when
+ const result = getters.getLastPrintConfig(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toEqual({
+ lang: 'de',
+ })
+ })
+
+ it('handles invalid data for print config', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:lastPrintConfig`]: 'invalid json',
+ })
+
+ // when
+ const result = getters.getLastPrintConfig(state)('/camps/1a2b3c4d')
+
+ // then
+ expect(result).toEqual({})
+ })
+})
+
+describe('writing state', () => {
+ it('saves picasso edit mode true', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:picassoEditMode`]: 'false',
+ })
+
+ // when
+ mutations.setPicassoEditMode(state, { campUri: '/camps/1a2b3c4d', editMode: true })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].picassoEditMode).toBeTruthy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:picassoEditMode`)
+ ).toEqual('true')
+ })
+
+ it('saves picasso edit mode false', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:picassoEditMode`]: 'true',
+ })
+
+ // when
+ mutations.setPicassoEditMode(state, { campUri: '/camps/1a2b3c4d', editMode: false })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].picassoEditMode).toBeFalsy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:picassoEditMode`)
+ ).toEqual('false')
+ })
+
+ it('saves picasso edit mode when previously not saved', () => {
+ // given
+ const state = loadFromLocalStorage({})
+
+ // when
+ mutations.setPicassoEditMode(state, { campUri: '/camps/1a2b3c4d', editMode: true })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].picassoEditMode).toBeTruthy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:picassoEditMode`)
+ ).toEqual('true')
+ })
+
+ it('saves story context edit mode true', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:storyContextEditMode`]: 'false',
+ })
+
+ // when
+ mutations.setStoryContextEditMode(state, {
+ campUri: '/camps/1a2b3c4d',
+ editMode: true,
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].storyContextEditMode).toBeTruthy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:storyContextEditMode`)
+ ).toEqual('true')
+ })
+
+ it('saves story context edit mode false', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:storyContextEditMode`]: 'true',
+ })
+
+ // when
+ mutations.setStoryContextEditMode(state, {
+ campUri: '/camps/1a2b3c4d',
+ editMode: false,
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].storyContextEditMode).toBeFalsy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:storyContextEditMode`)
+ ).toEqual('false')
+ })
+
+ it('saves story context edit mode when previously not saved', () => {
+ // given
+ const state = loadFromLocalStorage({})
+
+ // when
+ mutations.setStoryContextEditMode(state, {
+ campUri: '/camps/1a2b3c4d',
+ editMode: true,
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].storyContextEditMode).toBeTruthy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:storyContextEditMode`)
+ ).toEqual('true')
+ })
+
+ it('saves paper display size false', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:paperDisplaySize`]: 'true',
+ })
+
+ // when
+ mutations.setPaperDisplaySize(state, {
+ campUri: '/camps/1a2b3c4d',
+ paperDisplaySize: false,
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].paperDisplaySize).toBeFalsy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:paperDisplaySize`)
+ ).toEqual('false')
+ })
+
+ it('saves paper display size true', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:paperDisplaySize`]: 'false',
+ })
+
+ // when
+ mutations.setPaperDisplaySize(state, {
+ campUri: '/camps/1a2b3c4d',
+ paperDisplaySize: true,
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].paperDisplaySize).toBeTruthy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:paperDisplaySize`)
+ ).toEqual('true')
+ })
+
+ it('saves paper display size when previously not saved', () => {
+ // given
+ const state = loadFromLocalStorage({})
+
+ // when
+ mutations.setPaperDisplaySize(state, {
+ campUri: '/camps/1a2b3c4d',
+ paperDisplaySize: false,
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].paperDisplaySize).toBeFalsy()
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:paperDisplaySize`)
+ ).toEqual('false')
+ })
+
+ it('saves print config with content', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:lastPrintConfig`]: '{}',
+ })
+
+ // when
+ mutations.setLastPrintConfig(state, {
+ campUri: '/camps/1a2b3c4d',
+ printConfig: { lang: 'de' },
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].lastPrintConfig).toEqual({ lang: 'de' })
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:lastPrintConfig`)
+ ).toEqual('{"lang":"de"}')
+ })
+
+ it('saves print config undefined', () => {
+ // given
+ const state = loadFromLocalStorage({
+ [`preferences:${CAMP_URI}:lastPrintConfig`]: '{}',
+ })
+
+ // when
+ mutations.setLastPrintConfig(state, {
+ campUri: '/camps/1a2b3c4d',
+ printConfig: undefined,
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].lastPrintConfig).toEqual(undefined)
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:lastPrintConfig`)
+ ).toEqual('undefined')
+ })
+
+ it('saves print config when previously not saved', () => {
+ // given
+ const state = loadFromLocalStorage({})
+
+ // when
+ mutations.setLastPrintConfig(state, {
+ campUri: '/camps/1a2b3c4d',
+ printConfig: { lang: 'de' },
+ })
+
+ // then
+ expect(state.preferences['/camps/1a2b3c4d'].lastPrintConfig).toEqual({ lang: 'de' })
+ expect(
+ window.localStorage.getItem(`preferences:${CAMP_URI}:lastPrintConfig`)
+ ).toEqual('{"lang":"de"}')
+ })
+})
diff --git a/frontend-vue3/src/plugins/auth.js b/frontend-vue3/src/plugins/auth.js
new file mode 100644
index 0000000000..e5c75057a5
--- /dev/null
+++ b/frontend-vue3/src/plugins/auth.js
@@ -0,0 +1,183 @@
+import axios from 'axios'
+import { apiStore, store } from '@/plugins/store'
+import router from '@/router'
+import Cookies from 'js-cookie'
+import { getEnv } from '@/environment.js'
+
+axios.interceptors.response.use(null, (error) => {
+ if (error.status === 401) {
+ logout().then(() => {})
+ }
+ return Promise.reject(error)
+})
+
+function getJWTPayloadFromCookie() {
+ const jwtHeaderAndPayload = Cookies.get(headerAndPayloadCookieName())
+ if (!jwtHeaderAndPayload) return ''
+
+ return jwtHeaderAndPayload.split('.')[1]
+}
+
+function parseJWTPayload(payload) {
+ if (!payload) return {}
+ const base64 = payload.replace(/-/g, '+').replace(/_/g, '/')
+ const jsonPayload = decodeURIComponent(
+ atob(base64)
+ .split('')
+ .map(function (c) {
+ return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
+ })
+ .join('')
+ )
+
+ return JSON.parse(jsonPayload)
+}
+
+function getJWTExpirationTimestamp() {
+ return (parseJWTPayload(getJWTPayloadFromCookie()).exp ?? 0) * 1000
+}
+
+export function isLoggedIn() {
+ const isLoggedIn = Date.now() < getJWTExpirationTimestamp()
+
+ // TODO: commented code creates an infinite-loop
+ // if (isLoggedIn) {
+ // loadUser()
+ // }
+
+ return isLoggedIn
+}
+
+export function isAdmin() {
+ if (!isLoggedIn()) {
+ return false
+ }
+
+ return parseJWTPayload(getJWTPayloadFromCookie()).roles.includes('ROLE_ADMIN')
+}
+
+async function login(email, password) {
+ const url = await apiStore.href(apiStore.get(), 'login')
+ return apiStore.post(url, { identifier: email, password: password }).then(() => {
+ return isLoggedIn()
+ })
+}
+
+async function resetPasswordRequest(email, recaptchaToken) {
+ const url = await apiStore.href(apiStore.get(), 'resetPassword')
+ return apiStore.post(url, { email: email, recaptchaToken: recaptchaToken })
+}
+
+async function resetPassword(id, password, recaptchaToken) {
+ const url = await apiStore.href(apiStore.get(), 'resetPassword', { id: id })
+ return apiStore.patch(url, { password: password, recaptchaToken: recaptchaToken })
+}
+
+async function loadUser() {
+ if (!getJWTPayloadFromCookie()) {
+ store.commit('logout')
+ return null
+ }
+
+ try {
+ const user = await apiStore.get(parseJWTPayload(getJWTPayloadFromCookie()).user)._meta
+ .load
+ // store.commit('login', user)
+ return user
+ } catch (e) {
+ if (e.response && [401, 403, 404].includes(e.response.status)) {
+ // 401 means no complete token was submitted, so we may be missing the JWT signature cookie
+ // 403 means we can theoretically interact in some way with the user, but apparently not read it
+ // 404 means the user doesn't exist or we don't have access to it
+ // Either way, we aren't allowed to access the user from the token, so it's best to ask the user
+ // to log in again.
+ auth.logout()
+ return null
+ }
+
+ throw e
+ }
+}
+
+async function register(data) {
+ const url = await apiStore.href(apiStore.get(), 'users')
+ return apiStore.post(url, data)
+}
+
+async function redirectToOAuthLogin(provider) {
+ let returnUrl = window.location.origin + router.resolve({ name: 'loginCallback' }).href
+
+ const params = new URLSearchParams(window.location.search)
+ if (params.has('redirect')) {
+ returnUrl += '?redirect=' + params.get('redirect')
+ }
+
+ return apiStore
+ .href(apiStore.get(), provider, { callback: encodeURI(returnUrl) })
+ .then((url) => {
+ window.location.href = url
+ })
+}
+
+async function loginGoogle() {
+ return redirectToOAuthLogin('oauthGoogle')
+}
+
+async function loginPbsMiData() {
+ return redirectToOAuthLogin('oauthPbsmidata')
+}
+
+async function loginCeviDB() {
+ return redirectToOAuthLogin('oauthCevidb')
+}
+
+async function loginJublaDB() {
+ return redirectToOAuthLogin('oauthJubladb')
+}
+
+export async function logout() {
+ Cookies.remove(headerAndPayloadCookieName())
+ store.commit('logout')
+ return router
+ .push({ name: 'login' })
+ .catch(() => {}) // prevents throwing NavigationDuplicated is already on /login
+ .then(() => apiStore.purgeAll())
+ .then(() => isLoggedIn())
+}
+
+function headerAndPayloadCookieName() {
+ return `${cookiePrefix()}jwt_hp`
+}
+
+function cookiePrefix() {
+ return getEnv().COOKIE_PREFIX || ''
+}
+
+export const auth = {
+ isLoggedIn,
+ isAdmin,
+ login,
+ register,
+ loginGoogle,
+ loginPbsMiData,
+ loginCeviDB,
+ loginJublaDB,
+ logout,
+ loadUser,
+ resetPasswordRequest,
+ resetPassword,
+}
+
+class AuthPlugin {
+ install(app) {
+ Object.defineProperties(app.config.globalProperties, {
+ $auth: {
+ get() {
+ return auth
+ },
+ },
+ })
+ }
+}
+
+export default new AuthPlugin()
diff --git a/frontend-vue3/src/plugins/color.js b/frontend-vue3/src/plugins/color.js
new file mode 100644
index 0000000000..6633e6ba8d
--- /dev/null
+++ b/frontend-vue3/src/plugins/color.js
@@ -0,0 +1,7 @@
+import { ColorSpace, sRGB } from 'colorjs.io/fn'
+
+export default {
+ install: () => {
+ ColorSpace.register(sRGB)
+ },
+}
diff --git a/frontend-vue3/src/plugins/dayjs.js b/frontend-vue3/src/plugins/dayjs.js
new file mode 100644
index 0000000000..9f830125cd
--- /dev/null
+++ b/frontend-vue3/src/plugins/dayjs.js
@@ -0,0 +1,14 @@
+import dayjs from '@/common/helpers/dayjs.js'
+
+export default {
+ install: (app) => {
+ Object.defineProperties(app.config.globalProperties, {
+ $date: {
+ get() {
+ return dayjs
+ },
+ },
+ })
+ // Vue.dayjs = dayjs
+ },
+}
diff --git a/frontend-vue3/src/plugins/formBaseComponents.js b/frontend-vue3/src/plugins/formBaseComponents.js
new file mode 100644
index 0000000000..b2514f6f55
--- /dev/null
+++ b/frontend-vue3/src/plugins/formBaseComponents.js
@@ -0,0 +1,35 @@
+// Global registration of all Vue components in folder components/form/base
+
+import ECheckbox from '@/components/form/base/ECheckbox.vue'
+import EColorPicker from '@/components/form/base/EColorPicker.vue'
+import EColorField from '@/components/form/base/EColorField.vue'
+import EDatePicker from '@/components/form/base/EDatePicker.vue'
+import EForm from '@/components/form/base/EForm.vue'
+import ENumberField from '@/components/form/base/ENumberField.vue'
+import EParseField from '@/components/form/base/EParseField.vue'
+import ERichtext from '@/components/form/base/ERichtext.vue'
+import ESelect from '@/components/form/base/ESelect.vue'
+import ESwitch from '@/components/form/base/ESwitch.vue'
+import ETextarea from '@/components/form/base/ETextarea.vue'
+import ETextField from '@/components/form/base/ETextField.vue'
+import ETimePicker from '@/components/form/base/ETimePicker.vue'
+
+class FormBaseComponentsPlugin {
+ install(Vue) {
+ Vue.component('ECheckbox', ECheckbox)
+ Vue.component('EColorField', EColorField)
+ Vue.component('EColorPicker', EColorPicker)
+ Vue.component('EDatePicker', EDatePicker)
+ Vue.component('EForm', EForm)
+ Vue.component('ENumberField', ENumberField)
+ Vue.component('EParseField', EParseField)
+ Vue.component('ERichtext', ERichtext)
+ Vue.component('ESelect', ESelect)
+ Vue.component('ESwitch', ESwitch)
+ Vue.component('ETextarea', ETextarea)
+ Vue.component('ETextField', ETextField)
+ Vue.component('ETimePicker', ETimePicker)
+ }
+}
+
+export default new FormBaseComponentsPlugin()
diff --git a/frontend-vue3/src/plugins/head.js b/frontend-vue3/src/plugins/head.js
new file mode 100644
index 0000000000..87bdb48db6
--- /dev/null
+++ b/frontend-vue3/src/plugins/head.js
@@ -0,0 +1,24 @@
+import { createHead, useHead } from '@unhead/vue'
+export { UnheadPlugin as head } from '@unhead/vue/vue2'
+import { getEnv } from '@/environment.js'
+
+const env = getEnv().SENTRY_ENVIRONMENT.split('.')[0]
+const environment =
+ env === 'app' || env === ''
+ ? null
+ : env.match('^pr[0-9]+')
+ ? `[${env.toUpperCase()}]`
+ : `[${env.substring(0, 1).toUpperCase() + env.substring(1)}]`
+
+export const unhead = createHead()
+
+useHead({
+ title: null,
+ templateParams: {
+ site: 'eCamp v3',
+ separator: '·',
+ environment,
+ section: null,
+ },
+ titleTemplate: '%environment %s %separator %section %separator %site',
+})
diff --git a/frontend-vue3/src/plugins/i18n/__tests__/apiFallbackLocalesFor.spec.js b/frontend-vue3/src/plugins/i18n/__tests__/apiFallbackLocalesFor.spec.js
new file mode 100644
index 0000000000..0db9f116c0
--- /dev/null
+++ b/frontend-vue3/src/plugins/i18n/__tests__/apiFallbackLocalesFor.spec.js
@@ -0,0 +1,36 @@
+import { describe, expect, it } from 'vitest'
+import { fallbackLocales } from '@/plugins/i18n'
+import fallbackLocalesFor from '@/plugins/i18n/apiFallbackLocalesFor'
+
+const fallbackLocale = fallbackLocales.default
+
+describe('apiFallbackLocales', () => {
+ ;[null, undefined, 1, [], {}].forEach((param) => {
+ it(`returns fallbackLocale if input is not a string, but ${param}`, () => {
+ expect([...fallbackLocalesFor(param)]).toStrictEqual([fallbackLocale])
+ })
+
+ it('returns fallbackLocale if string does not contain dashes', () => {
+ expect([...fallbackLocalesFor('de')]).toStrictEqual([fallbackLocale])
+ })
+
+ Object.entries({
+ de_CH_scout: ['de_CH', 'de', fallbackLocale],
+ de_CH: ['de', fallbackLocale],
+ fr_CH_scout: ['fr_CH', 'fr', fallbackLocale],
+ fr_CH: ['fr', fallbackLocale],
+ it_CH_scout: ['it_CH', 'it', fallbackLocale],
+ it_CH: ['it', fallbackLocale],
+ en_CH_scout: ['en_CH', 'en', fallbackLocale],
+ en_CH: ['en', fallbackLocale],
+ rm_CH: ['rm', 'de', fallbackLocale],
+ rm_CH_scout: ['rm_CH', 'rm', 'de', fallbackLocale],
+ }).forEach((entry) => {
+ const locale = entry[0]
+ const result = entry[1]
+ it(`returns correct fallbacks [${result}] for locale ${locale}`, () => {
+ expect([...fallbackLocalesFor(locale)]).toStrictEqual(result)
+ })
+ })
+ })
+})
diff --git a/frontend-vue3/src/plugins/i18n/apiFallbackLocalesFor.js b/frontend-vue3/src/plugins/i18n/apiFallbackLocalesFor.js
new file mode 100644
index 0000000000..20767a0c5f
--- /dev/null
+++ b/frontend-vue3/src/plugins/i18n/apiFallbackLocalesFor.js
@@ -0,0 +1,24 @@
+import { fallbackLocales } from '@/plugins/i18n/index'
+
+export default function* (locale) {
+ if (typeof locale !== 'string') {
+ yield fallbackLocales.default
+ return
+ }
+ if (fallbackLocales[locale]) {
+ for (const fallback of fallbackLocales[locale]) {
+ yield fallback
+ }
+ }
+ const parts = locale.split('_')
+ for (let i = parts.length - 1; i > 0; i--) {
+ const implicitFallback = parts.slice(0, i).join('_')
+ yield implicitFallback
+ if (fallbackLocales[implicitFallback]) {
+ for (const fallback of fallbackLocales[implicitFallback]) {
+ yield fallback
+ }
+ }
+ }
+ yield fallbackLocales.default
+}
diff --git a/frontend-vue3/src/plugins/i18n/index.js b/frontend-vue3/src/plugins/i18n/index.js
new file mode 100644
index 0000000000..04fc01d0fc
--- /dev/null
+++ b/frontend-vue3/src/plugins/i18n/index.js
@@ -0,0 +1,104 @@
+import { createI18n } from 'vue-i18n'
+import deepmerge from 'deepmerge'
+
+import itCommon from '@/common/locales/it.json'
+import itCHScoutCommon from '@/common/locales/it-CH-scout.json'
+import frCommon from '@/common/locales/fr.json'
+import frCHScoutCommon from '@/common/locales/fr-CH-scout.json'
+import enCommon from '@/common/locales/en.json'
+import enCHScoutCommon from '@/common/locales/en-CH-scout.json'
+import deCommon from '@/common/locales/de.json'
+import deCHScoutCommon from '@/common/locales/de-CH-scout.json'
+import rmCommon from '@/common/locales/rm.json'
+import rmCHScoutCommon from '@/common/locales/rm-CH-scout.json'
+
+import it from '@/locales/it.json'
+import itCHScout from '@/locales/it-CH-scout.json'
+import fr from '@/locales/fr.json'
+import frCHScout from '@/locales/fr-CH-scout.json'
+import en from '@/locales/en.json'
+import enCHScout from '@/locales/en-CH-scout.json'
+import de from '@/locales/de.json'
+import deCHScout from '@/locales/de-CH-scout.json'
+import rm from '@/locales/rm.json'
+import rmCHScout from '@/locales/rm-CH-scout.json'
+
+// import validationIt from 'vee-validate/dist/locale/it.json'
+// import validationFr from 'vee-validate/dist/locale/fr.json'
+// import validationEn from 'vee-validate/dist/locale/en.json'
+// import validationDe from 'vee-validate/dist/locale/de.json'
+
+import vuetifyEn from 'vuetify/lib/locale/en'
+import vuetifyDe from 'vuetify/lib/locale/de'
+import vuetifyFr from 'vuetify/lib/locale/fr'
+import vuetifyIt from 'vuetify/lib/locale/it'
+
+const fallbackLocales = {
+ rm: ['de'],
+ default: 'en',
+}
+
+const i18n = createI18n({
+ locale: 'de',
+ fallbackLocale: fallbackLocales,
+ messages: deepmerge.all([
+ // vuetify locales
+ {
+ en: { $vuetify: vuetifyEn },
+ de: { $vuetify: vuetifyDe },
+ fr: { $vuetify: vuetifyFr },
+ it: { $vuetify: vuetifyIt },
+ },
+
+ // eCamp common locales
+ {
+ it: itCommon,
+ 'it-CH-scout': itCHScoutCommon,
+ fr: frCommon,
+ 'fr-CH-scout': frCHScoutCommon,
+ en: enCommon,
+ 'en-CH-scout': enCHScoutCommon,
+ de: deCommon,
+ 'de-CH-scout': deCHScoutCommon,
+ rm: rmCommon,
+ 'rm-CH-scout': rmCHScoutCommon,
+ },
+
+ // eCamp frontend only locales
+ {
+ it,
+ 'it-CH-scout': itCHScout,
+ fr,
+ 'fr-CH-scout': frCHScout,
+ en,
+ 'en-CH-scout': enCHScout,
+ de,
+ 'de-CH-scout': deCHScout,
+ rm,
+ 'rm-CH-scout': rmCHScout,
+ },
+ ]),
+ silentTranslationWarn: true,
+ silentFallbackWarn: true,
+})
+
+Object.defineProperty(i18n, 'browserPreferredLocale', {
+ get: function () {
+ const languages = navigator.languages || [navigator.language]
+ for (const language of languages) {
+ if (this.availableLocales.includes(language)) {
+ return language
+ }
+
+ const languageFallback = language.substring(0, 2)
+ if (this.availableLocales.includes(languageFallback)) {
+ return languageFallback
+ }
+ }
+ return fallbackLocales.default
+ },
+})
+
+export default i18n
+
+export { i18n, fallbackLocales }
diff --git a/frontend-vue3/src/plugins/ignoreNativeBindingWarnMessages.js b/frontend-vue3/src/plugins/ignoreNativeBindingWarnMessages.js
new file mode 100644
index 0000000000..825b9eba01
--- /dev/null
+++ b/frontend-vue3/src/plugins/ignoreNativeBindingWarnMessages.js
@@ -0,0 +1,24 @@
+/**
+ * Disables display of console warn messages related to .native event bindings
+ *
+ * See also here https://github.com/vuejs/vue/issues/10939
+ * and here https://github.com/vuetifyjs/vuetify/issues/9999
+ */
+class IgnoreNativeBindingWarnMessagesPlugin {
+ install(Vue) {
+ const ignoreWarnMessage =
+ 'The .native modifier for v-on is only valid on components but it was used on'
+ Vue.config.warnHandler = function (msg, vm, trace) {
+ // `trace` is the component hierarchy trace
+ if (msg.startsWith(ignoreWarnMessage)) {
+ msg = null
+ vm = null
+ trace = null
+ } else {
+ console.error(`[Vue warn]: ${msg}${trace}`)
+ }
+ }
+ }
+}
+
+export default new IgnoreNativeBindingWarnMessagesPlugin()
diff --git a/frontend-vue3/src/plugins/index.js b/frontend-vue3/src/plugins/index.js
new file mode 100644
index 0000000000..b7cd7383ee
--- /dev/null
+++ b/frontend-vue3/src/plugins/index.js
@@ -0,0 +1,9 @@
+export { default as vuetifyLoader } from './vuetify'
+export { default as storeLoader } from './store'
+export { default as auth } from './auth'
+export { default as formBaseComponents } from './formBaseComponents'
+export { default as ignoreNativeBindingWarnMessages } from './ignoreNativeBindingWarnMessages'
+export { default as i18n } from './i18n'
+export { default as veeValidate } from './veeValidate'
+export { default as dayjs } from './dayjs'
+export { default as color } from './color'
diff --git a/frontend-vue3/src/plugins/passwordStrength.js b/frontend-vue3/src/plugins/passwordStrength.js
new file mode 100644
index 0000000000..8fc0efbd11
--- /dev/null
+++ b/frontend-vue3/src/plugins/passwordStrength.js
@@ -0,0 +1,25 @@
+import { zxcvbnAsync, zxcvbnOptions } from '@zxcvbn-ts/core'
+import { adjacencyGraphs, dictionary } from '@zxcvbn-ts/language-common'
+import * as en from '@zxcvbn-ts/language-en'
+import * as de from '@zxcvbn-ts/language-de'
+import * as fr from '@zxcvbn-ts/language-fr'
+import * as it from '@zxcvbn-ts/language-it'
+
+const languages = { en, de, fr, it }
+
+const options = function (lang) {
+ const baseLanguage = lang.split('-', 2)[0]
+ return {
+ translations: languages[baseLanguage].translations,
+ graphs: adjacencyGraphs,
+ dictionary: {
+ ...dictionary,
+ ...languages[baseLanguage].dictionary,
+ },
+ }
+}
+
+export const passwordStrength = async function (password, lang) {
+ zxcvbnOptions.setOptions(options(lang))
+ return await zxcvbnAsync(password)
+}
diff --git a/frontend-vue3/src/plugins/slugify.js b/frontend-vue3/src/plugins/slugify.js
new file mode 100644
index 0000000000..944c485905
--- /dev/null
+++ b/frontend-vue3/src/plugins/slugify.js
@@ -0,0 +1,9 @@
+import slugify from 'slugify'
+
+slugify.extend({
+ '@': '(at)',
+ '.': ' ',
+ ':': ' ',
+})
+
+export { slugify }
diff --git a/frontend-vue3/src/plugins/store/auth.js b/frontend-vue3/src/plugins/store/auth.js
new file mode 100644
index 0000000000..560c2c8e0c
--- /dev/null
+++ b/frontend-vue3/src/plugins/store/auth.js
@@ -0,0 +1,30 @@
+import { apiStore } from '@/plugins/store/index'
+
+export const state = {
+ user: null,
+}
+
+export const mutations = {
+ login(state, user) {
+ state.user = user
+ },
+
+ logout(state) {
+ state.user = null
+ },
+}
+export const getters = {
+ /**
+ * Since store.auth.user isn't always up to date - uses the logged-in user URI and returns the latest data for that user
+ * @returns {*} the Logged-in user with the latest fetched api data
+ */
+ getLoggedInUser: (authState) => {
+ return authState.user ? apiStore.get(authState.user._meta.self) : authState.user
+ },
+}
+
+export default {
+ state,
+ mutations,
+ getters,
+}
diff --git a/frontend-vue3/src/plugins/store/index.js b/frontend-vue3/src/plugins/store/index.js
new file mode 100644
index 0000000000..26add3b008
--- /dev/null
+++ b/frontend-vue3/src/plugins/store/index.js
@@ -0,0 +1,47 @@
+import { createStore } from 'vuex'
+import axios from 'axios'
+import HalJsonVuex from 'hal-json-vuex'
+import lang from './lang'
+import auth from './auth'
+import preferences from './preferences'
+import { getEnv } from '@/environment.js'
+
+const debug = process.env.NODE_ENV !== 'production'
+
+export default {
+ install: (app, options) => {
+ store = createStore({
+ modules: {
+ lang,
+ auth,
+ preferences,
+ },
+ strict: false,
+ // plugins: debug ? [createLogger()] : [],
+ })
+
+ app.use(store)
+
+ const axiosInstance = axios.create({
+ withCredentials: true,
+ baseURL: getEnv().API_ROOT_URL,
+ headers: { common: { Accept: 'application/hal+json' } },
+ })
+ axiosInstance.interceptors.request.use(function (config) {
+ if (config.method === 'patch') {
+ config.headers['Content-Type'] = 'application/merge-patch+json'
+ }
+ return config
+ })
+
+ // create and inject API
+ apiStore = new HalJsonVuex(store, axiosInstance, {
+ forceRequestedSelfLink: true,
+ })
+
+ app.use(apiStore)
+ },
+}
+
+export let apiStore
+export let store
diff --git a/frontend-vue3/src/plugins/store/lang.js b/frontend-vue3/src/plugins/store/lang.js
new file mode 100644
index 0000000000..5437119d95
--- /dev/null
+++ b/frontend-vue3/src/plugins/store/lang.js
@@ -0,0 +1,37 @@
+import axios from 'axios'
+import VueI18n from '@/plugins/i18n'
+import { dayjsLocaleMap } from '@/common/helpers/dayjs.js'
+import dayjs from '@/common/helpers/dayjs.js'
+import { setLocale as veeValidateSetLocale } from '@vee-validate/i18n'
+
+const LANG_KEY = 'language'
+
+export const state = {
+ language: window.localStorage.getItem(LANG_KEY) || window.navigator.language || 'en',
+}
+
+export const mutations = {
+ /**
+ * Changes language
+ * @param state Vuex state
+ * @param lang Language string
+ */
+ setLanguage(state, lang) {
+ if (!lang) {
+ return
+ }
+
+ state.language = lang
+ VueI18n.global.locale = lang
+ dayjs.locale(Object.keys(dayjsLocaleMap).includes(lang) ? dayjsLocaleMap[lang] : lang)
+ //veeValidateSetLocale(lang.substring(0, 2))
+ axios.defaults.headers.common['Accept-Language'] = lang
+ document.querySelector('html').setAttribute('lang', lang)
+ window.localStorage.setItem(LANG_KEY, lang)
+ },
+}
+
+export default {
+ state,
+ mutations,
+}
diff --git a/frontend-vue3/src/plugins/store/preferences.js b/frontend-vue3/src/plugins/store/preferences.js
new file mode 100644
index 0000000000..219d80e7c2
--- /dev/null
+++ b/frontend-vue3/src/plugins/store/preferences.js
@@ -0,0 +1,96 @@
+import app from '../../main.js'
+
+const LOCAL_STORAGE_PREFIX = 'preferences:'
+
+export function loadFromLocalStorage(localStorage = window.localStorage) {
+ const values = {}
+ Object.keys(localStorage)
+ .filter((key) => key.startsWith(LOCAL_STORAGE_PREFIX))
+ .forEach((key) => {
+ try {
+ const [, uri, identifier] = key.match(
+ new RegExp(`^${LOCAL_STORAGE_PREFIX}(.*):(.*)$`)
+ )
+ values[uri] ||= {}
+ values[uri][identifier] = JSON.parse(localStorage[key])
+ } catch (error) {
+ // Just ignore this key and continue with the others
+ }
+ })
+ return {
+ preferences: values,
+ }
+}
+
+export const state = loadFromLocalStorage()
+
+export const getters = {
+ getPicassoEditMode: (state) => (campUri) => {
+ return !!(state.preferences[campUri]?.picassoEditMode ?? false)
+ },
+ getStoryContextEditMode: (state) => (campUri) => {
+ return !!(state.preferences[campUri]?.storyContextEditMode ?? false)
+ },
+ getPaperDisplaySize: (state) => (campUri) => {
+ return !!(state.preferences[campUri]?.paperDisplaySize ?? true)
+ },
+ getLastPrintConfig:
+ (state) =>
+ (campUri, fallback = {}) => {
+ return state.preferences[campUri]?.lastPrintConfig ?? fallback
+ },
+}
+
+function setPreferenceValue(state, campUri, identifier, value) {
+ if (!(campUri in state.preferences)) Vue.set(state.preferences, campUri, {})
+ app.set(state.preferences[campUri], identifier, value)
+ window.localStorage.setItem(
+ `${LOCAL_STORAGE_PREFIX}${campUri}:${identifier}`,
+ JSON.stringify(value)
+ )
+}
+
+export const mutations = {
+ /**
+ * Changes the edit mode of the picasso (locked or unlocked)
+ * @param state Vuex state
+ * @param campUri The URI of the camp to which this preference belongs
+ * @param editMode boolean value, true meaning unlocked, false meaning locked
+ */
+ setPicassoEditMode(state, { campUri, editMode }) {
+ setPreferenceValue(state, campUri, 'picassoEditMode', editMode)
+ },
+ /**
+ * Changes the edit mode of the story context overview (locked or unlocked)
+ * @param state Vuex state
+ * @param campUri The URI of the camp to which this preference belongs
+ * @param editMode boolean value, true meaning unlocked, false meaning locked
+ */
+ setStoryContextEditMode(state, { campUri, editMode }) {
+ setPreferenceValue(state, campUri, 'storyContextEditMode', editMode)
+ },
+ /**
+ * Changes the width of the displayed activity details between paper size and full-screen width
+ * @param state Vuex state
+ * @param campUri The URI of the camp to which this preference belongs
+ * @param paperDisplaySize boolean value, true meaning unlocked, false meaning locked
+ */
+ setPaperDisplaySize(state, { campUri, paperDisplaySize }) {
+ setPreferenceValue(state, campUri, 'paperDisplaySize', paperDisplaySize)
+ },
+ /**
+ * Remembers the last used PDF print settings
+ * @param state Vuex state
+ * @param campUri The URI of the camp to which this preference belongs
+ * @param printConfig an object describing the last used print configuration
+ */
+ setLastPrintConfig(state, { campUri, printConfig }) {
+ setPreferenceValue(state, campUri, 'lastPrintConfig', printConfig)
+ },
+}
+
+export default {
+ state,
+ getters,
+ mutations,
+}
diff --git a/frontend-vue3/src/plugins/veeValidate.js b/frontend-vue3/src/plugins/veeValidate.js
new file mode 100644
index 0000000000..4f68c84b23
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate.js
@@ -0,0 +1,52 @@
+import { configure, defineRule } from 'vee-validate'
+import { localize, setLocale } from '@vee-validate/i18n'
+import * as rules from '@vee-validate/rules'
+
+// import greaterThan_time from './veeValidate/greaterThan_time.js'
+// import greaterThanOrEqual_date from './veeValidate/greaterThanOrEqual_date.js'
+// import lessThanOrEqual_date from './veeValidate/lessThanOrEqual_date.js'
+// import oneEmojiOrTwoCharacters from '@/plugins/veeValidate/oneEmojiOrTwoCharacters.js'
+
+import it from '@vee-validate/i18n/dist/locale/it.json'
+import fr from '@vee-validate/i18n/dist/locale/fr.json'
+import en from '@vee-validate/i18n/dist/locale/en.json'
+import de from '@vee-validate/i18n/dist/locale/de.json'
+
+class VeeValidatePlugin {
+ install() {
+ // Eager = Lazy at the beginning, Agressive once the field is invalid (https://vee-validate.logaretm.com/v3/guide/interaction-and-ux.html#interaction-modes)
+ // setInteractionMode('eager')
+
+ configure({
+ // TODO: this is using localize from vee-validate instead of vue-i18n.
+ // vee-validate messages are not directly compatible with vue-i18n, so some message format change would be needed,
+ // if we want to use vue-i18n here (see alo https://github.com/logaretm/vee-validate/issues/3684).
+ // Not using vue-18n will break translation for our own custom validators below, so we still need to fix this.
+ generateMessage: localize({ en, de, fr, it }),
+ })
+
+ setLocale('en')
+
+ // install all default rules
+ Object.keys(rules).forEach((rule) => {
+ defineRule(rule, rules[rule])
+ })
+
+ /**
+ * define custom rules
+ */
+
+ // extend('greaterThan_time', greaterThan_time(Vue.dayjs, i18n))
+ //
+ // // check if date (value) is equal or larger than another date (min)
+ // extend('greaterThanOrEqual_date', greaterThanOrEqual_date(Vue.dayjs, i18n))
+ //
+ // // check if date (value) is equal or less than another date (max)
+ // extend('lessThanOrEqual_date', lessThanOrEqual_date(Vue.dayjs, i18n))
+ //
+ // // check if date (value) is equal or less than another date (max)
+ // extend('oneEmojiOrTwoCharacters', oneEmojiOrTwoCharacters(i18n))
+ }
+}
+
+export default new VeeValidatePlugin()
diff --git a/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThan.spec.js b/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThan.spec.js
new file mode 100644
index 0000000000..142fa136da
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThan.spec.js
@@ -0,0 +1,32 @@
+import { describe, expect, it } from 'vitest'
+import greaterThan from '@/plugins/veeValidate/greaterThan'
+
+const mockI18n = {
+ $tc: (key) => key,
+}
+
+describe('greaterThan validation', () => {
+ it.each([
+ [[1, { min: 0 }], true],
+ [['1', { min: 0 }], true],
+ [[0, { min: 0 }], false],
+ [[0.0001, { min: 0 }], true],
+ [['0.0001', { min: 0 }], true],
+ [[-0.0001, { min: 0 }], false],
+ [['-0.0001', { min: 0 }], false],
+ [[-0, { min: 0 }], false],
+ [[-1, { min: 0 }], false],
+ [[1e-10, { min: 0 }], true],
+ [[-1e-10, { min: 0 }], false],
+ [['not a number', { min: 0 }], false],
+ ])('validates %p as %p', (input, expected) => {
+ // given
+ const rule = greaterThan(mockI18n)
+
+ // when
+ const result = rule.validate(...input)
+
+ // then
+ expect(result).toBe(expected)
+ })
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThanOrEqual_date.spec.js b/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThanOrEqual_date.spec.js
new file mode 100644
index 0000000000..0a8fdd9595
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThanOrEqual_date.spec.js
@@ -0,0 +1,58 @@
+import { describe, beforeEach, expect, it } from 'vitest'
+import greaterThanOrEqual_date from '../greaterThanOrEqual_date.js'
+import dayjs from '@/common/helpers/dayjs.js'
+
+const mockI18n = {
+ $tc: (key) => key,
+}
+
+describe('greaterThanOrEqual_date validation', () => {
+ describe('german', () => {
+ beforeEach(() => {
+ dayjs.locale('de')
+ })
+
+ it.each([
+ [['20.01.2020', { min: '19.01.2020' }], true],
+ [['19.01.2020', { min: '19.01.2020' }], true],
+ [['18.01.2020', { min: '19.01.2020' }], false],
+ [['', { min: '19.01.2020' }], false],
+ [['2.1.2020', { min: '02.01.2020' }], false], // invalid date
+ [['1.1.2020', { min: '02.01.2020' }], false], // invalid date
+ [['today', { min: '02.01.2020' }], false], // invalid date
+ ])('validates %p as %p', (input, expected) => {
+ // given
+ const rule = greaterThanOrEqual_date(dayjs, mockI18n)
+
+ // when
+ const result = rule.validate(...input)
+
+ // then
+ expect(result).toBe(expected)
+ })
+ })
+ describe('english', () => {
+ beforeEach(() => {
+ dayjs.locale('en')
+ })
+
+ it.each([
+ [['01/20/2020', { min: '01/19/2020' }], true],
+ [['01/19/2020', { min: '01/19/2020' }], true],
+ [['01/18/2020', { min: '01/19/2020' }], false],
+ [['', { min: '01/19/2020' }], false],
+ [['1/2/2020', { min: '01/02/2020' }], false], // invalid date
+ [['1/1/2020', { min: '01/02/2020' }], false], // invalid date
+ [['today', { min: '01/02/2020' }], false], // invalid date
+ ])('validates %p as %p', (input, expected) => {
+ // given
+ const rule = greaterThanOrEqual_date(dayjs, mockI18n)
+
+ // when
+ const result = rule.validate(...input)
+
+ // then
+ expect(result).toBe(expected)
+ })
+ })
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThan_time.spec.js b/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThan_time.spec.js
new file mode 100644
index 0000000000..2d71b887ee
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/__tests__/greaterThan_time.spec.js
@@ -0,0 +1,74 @@
+import { describe, beforeEach, expect, it } from 'vitest'
+import greaterThan_time from '../greaterThan_time.js'
+import dayjs from '@/common/helpers/dayjs.js'
+
+const mockI18n = {
+ $tc: (key) => key,
+}
+
+function convertTimeStringToDayjsObject(timeString) {
+ // The date should be actively ignored by the validator, so we can use any random date
+ return dayjs.utc('2022-09-03 ' + timeString, 'YYYY-MM-DD LT')
+}
+
+describe('greaterThan_time validation', () => {
+ const testcases = {
+ de: [
+ [['09:31', { min: '09:30' }], true],
+ [['09:30', { min: '09:30' }], false],
+ [['09:29', { min: '09:30' }], false],
+ [['', { min: '09:30' }], false],
+ [['9:31 AM', { min: '09:30' }], true], // dayjs parser is somewhat forgiving here
+ [['9:31', { min: '09:30' }], true],
+ [['9:30', { min: '09:30' }], false],
+ [['9:29', { min: '09:30' }], false],
+ [['now', { min: '09:30' }], false], // invalid date
+ ],
+ en: [
+ [['09:31 AM', { min: '09:30 AM' }], true],
+ [['09:30 AM', { min: '09:30 AM' }], false],
+ [['09:29 AM', { min: '09:30 AM' }], false],
+ [['', { min: '09:30 AM' }], false],
+ [['09:30', { min: '09:30 AM' }], false], // wrong format
+ [['9:31', { min: '09:30 AM' }], false], // wrong format
+ [['now', { min: '09:30 AM' }], false], // invalid date
+ ],
+ }
+
+ describe.each(Object.entries(testcases))('%s', (language, cases) => {
+ beforeEach(() => {
+ dayjs.locale(language)
+ })
+
+ describe('when min is a string', () => {
+ it.each(cases)('validates %p as %p', (input, expected) => {
+ // given
+ const rule = greaterThan_time(dayjs, mockI18n)
+
+ // when
+ const result = rule.validate(...input)
+
+ // then
+ expect(result).toBe(expected)
+ })
+ })
+
+ describe('when min is a dayjs object', () => {
+ const casesWithDayjsObjectsAsMin = cases.map(([[input, { min }], expected]) => {
+ dayjs.locale(language)
+ return [[input, { min: convertTimeStringToDayjsObject(min) }], expected]
+ })
+
+ it.each(casesWithDayjsObjectsAsMin)('validates %p as %p', (input, expected) => {
+ // given
+ const rule = greaterThan_time(dayjs, mockI18n)
+
+ // when
+ const result = rule.validate(...input)
+
+ // then
+ expect(result).toBe(expected)
+ })
+ })
+ })
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/__tests__/lessThanOrEqual_date.spec.js b/frontend-vue3/src/plugins/veeValidate/__tests__/lessThanOrEqual_date.spec.js
new file mode 100644
index 0000000000..86ab2dc90d
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/__tests__/lessThanOrEqual_date.spec.js
@@ -0,0 +1,58 @@
+import { describe, beforeEach, expect, it } from 'vitest'
+import lessThanOrEqual_date from '../lessThanOrEqual_date.js'
+import dayjs from '@/common/helpers/dayjs.js'
+
+const mockI18n = {
+ $tc: (key) => key,
+}
+
+describe('lessThanOrEqual_date validation', () => {
+ describe('german', () => {
+ beforeEach(() => {
+ dayjs.locale('de')
+ })
+
+ it.each([
+ [['18.01.2020', { max: '19.01.2020' }], true],
+ [['19.01.2020', { max: '19.01.2020' }], true],
+ [['20.01.2020', { max: '19.01.2020' }], false],
+ [['', { max: '19.01.2020' }], false],
+ [['2.1.2020', { max: '02.01.2020' }], false], // invalid date
+ [['3.1.2020', { max: '02.01.2020' }], false], // invalid date
+ [['today', { max: '02.01.2020' }], false], // invalid date
+ ])('validates %p as %p', (input, expected) => {
+ // given
+ const rule = lessThanOrEqual_date(dayjs, mockI18n)
+
+ // when
+ const result = rule.validate(...input)
+
+ // then
+ expect(result).toBe(expected)
+ })
+ })
+ describe('english', () => {
+ beforeEach(() => {
+ dayjs.locale('en')
+ })
+
+ it.each([
+ [['01/18/2020', { max: '01/19/2020' }], true],
+ [['01/19/2020', { max: '01/19/2020' }], true],
+ [['01/20/2020', { max: '01/19/2020' }], false],
+ [['', { max: '01/19/2020' }], false],
+ [['1/2/2020', { max: '01/02/2020' }], false], // invalid date
+ [['1/3/2020', { max: '01/02/2020' }], false], // invalid date
+ [['today', { max: '01/02/2020' }], false], // invalid date
+ ])('validates %p as %p', (input, expected) => {
+ // given
+ const rule = lessThanOrEqual_date(dayjs, mockI18n)
+
+ // when
+ const result = rule.validate(...input)
+
+ // then
+ expect(result).toBe(expected)
+ })
+ })
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/__tests__/oneEmojiOrTwoCharacters.spec.js b/frontend-vue3/src/plugins/veeValidate/__tests__/oneEmojiOrTwoCharacters.spec.js
new file mode 100644
index 0000000000..bfdb516776
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/__tests__/oneEmojiOrTwoCharacters.spec.js
@@ -0,0 +1,30 @@
+import { describe, expect, it } from 'vitest'
+import oneEmojiOrTwoCharacters from '../oneEmojiOrTwoCharacters.js'
+
+const mockI18n = {
+ $tc: (key) => key,
+}
+
+describe('oneEmojiOrTwoCharacters validation', () => {
+ it.each([
+ ['1', true],
+ ['12', true],
+ ['123', false],
+ ['🧑🏼🔧', true],
+ ['🧑🏼🔧😊', false],
+ ['😊', true],
+ ['😊😊', false],
+ ['a😊', false],
+ ['', true],
+ ['😊😊😊😊', false],
+ ])('validates %s as %s', (input, expected) => {
+ // given
+ const rule = oneEmojiOrTwoCharacters(mockI18n)
+
+ // when
+ const result = rule.validate(input)
+
+ // then
+ expect(result).toBe(expected)
+ })
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/greaterThan.js b/frontend-vue3/src/plugins/veeValidate/greaterThan.js
new file mode 100644
index 0000000000..143cb81609
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/greaterThan.js
@@ -0,0 +1,17 @@
+export default (i18n) => ({
+ params: ['min'],
+ /**
+ *
+ * @param {string} value value of a float number
+ * @param number min Comparison value in string format 'HH:mm'
+ * @returns {boolean} validation result
+ */
+ validate: (value, { min }) => {
+ return parseFloat(value) > min
+ },
+ message: (field, { min }) => {
+ return i18n.t('global.validation.greaterThan', 0, {
+ min: min,
+ })
+ },
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/greaterThanOrEqual_date.js b/frontend-vue3/src/plugins/veeValidate/greaterThanOrEqual_date.js
new file mode 100644
index 0000000000..99bbbc9cdb
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/greaterThanOrEqual_date.js
@@ -0,0 +1,15 @@
+export default (dayjs, i18n) => ({
+ params: ['min'],
+ /**
+ * @param {string} value Dater value in local string format
+ * @param {string} min comparison valye in local string format
+ * @returns {bool} validation result
+ */
+ validate: (value, { min }) => {
+ const minDate = dayjs.utc(min, 'L')
+ const valueDate = dayjs.utc(value, 'L')
+ return valueDate.diff(minDate, 'day') >= 0
+ },
+ message: (field, values) =>
+ i18n.tc('global.validation.greaterThanOrEqual_date', 0, values),
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/greaterThan_time.js b/frontend-vue3/src/plugins/veeValidate/greaterThan_time.js
new file mode 100644
index 0000000000..3fb771b31f
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/greaterThan_time.js
@@ -0,0 +1,25 @@
+function normalizeMin(min, dayjs) {
+ return typeof min === 'string'
+ ? dayjs.utc('1970-01-01 ' + min, 'YYYY-MM-DD LT')
+ : min.set('date', 1).set('month', 0).set('year', 1970)
+}
+
+export default (dayjs, i18n) => ({
+ params: ['min'],
+ /**
+ *
+ * @param {string} value Time value in string format 'HH:mm'
+ * @param {string} min Comparison value in string format 'HH:mm'
+ * @returns {bool} validation result
+ */
+ validate: (value, { min }) => {
+ const valueDate = dayjs.utc('1970-01-01 ' + value, 'YYYY-MM-DD LT')
+ const minDate = normalizeMin(min, dayjs)
+ return valueDate.unix() > minDate.unix()
+ },
+ message: (field, values) => {
+ return i18n.t('global.validation.greaterThan_time', 0, {
+ min: normalizeMin(values.min, dayjs).format('LT'),
+ })
+ },
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/lessThanOrEqual_date.js b/frontend-vue3/src/plugins/veeValidate/lessThanOrEqual_date.js
new file mode 100644
index 0000000000..cfb79abf78
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/lessThanOrEqual_date.js
@@ -0,0 +1,15 @@
+export default (dayjs, i18n) => ({
+ params: ['max'],
+ /**
+ * @param {string} value Dater value in local string format
+ * @param {string} max comparison valye in local string format
+ * @returns {bool} validation result
+ */
+ validate: (value, { max }) => {
+ const maxDate = dayjs.utc(max, 'L')
+ const valueDate = dayjs.utc(value, 'L')
+ return valueDate.diff(maxDate, 'day') <= 0
+ },
+ message: (field, values) =>
+ i18n.tc('global.validation.lessThanOrEqual_date', 0, values),
+})
diff --git a/frontend-vue3/src/plugins/veeValidate/oneEmojiOrTwoCharacters.js b/frontend-vue3/src/plugins/veeValidate/oneEmojiOrTwoCharacters.js
new file mode 100644
index 0000000000..f563ec69bc
--- /dev/null
+++ b/frontend-vue3/src/plugins/veeValidate/oneEmojiOrTwoCharacters.js
@@ -0,0 +1,9 @@
+import { size } from 'lodash-es'
+
+export default (i18n) => ({
+ validate: (value) => {
+ return /\p{Extended_Pictographic}/u.test(value) ? size(value) <= 1 : value.length <= 2
+ },
+ message: (field, values) =>
+ i18n.tc('global.validation.oneEmojiOrTwoCharacters', 0, values),
+})
diff --git a/frontend-vue3/src/plugins/vuetify.js b/frontend-vue3/src/plugins/vuetify.js
new file mode 100644
index 0000000000..2facd0a3c4
--- /dev/null
+++ b/frontend-vue3/src/plugins/vuetify.js
@@ -0,0 +1,68 @@
+// You still need to register Vuetify itself
+// src/plugins/vuetify.js
+
+import PbsLogo from '@/assets/PbsLogo.svg'
+import GoogleLogo from '@/assets/GoogleLogo.svg'
+import eCampLogo from '@/assets/eCampLogo.svg'
+import CeviLogo from '@/assets/CeviLogo.svg'
+import JublaLogo from '@/assets/JublaLogo.svg'
+import JSLogo from '@/common/assets/logos/JSLogo.svg'
+import GSLogo from '@/common/assets/logos/GSLogo.svg'
+import TentDay from '@/assets/tents/TentDay.svg'
+import PaperSize from '@/assets/icons/PaperSize.svg'
+import BigScreen from '@/assets/icons/BigScreen.svg'
+import ResponsiveLayout from '@/assets/icons/ResponsiveLayout.svg'
+import ColumnLayout from '@/assets/icons/ColumnLayout.svg'
+import i18n from '@/plugins/i18n'
+import * as colors from 'vuetify/util/colors'
+
+import { VCalendar } from 'vuetify/labs/VCalendar'
+
+// Styles
+import '@mdi/font/css/materialdesignicons.css'
+import 'vuetify/styles'
+import { createVuetify } from 'vuetify'
+
+class VuetifyLoaderPlugin {
+ install(app) {
+ const opts = {
+ lang: {
+ t: (key, ...params) => i18n.t(key, 0, params),
+ },
+ icons: {
+ aliases: {
+ pbs: PbsLogo,
+ google: GoogleLogo,
+ ecamp: eCampLogo,
+ cevi: CeviLogo,
+ jubla: JublaLogo,
+ js: JSLogo,
+ gs: GSLogo,
+ tentDay: TentDay,
+ paperSize: PaperSize,
+ bigScreen: BigScreen,
+ columnLayout: ColumnLayout,
+ responsiveLayout: ResponsiveLayout,
+ },
+ },
+ theme: {
+ themes: {
+ light: {
+ error: colors.red.darken2,
+ },
+ },
+ },
+ components: {
+ VCalendar,
+ },
+ }
+
+ vuetify = createVuetify(opts)
+
+ app.use(vuetify)
+ }
+}
+
+export let vuetify
+
+export default new VuetifyLoaderPlugin()
diff --git a/frontend-vue3/src/router.js b/frontend-vue3/src/router.js
new file mode 100644
index 0000000000..4d0567d6b3
--- /dev/null
+++ b/frontend-vue3/src/router.js
@@ -0,0 +1,1033 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import { slugify } from '@/plugins/slugify.js'
+import { isLoggedIn } from '@/plugins/auth'
+import { apiStore } from '@/plugins/store'
+import { getEnv } from '@/environment.js'
+import campShortTitle from '@/common/helpers/campShortTitle.js'
+
+const NavigationAuth = () => import('./views/auth/NavigationAuth.vue')
+const NavigationDefault = () => import('./views/NavigationDefault.vue')
+const NavigationCamp = () => import('./views/camp/navigation/NavigationCamp.vue')
+const GenericPage = () => import('./components/generic/GenericPage.vue')
+
+/* istanbul ignore next */
+const router = createRouter({
+ mode: 'history',
+ history: createWebHistory(),
+ base: '/',
+ routes: [
+ ...(getEnv().FEATURE_DEVELOPER
+ ? [
+ // Dev-Pages:
+ {
+ path: '/controls',
+ name: 'controls',
+ components: {
+ default: () => import('./views/dev/Controls.vue'),
+ },
+ beforeEnter: requireAuth,
+ },
+ {
+ path: '/performance',
+ name: 'performance',
+ components: {
+ default: () => import('./views/dev/Performance.vue'),
+ },
+ beforeEnter: requireAuth,
+ },
+ ]
+ : []),
+
+ // Prod-Pages:
+ {
+ path: '/debug',
+ name: 'debug',
+ components: {
+ default: () => import('./views/admin/Debug.vue'),
+ },
+ },
+ {
+ path: '/admin',
+ beforeEnter: all([requireAuth, requireAdmin]),
+ components: {
+ navigation: NavigationDefault,
+ default: GenericPage,
+ aside: () => import('./views/admin/SideBarAdmin.vue'),
+ },
+ children: [
+ {
+ path: '',
+ redirect: 'debug',
+ },
+ {
+ path: 'debug',
+ name: 'admin/debug',
+ components: {
+ default: () => import('./views/admin/Debug.vue'),
+ },
+ },
+ ...(getEnv().FEATURE_CHECKLIST
+ ? [
+ {
+ path: 'checklists',
+ name: 'admin/checklists',
+ components: {
+ default: () => import('./views/admin/Checklists.vue'),
+ },
+ },
+ {
+ path: 'checklist/:checklistId/:checklistName?',
+ name: 'admin/checklists/checklist',
+ components: {
+ default: () => import('./views/admin/Checklist.vue'),
+ },
+ props: {
+ default: (route) => ({
+ checklist: checklistFromRoute(route),
+ }),
+ },
+ },
+ ]
+ : []),
+ ],
+ },
+
+ {
+ path: '/register',
+ name: 'register',
+ components: {
+ navigation: NavigationAuth,
+ default: () => import('./views/auth/Register.vue'),
+ },
+ },
+ {
+ path: '/register-done',
+ name: 'register-done',
+ components: {
+ navigation: NavigationAuth,
+ default: () => import('./views/auth/RegisterDone.vue'),
+ },
+ },
+ {
+ path: '/resend-activation',
+ name: 'resendActivation',
+ components: {
+ navigation: NavigationAuth,
+ default: () => import('./views/auth/ResendActivation.vue'),
+ },
+ },
+ {
+ path: '/reset-password',
+ name: 'resetPasswordRequest',
+ components: {
+ navigation: NavigationAuth,
+ default: () => import('./views/auth/ResetPasswordRequest.vue'),
+ },
+ },
+ {
+ path: '/reset-password/:id',
+ name: 'resetPassword',
+ components: {
+ navigation: NavigationAuth,
+ default: () => import('./views/auth/ResetPassword.vue'),
+ },
+ props: {
+ default: (route) => {
+ return {
+ id: route.params.id,
+ }
+ },
+ },
+ },
+ {
+ path: '/activate/:userId/:activationKey',
+ name: 'activate',
+ components: {
+ navigation: NavigationAuth,
+ default: () => import('./views/auth/Activate.vue'),
+ },
+ props: {
+ default: (route) => {
+ return {
+ userId: route.params.userId,
+ activationKey: route.params.activationKey,
+ }
+ },
+ },
+ },
+ {
+ path: '/login',
+ name: 'login',
+ components: {
+ navigation: NavigationAuth,
+ default: () => import('./views/auth/Login.vue'),
+ },
+ },
+ {
+ path: '/loginCallback',
+ name: 'loginCallback',
+ components: {
+ navigation: NavigationAuth,
+ default: () => import('./views/auth/LoginCallback.vue'),
+ },
+ },
+ {
+ path: '/profile',
+ name: 'profile',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/Profile.vue'),
+ },
+ beforeEnter: requireAuth,
+ },
+ {
+ path: '/profile/verify-mail/:emailVerificationKey',
+ name: 'profileVerifyEmail',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/Profile.vue'),
+ },
+ props: {
+ default: (route) => {
+ return { emailVerificationKey: route.params.emailVerificationKey }
+ },
+ },
+ beforeEnter: requireAuth,
+ },
+ {
+ path: '/camps',
+ name: 'camps',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/Camps.vue'),
+ },
+ beforeEnter: requireAuth,
+ },
+ {
+ path: '/invitations',
+ name: 'invitations',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/Invitations.vue'),
+ },
+ beforeEnter: requireAuth,
+ },
+ {
+ path: '/camps/create',
+ name: 'camps/create',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/CampCreate.vue'),
+ },
+ beforeEnter: requireAuth,
+ },
+ {
+ path: '/camps/invitation/rejected',
+ name: 'invitationRejected',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/camp/Invitation.vue'),
+ },
+ props: {
+ default: () => ({
+ variant: 'rejected',
+ }),
+ },
+ },
+ {
+ path: '/camps/invitation/updateError',
+ name: 'invitationUpdateError',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/camp/Invitation.vue'),
+ },
+ props: {
+ default: () => ({
+ variant: 'error',
+ }),
+ },
+ },
+ {
+ path: '/camps/invitation/:inviteKey',
+ name: 'campInvitation',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/camp/Invitation.vue'),
+ },
+ props: {
+ default: (route) => ({
+ variant: 'default',
+ invitation: invitationFromInviteKey(route.params.inviteKey),
+ }),
+ },
+ },
+ {
+ path: '/camps/:campId/:campShortTitle?',
+ components: {
+ navigation: NavigationCamp,
+ default: GenericPage,
+ },
+ beforeEnter: all([requireAuth, requireCamp]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ camp: campFromRoute(route),
+ period: periodFromRoute(route),
+ layout: getContentLayout(route),
+ }),
+ },
+ children: [
+ {
+ path: 'program/period/:periodId/:periodTitle?',
+ name: 'camp/period/program',
+ component: () => import('./views/camp/CampProgram.vue'),
+ beforeEnter: requirePeriod,
+ },
+ {
+ path: 'program',
+ name: 'camp/program',
+ async beforeEnter(to, from, next) {
+ redirectToPeriod(to, from, next, 'camp/period/program')
+ },
+ },
+ {
+ path: 'overview/checklists',
+ name: 'camp/overview/checklists',
+ component: () => import('./views/camp/checklistOverview/ChecklistLists.vue'),
+ },
+ {
+ path: 'story/period/:periodId/:periodTitle?',
+ name: 'camp/period/story',
+ component: () => import('./views/camp/Story.vue'),
+ beforeEnter: requirePeriod,
+ },
+ {
+ path: 'story',
+ name: 'camp/story',
+ async beforeEnter(to, from, next) {
+ redirectToPeriod(to, from, next, 'camp/period/story')
+ },
+ },
+ {
+ path: 'dashboard',
+ name: 'camp/dashboard',
+ component: () => import('./views/camp/Dashboard.vue'),
+ },
+ {
+ path: '',
+ name: 'camp/home',
+ redirect: { name: 'camp/dashboard' },
+ },
+ ],
+ },
+ {
+ name: 'camp/material/all',
+ path: '/camps/:campId/:campShortTitle?/material/all',
+ components: {
+ navigation: NavigationCamp,
+ default: () => import('./views/camp/material/MaterialOverview.vue'),
+ aside: () => import('./views/camp/material/SideBarMaterialLists.vue'),
+ },
+ beforeEnter: all([requireAuth, requireCamp]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ aside: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ camp: campFromRoute(route),
+ }),
+ },
+ },
+ {
+ name: 'camp/overview/checklists/checklist',
+ path: '/camps/:campId/:campShortTitle?/overview/checklists/:checklistId/:checklistName?',
+ components: {
+ navigation: NavigationCamp,
+ default: () => import('./views/camp/checklistOverview/ChecklistOverview.vue'),
+ aside: () =>
+ import('./views/camp/checklistOverview/SideBarChecklistOverview.vue'),
+ },
+ beforeEnter: all([requireAuth, requireCamp]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ aside: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ camp: campFromRoute(route),
+ checklist: checklistFromRoute(route),
+ }),
+ },
+ },
+ {
+ name: 'camp/material/lists', // Only used on mobile
+ path: '/camps/:campId/:campShortTitle?/material/lists',
+ components: {
+ navigation: NavigationCamp,
+ default: () => import('./views/camp/material/MaterialLists.vue'),
+ },
+ beforeEnter: all([requireAuth, requireCamp]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ camp: campFromRoute(route),
+ }),
+ },
+ },
+ {
+ name: 'camp/material/detail',
+ path: '/camps/:campId/:campShortTitle?/material/:materialId/:materialName?',
+ components: {
+ navigation: NavigationCamp,
+ default: () => import('./views/camp/material/MaterialDetail.vue'),
+ aside: () => import('./views/camp/material/SideBarMaterialLists.vue'),
+ },
+ beforeEnter: all([requireAuth, requireCamp, requireMaterialList]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ aside: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ camp: campFromRoute(route),
+ materialList: materialListFromRoute(route),
+ }),
+ },
+ },
+ {
+ name: 'camp/admin/activity/category',
+ path: '/camps/:campId/:campShortTitle?/category/:categoryId/:categoryName?',
+ components: {
+ navigation: NavigationCamp,
+ default: () => import('./views/camp/category/Category.vue'),
+ aside: () => import('./views/camp/category/SideBarCategory.vue'),
+ },
+ beforeEnter: all([requireAuth, requireCamp, requireCategory]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ aside: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ camp: campFromRoute(route),
+ category: categoryFromRoute(route),
+ }),
+ },
+ },
+ ...(getEnv().FEATURE_CHECKLIST
+ ? [
+ // Checklist-Pages:
+ {
+ name: 'camp/admin/checklists/checklist',
+ path: '/camps/:campId/:campTitle?/admin/checklist/:checklistId/:checklistName?',
+ components: {
+ navigation: NavigationCamp,
+ default: () => import('./views/camp/checklist/Checklist.vue'),
+ aside: () => import('./views/camp/checklist/SideBarChecklist.vue'),
+ },
+ beforeEnter: all([requireAuth, requireCamp, requireChecklist]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ aside: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ camp: campFromRoute(route),
+ checklist: checklistFromRoute(route),
+ }),
+ },
+ },
+ ]
+ : []),
+ {
+ path: '/camps/:campId/:campShortTitle?/admin',
+ components: {
+ navigation: NavigationCamp,
+ default: GenericPage,
+ aside: () => import('./views/camp/admin/SideBarAdmin.vue'),
+ },
+ beforeEnter: all([requireAuth, requireCamp]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ camp: campFromRoute(route),
+ layout: getContentLayout(route),
+ }),
+ aside: (route) => ({ camp: campFromRoute(route) }),
+ },
+ children: [
+ {
+ path: 'info',
+ name: 'camp/admin/info',
+ component: () => import('./views/camp/admin/Info.vue'),
+ props: (route) => ({ camp: campFromRoute(route) }),
+ },
+ {
+ path: 'activity',
+ name: 'camp/admin/activity',
+ component: () => import('./views/camp/admin/Activity.vue'),
+ props: (route) => ({ camp: campFromRoute(route) }),
+ },
+ {
+ path: 'collaborators',
+ name: 'camp/admin/collaborators',
+ component: () => import('./views/camp/admin/Collaborators.vue'),
+ props: () => ({ layout: 'normal' }),
+ },
+ {
+ path: 'material',
+ name: 'camp/admin/material',
+ component: () => import('./views/camp/admin/AdminMaterialLists.vue'),
+ },
+ {
+ path: 'print',
+ name: 'camp/admin/print',
+ component: () => import('./views/camp/admin/Print.vue'),
+ props: (route) => ({ camp: campFromRoute(route) }),
+ },
+ ...(getEnv().FEATURE_CHECKLIST
+ ? [
+ // Checklist-Pages:
+ {
+ path: 'checklists',
+ name: 'camp/admin/checklists',
+ component: () => import('./views/camp/admin/Checklists.vue'),
+ props: (route) => ({ camp: campFromRoute(route) }),
+ },
+ ]
+ : []),
+ {
+ path: 'materiallists',
+ name: 'camp/material',
+ redirect: { name: 'camp/admin/material' },
+ },
+ {
+ path: '',
+ name: 'camp/admin',
+ redirect: { name: 'camp/admin/info' },
+ },
+ ],
+ },
+ {
+ path: '/camps/:campId/:campShortTitle/program/activity/:activityId/:scheduleEntryId?/:activityName?',
+ name: 'camp/activity',
+ components: {
+ navigation: NavigationCamp,
+ default: () => import('./views/camp/activity/Activity.vue'),
+ aside: () => import('./views/camp/activity/SideBarProgram.vue'),
+ },
+ beforeEnter: all([requireAuth, requireCamp, requireActivityScheduleEntry]),
+ props: {
+ navigation: (route) => ({ camp: campFromRoute(route) }),
+ default: (route) => ({
+ activityId: route.params.activityId,
+ scheduleEntryId: route.params.scheduleEntryId,
+ }),
+ aside: (route) => ({
+ camp: campFromRoute(route),
+ activityId: route.params.activityId,
+ scheduleEntryId: route.params.scheduleEntryId,
+ }),
+ },
+ },
+ {
+ path: '/camps/:campId/:campShortTitle/program/activities/:scheduleEntryId/:activityName?',
+ redirect:
+ '/camps/:campId/:campShortTitle/program/activity/0/:scheduleEntryId?/:activityName?',
+ },
+ {
+ path: '/',
+ name: 'home',
+ redirect: { name: 'camps' },
+ },
+ {
+ path: '/**',
+ name: 'PageNotFound',
+ components: {
+ navigation: NavigationDefault,
+ default: () => import('./views/PageNotFound.vue'),
+ },
+ },
+ ],
+})
+
+export default router
+
+function evaluateGuards(guards, to, from, next) {
+ const guardsLeft = guards.slice(0)
+ const nextGuard = guardsLeft.shift()
+
+ if (nextGuard === undefined) {
+ next()
+ return
+ }
+
+ nextGuard(to, from, (nextArg) => {
+ if (nextArg === undefined) {
+ evaluateGuards(guardsLeft, to, from, next)
+ return
+ }
+ next(nextArg)
+ })
+}
+
+function all(guards) {
+ return (to, from, next) => evaluateGuards(guards, to, from, next)
+}
+
+function requireAuth(to, from, next) {
+ if (isLoggedIn()) {
+ next()
+ } else {
+ next({ name: 'login', query: to.path === '/' ? {} : { redirect: to.fullPath } })
+ }
+}
+
+function requireAdmin(to, from, next) {
+ if (isAdmin()) {
+ next()
+ } else {
+ next({
+ name: 'PageNotFound',
+ params: [to.fullPath, ''],
+ replace: true,
+ })
+ }
+}
+
+async function requireCamp(to, from, next) {
+ const camp = await campFromRoute(to)
+ if (camp === undefined) {
+ next({
+ name: 'PageNotFound',
+ params: [to.fullPath, ''],
+ replace: true,
+ })
+ } else {
+ await camp._meta.load
+ .then(() => {
+ next()
+ })
+ .catch(() => {
+ next({
+ name: 'PageNotFound',
+ params: [to.fullPath, ''],
+ replace: true,
+ })
+ })
+ }
+}
+
+async function requireActivityScheduleEntry(to, from, next) {
+ await apiStore
+ .get()
+ .activities({ id: to.params.activityId })
+ .$reload()
+ .then(async (activity) => {
+ // activity exists
+ const scheduleEntry = to.params.scheduleEntryId
+ ? activity
+ .scheduleEntries()
+ .items.find((entry) => entry.id === to.params.scheduleEntryId)
+ : null
+
+ if (scheduleEntry) {
+ // activity and scheduleEntry exist
+ next()
+ } else {
+ // scheduleEntry is not found, use first activity scheduleEntry
+ to.params.scheduleEntryId = (await firstActivityScheduleEntry(activity)).id
+ next(to)
+ }
+ })
+ .catch(() => {
+ // activityId does not exist, check if scheduleEntryId exists
+ if (to.params.scheduleEntryId) {
+ apiStore
+ .get()
+ .scheduleEntries({ id: to.params.scheduleEntryId })
+ ._meta.load.then(async (scheduleEntry) => {
+ to.params.activityId = scheduleEntry.activity().id
+ next(to)
+ })
+ .catch(async () => {
+ // scheduleEntry and activity are not found, fallback to camp program
+ next({
+ ...to,
+ name: 'camp/program',
+ })
+ })
+ }
+ })
+}
+
+async function requirePeriod(to, from, next) {
+ const period = await periodFromRoute(to)
+ if (period === undefined) {
+ next({
+ name: 'PageNotFound',
+ params: [to.fullPath, ''],
+ replace: true,
+ })
+ } else {
+ await period._meta.load
+ .then(() => {
+ next()
+ })
+ .catch(() => {
+ next(campRoute(campFromRoute(to)))
+ })
+ }
+}
+
+async function requireCategory(to, from, next) {
+ const category = await categoryFromRoute(to)
+ if (category === undefined) {
+ next({
+ name: 'PageNotFound',
+ params: [to.fullPath, ''],
+ replace: true,
+ })
+ } else {
+ await category._meta.load
+ .then(() => {
+ next()
+ })
+ .catch(() => {
+ next({
+ name: 'PageNotFound',
+ params: [to.fullPath, ''],
+ replace: true,
+ })
+ })
+ }
+}
+
+async function requireMaterialList(to, from, next) {
+ const materialList = await materialListFromRoute(to)
+ if (materialList === undefined) {
+ next({
+ name: 'PageNotFound',
+ params: [to.fullPath, ''],
+ replace: true,
+ })
+ } else {
+ await materialList._meta.load
+ .then(() => {
+ next()
+ })
+ .catch(() => {
+ next(campRoute(campFromRoute(to)))
+ })
+ }
+}
+
+async function requireChecklist(to, from, next) {
+ const checklist = await checklistFromRoute(to)
+ if (checklist === undefined) {
+ next({
+ name: 'PageNotFound',
+ params: [to.fullPath, ''],
+ replace: true,
+ })
+ } else {
+ await checklist._meta.load
+ .then(() => {
+ next()
+ })
+ .catch(() => {
+ next(campRoute(campFromRoute(to)))
+ })
+ }
+}
+
+export function campFromRoute(route) {
+ if (!route.params.campId) {
+ return undefined
+ }
+ return apiStore.get().camps({ id: route.params.campId })
+}
+
+export function invitationFromInviteKey(inviteKey) {
+ return apiStore.get().invitations({ action: 'find', id: inviteKey })
+}
+
+export function periodFromRoute(route) {
+ if (!route.params.periodId) {
+ return undefined
+ }
+ return apiStore.get().periods({ id: route.params.periodId })
+}
+
+function categoryFromRoute(route) {
+ if (!route.params.categoryId) {
+ return undefined
+ }
+ return campFromRoute(route)
+ .categories()
+ .allItems.find((c) => c.id === route.params.categoryId)
+}
+
+export function materialListFromRoute(route) {
+ if (!route.params.materialId) {
+ return undefined
+ }
+ return apiStore.get().materialLists({ id: route.params.materialId })
+}
+
+export function checklistFromRoute(route) {
+ if (!route.params.checklistId) {
+ return undefined
+ }
+ return campFromRoute(route)
+ .checklists()
+ .allItems.find((c) => c.id === route.params.checklistId)
+}
+
+function getContentLayout(route) {
+ switch (route.name) {
+ case 'camp/checklist':
+ case 'camp/period/program':
+ case 'camp/admin/print':
+ case 'camp/admin/activity/category':
+ return 'full'
+ case 'camp/print':
+ case 'camp/material':
+ case 'camp/admin/info':
+ case 'camp/admin/activity':
+ return 'wide'
+ case 'camp/admin/collaborators':
+ case 'camp/admin/material':
+ default:
+ return 'normal'
+ }
+}
+
+/**
+ * @param camp
+ * @param subroute {'admin' | 'dashboard' | 'program' | 'material' | 'story' | 'home' | 'collaborators' | 'print' }
+ * @param query
+ */
+export function campRoute(camp, subroute = 'dashboard', query = {}) {
+ if (camp._meta.loading) return {}
+ return {
+ name: 'camp/' + subroute,
+ params: { campId: camp.id, campShortTitle: slugify(campShortTitle(camp)) },
+ query,
+ }
+}
+
+/**
+ * @param camp
+ * @param materialListOrRoute { '/all', '/lists', object }
+ * @param query
+ */
+export function materialListRoute(camp, materialListOrRoute = '/all', query = {}) {
+ if (camp._meta.loading) return {}
+ if (typeof materialListOrRoute === 'string') {
+ return {
+ name: `camp/material${materialListOrRoute}`,
+ params: { campId: camp.id, campShortTitle: slugify(campShortTitle(camp)) },
+ query,
+ }
+ }
+ if (!materialListOrRoute?._meta || materialListOrRoute.meta?.loading) return {}
+ return {
+ name: 'camp/material/detail',
+ params: {
+ campId: camp.id,
+ campShortTitle: slugify(campShortTitle(camp)),
+ materialId: materialListOrRoute.id,
+ materialName: slugify(materialListOrRoute.name),
+ },
+ query,
+ }
+}
+
+/**
+ * @param camp
+ * @param subroute {'info' | 'activity' | 'collaborators' | 'material' | 'print'}
+ * @param query
+ */
+export function adminRoute(camp, subroute = 'info', query = {}) {
+ if (camp._meta.loading) return {}
+ return {
+ name: 'camp/admin/' + subroute,
+ params: { campId: camp.id, campShortTitle: slugify(campShortTitle(camp)) },
+ query,
+ }
+}
+
+export function loginRoute(redirectTo) {
+ return { path: '/login', query: { redirect: redirectTo } }
+}
+
+export function periodRoute(period, routeName = 'camp/period/program', query = {}) {
+ const camp = period.camp()
+ if (camp._meta.loading || period._meta.loading) return {}
+ return {
+ name: routeName,
+ params: {
+ campId: camp.id,
+ campShortTitle: slugify(campShortTitle(camp)),
+ periodId: period.id,
+ periodTitle: slugify(period.description),
+ },
+ query,
+ }
+}
+
+export function scheduleEntryRoute(scheduleEntry, query = {}) {
+ if (scheduleEntry?._meta.loading || scheduleEntry?.activity()._meta.loading) return {}
+
+ const activity = scheduleEntry.activity()
+ const camp = activity.camp()
+
+ // if (camp._meta.loading) return {}
+
+ return {
+ name: 'camp/activity',
+ params: {
+ campId: camp.id,
+ campShortTitle: slugify(campShortTitle(camp)),
+ scheduleEntryId: scheduleEntry.id,
+ activityId: activity.id,
+ activityName: slugify(activity.title),
+ },
+ query,
+ }
+}
+
+export async function firstActivityScheduleEntryRoute(activity, query = {}) {
+ if (typeof activity === 'string') {
+ activity = await apiStore.get().activities({ id: activity })._meta.load
+ }
+ const camp = activity.camp()
+ apiStore.reload(activity.scheduleEntries())
+ const scheduleEntry = await firstActivityScheduleEntry(activity)
+
+ return {
+ name: 'camp/activity',
+ params: {
+ campId: camp.id,
+ campShortTitle: slugify(campShortTitle(camp)),
+ scheduleEntryId: scheduleEntry.id,
+ activityId: activity.id,
+ activityName: slugify(activity.title),
+ },
+ query,
+ }
+}
+
+export function categoryRoute(camp, category, query = {}) {
+ if (camp._meta.loading || category._meta.loading) return {}
+ return {
+ name: 'camp/admin/activity/category',
+ params: {
+ campId: camp.id,
+ campShortTitle: slugify(campShortTitle(camp)),
+ categoryId: category.id,
+ categoryName: slugify(category.name),
+ },
+ query,
+ }
+}
+
+export function checklistRoute(camp, checklist, query = {}) {
+ if (camp?._meta.loading || checklist?._meta.loading) return {}
+
+ if (!camp) {
+ if (!checklist) {
+ return {
+ name: 'admin/checklists',
+ query,
+ }
+ }
+ return {
+ name: 'admin/checklists/checklist',
+ params: {
+ checklistId: checklist.id,
+ checklistName: slugify(checklist.name),
+ },
+ query,
+ }
+ }
+
+ if (!checklist) {
+ return {
+ name: 'camp/admin/checklists',
+ params: {
+ campId: camp.id,
+ campTitle: slugify(camp.title),
+ },
+ query,
+ }
+ }
+ return {
+ name: 'camp/admin/checklists/checklist',
+ params: {
+ campId: camp.id,
+ campTitle: slugify(camp.title),
+ checklistId: checklist.id,
+ checklistName: slugify(checklist.name),
+ },
+ query,
+ }
+}
+
+export function checklistOverviewRoute(camp, checklist, query = {}) {
+ if (camp?._meta.loading || checklist._meta.loading) return {}
+
+ if (!checklist) {
+ return {
+ name: 'camp/overview/checklists',
+ params: {
+ campId: camp.id,
+ campTitle: slugify(camp.title),
+ },
+ query,
+ }
+ }
+
+ return {
+ name: 'camp/overview/checklists/checklist',
+ params: {
+ campId: camp.id,
+ campTitle: slugify(camp.title),
+ checklistId: checklist.id,
+ checklistName: slugify(checklist.name),
+ },
+ query,
+ }
+}
+
+async function firstFuturePeriod(route) {
+ if (!route.params.campId) {
+ return undefined
+ }
+ const periods = await apiStore.get().camps({ id: route.params.campId }).periods()._meta
+ .load
+ // Return the first period that hasn't ended, or if no such period exists, return the first period
+ return (
+ periods.items.find((period) => new Date(period.end) >= new Date()) ||
+ periods.items.find((_) => true)
+ )
+}
+
+export async function firstActivityScheduleEntry(activity) {
+ if (typeof activity === 'string') {
+ activity = await apiStore.get().activities({ id: activity })._meta.load
+ }
+ await activity.scheduleEntries()._meta.load
+ return activity
+ .scheduleEntries()
+ .items.reduce(
+ (result, current) =>
+ result === null || new Date(result.start) > new Date(current.start)
+ ? current
+ : result,
+ null
+ )
+}
+
+async function redirectToPeriod(to, from, next, routeName) {
+ const period = await firstFuturePeriod(to)
+ if (period) {
+ await period.camp()._meta.load
+ next(periodRoute(period, routeName, to.query))
+ } else {
+ const camp = await apiStore.get().camps({ id: to.params.campId })
+ next(campRoute(camp, 'camp/admin', to.query))
+ }
+}
diff --git a/frontend-vue3/src/scss/global.scss b/frontend-vue3/src/scss/global.scss
new file mode 100644
index 0000000000..952239e263
--- /dev/null
+++ b/frontend-vue3/src/scss/global.scss
@@ -0,0 +1,259 @@
+@use 'inter-ui/default' as inter-ui with (
+ $inter-font-path: 'inter-ui/Inter (web hinted latin)'
+);
+@include inter-ui.weight-200;
+@include inter-ui.weight-400;
+@include inter-ui.weight-500;
+@include inter-ui.weight-600;
+
+body {
+ font-feature-settings: 'ss03', 'calt', 'rlig', 'kern', 'cv05', 'cv07', 'cv08';
+}
+.text-uppercase {
+ font-feature-settings: 'ss03', 'calt', 'rlig', 'kern', 'cv05', 'cv07';
+}
+.v-toolbar__title {
+ font-weight: 500;
+}
+.v-theme--light.v-application {
+ background: #546e7a !important;
+}
+.v-calendar-daily,
+.v-skeleton-loader__actions,
+.v-skeleton-loader__article,
+.v-skeleton-loader__card-heading,
+.v-skeleton-loader__card-text,
+.v-skeleton-loader__date-picker,
+.v-skeleton-loader__list-item,
+.v-skeleton-loader__list-item-avatar,
+.v-skeleton-loader__list-item-text,
+.v-skeleton-loader__list-item-two-line,
+.v-skeleton-loader__list-item-avatar-two-line,
+.v-skeleton-loader__list-item-three-line,
+.v-skeleton-loader__list-item-avatar-three-line,
+.v-skeleton-loader__table-heading,
+.v-skeleton-loader__table-thead,
+.v-skeleton-loader__table-tbody,
+.v-skeleton-loader__table-tfoot {
+ background: none !important;
+}
+.v-skeleton-loader--inherit-size .v-skeleton-loader__bone {
+ height: inherit !important;
+ width: inherit !important;
+}
+.v-skeleton-loader--no-margin .v-skeleton-loader__bone {
+ margin-bottom: 0 !important;
+}
+.v-btn--outlined:before {
+ opacity: 0.08 !important;
+}
+.theme--dark.v-btn.v-btn--outlined:hover::before {
+ opacity: 0.16 !important;
+}
+.w-100 {
+ width: 100%;
+}
+.h-full {
+ height: 100%;
+}
+.v-application {
+ ul.v-list {
+ padding-left: 0;
+ }
+
+ .min-h-0 {
+ min-height: 0;
+ }
+
+ .e-title-link {
+ color: inherit;
+ text-underline-offset: 0.1em;
+ text-decoration-color: #1976d2;
+ outline-offset: 0.2em;
+
+ &:focus {
+ text-decoration-line: none;
+ }
+
+ &:hover {
+ text-decoration-thickness: 2px;
+ }
+ }
+
+ .v-alert.text-warning {
+ .v-alert__icon {
+ color: #d25f00 !important;
+ }
+ .v-alert__content {
+ color: #972e00 !important;
+ }
+ border-color: #ffe0b2 !important;
+ }
+
+ .elevation-4--light {
+ box-shadow:
+ 0 2px 4px -1px rgba(0, 0, 0, 0.1),
+ 0 4px 5px 0px rgba(0, 0, 0, 0.07),
+ 0 1px 10px 0px rgba(0, 0, 0, 0.06) !important;
+ }
+}
+.tabular-nums {
+ font-variant-numeric: tabular-nums;
+}
+
+.v-list-item--link:before {
+ border-radius: inherit;
+}
+
+.e-form-container + .e-form-container {
+ margin-top: 12px;
+}
+
+.basis-auto {
+ flex-basis: auto !important;
+}
+
+.select-left .v-select__selections {
+ justify-content: flex-start !important;
+}
+
+.flex-full {
+ flex: 1 1 0;
+}
+
+.v-sheet > .v-expansion-panels,
+.v-card > .v-expansion-panels {
+ border-top: 1px solid #eee;
+ border-bottom: 1px solid #eee;
+
+ > .v-expansion-panel + .v-expansion-panel {
+ border-top: 1px solid #eee;
+ }
+}
+
+.v-text-field--outlined.v-input--is-readonly:not(.v-input--is-focused):not(
+ .v-input--has-state
+ )
+ > .v-input__control
+ > .v-input__slot
+ fieldset {
+ color: rgb(0, 0, 0, 0.18);
+}
+
+.v-text-field.v-input--is-readonly > .v-input__control > .v-input__slot,
+.v-text-field.v-input--is-readonly > .v-input__control > .v-input__slot:before,
+.v-text-field.v-input--is-readonly > .v-input__control > .v-input__slot:after {
+ border-color: transparent !important;
+ background-color: transparent !important;
+}
+
+.v-text-field--outlined.v-input--is-readonly
+ > .v-input__control
+ > .v-input__slot
+ fieldset {
+ border: none !important;
+}
+
+.v-list-item__title {
+ font-size: 16px;
+}
+.v-list-item__content {
+ align-content: flex-start;
+}
+
+.dragging {
+ cursor: move;
+}
+
+.vertical-baseline {
+ vertical-align: baseline !important;
+}
+
+.pb-safe {
+ padding-bottom: env(safe-area-inset-bottom);
+}
+
+.mb-safe {
+ margin-bottom: env(safe-area-inset-bottom);
+}
+
+.d-flow-root {
+ display: flow-root;
+}
+.v-application {
+ .d-contents {
+ display: contents !important;
+ }
+
+ // @media #{map.get(settings.$display-breakpoints, 'sm-and-up')} {
+ // .d-sm-contents {
+ // display: contents !important;
+ // }
+ // }
+}
+
+.d-grid {
+ display: grid;
+}
+
+.d-inline-grid {
+ display: inline-grid;
+}
+
+.pointer-events-none {
+ pointer-events: none;
+}
+
+.user-select-none {
+ user-select: none;
+}
+
+.opacity-60 {
+ opacity: 0.6;
+}
+
+.grid-cols-2 {
+ grid-template-columns: 1fr 1fr;
+}
+
+.grid-cols-fill {
+ grid-template-columns: repeat(auto-fill, 1fr);
+}
+
+.currentColor--text {
+ color: currentColor !important;
+}
+
+.e-button-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1rem;
+}
+
+.relative {
+ position: relative;
+}
+
+.absolute {
+ position: absolute;
+}
+
+.bottom-0 {
+ bottom: 0;
+}
+
+.bottom-n100 {
+ bottom: -100%;
+}
+
+.right-0 {
+ right: 0;
+}
+
+.top-0 {
+ top: 0;
+}
+
+.justify-items-center {
+ justify-items: center;
+}
diff --git a/frontend-vue3/src/scss/settings.scss b/frontend-vue3/src/scss/settings.scss
new file mode 100644
index 0000000000..6b20305382
--- /dev/null
+++ b/frontend-vue3/src/scss/settings.scss
@@ -0,0 +1,111 @@
+/**
+ * src/styles/settings.scss
+ *
+ * Configures SASS variables and Vuetify overwrites
+ */
+
+// https://vuetifyjs.com/features/sass-variables/`
+// @use 'vuetify/settings' with (
+// $color-pack: false
+// );
+
+@use 'vuetify/settings' with (
+ $heading-font-family: (
+ 'Inter',
+ sans-serif,
+ emoji,
+ ),
+ $body-font-family: (
+ 'Inter',
+ sans-serif,
+ emoji,
+ ),
+ $font-weights: (
+ 'light': 200,
+ 'regular': 400,
+ 'bold': 600,
+ ),
+ $typography: (
+ 'h1': (
+ 'size': 6rem,
+ 'weight': 200,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.022em,
+ ),
+ 'h2': (
+ 'size': 3.75rem,
+ 'weight': 200,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.022em,
+ ),
+ 'h3': (
+ 'size': 3rem,
+ 'weight': 400,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.0215em,
+ ),
+ 'h4': (
+ 'size': 2.125rem,
+ 'weight': 400,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.021em,
+ ),
+ 'h5': (
+ 'size': 1.5rem,
+ 'weight': 400,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.019em,
+ ),
+ 'h6': (
+ 'size': 1.25rem,
+ 'weight': 600,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.0125em,
+ ),
+ 'subtitle-1': (
+ 'size': 1.125rem,
+ 'weight': 400,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.017em,
+ ),
+ 'subtitle-2': (
+ 'size': 0.875rem,
+ 'weight': 600,
+ 'line-height': 1.375rem,
+ 'letter-spacing': -0.006em,
+ ),
+ 'body-2': (
+ 'size': 0.875rem,
+ 'weight': 400,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.006em,
+ ),
+ 'body-1': (
+ 'size': 1rem,
+ 'weight': 400,
+ 'line-height': 1.428571429,
+ 'letter-spacing': -0.011em,
+ ),
+ 'caption': (
+ 'size': 0.75rem,
+ 'weight': 400,
+ 'line-height': 1.428571429,
+ 'letter-spacing': 0em,
+ ),
+ 'overline': (
+ 'size': 0.625rem,
+ 'weight': 400,
+ 'line-height': 1.428571429,
+ 'letter-spacing': 0.01em,
+ ),
+ ),
+ $button-text-letter-spacing: 0.25px,
+ $chip-icon-size-multiplier: calc(8 / 10),
+ $button-text-transform: none,
+ $bottom-navigation-min-width: 60px,
+ $list-item-icon-margin-end: 20px,
+ $menu-content-border-radius: 0 0 4px 4px,
+ $card-actions-padding: 16px,
+ $expansion-panel-title-padding: 16px,
+ $expansion-panel-text-padding: 0 16px 16px
+);
diff --git a/frontend-vue3/src/scss/tailwind.scss b/frontend-vue3/src/scss/tailwind.scss
new file mode 100644
index 0000000000..4f55e54c55
--- /dev/null
+++ b/frontend-vue3/src/scss/tailwind.scss
@@ -0,0 +1,45 @@
+// This will eventually be replaced by tailwind
+
+.whitespace-normal {
+ white-space: normal;
+}
+
+.gap-1 {
+ gap: 4px;
+}
+
+.gap-x-1 {
+ column-gap: 4px;
+}
+
+.gap-2 {
+ gap: 8px;
+}
+
+.gap-x-2 {
+ column-gap: 8px;
+}
+
+.gap-4 {
+ gap: 16px;
+}
+
+.gap-x-4 {
+ column-gap: 16px;
+}
+
+.flex-wrap-reverse {
+ flex-wrap: wrap-reverse;
+}
+
+.justify-items-start {
+ justify-items: start;
+}
+
+.justify-content-between {
+ justify-content: space-between;
+}
+
+.opacity-60 {
+ opacity: 0.6;
+}
diff --git a/frontend-vue3/src/test/mockEventClass.js b/frontend-vue3/src/test/mockEventClass.js
new file mode 100644
index 0000000000..aaa3f538d1
--- /dev/null
+++ b/frontend-vue3/src/test/mockEventClass.js
@@ -0,0 +1,27 @@
+import { beforeEach, afterEach } from 'vitest'
+/**
+ * @param { "ClipboardEvent" | "DragEvent" } eventName
+ */
+export function mockEventClass(eventName) {
+ const eventBackup = window[eventName]
+ const eventClass = class extends Event {
+ constructor(type, eventInitDict) {
+ // noinspection JSCheckFunctionSignatures
+ super(type, eventInitDict)
+ }
+ }
+
+ beforeEach(() => {
+ if (!eventBackup) {
+ window[eventName] = eventClass
+ } else {
+ console.error(
+ `you don't need to mock ${eventName} anymore, the test runner supports it now natively`
+ )
+ }
+ })
+
+ afterEach(() => {
+ window[eventName] = eventBackup
+ })
+}
diff --git a/frontend-vue3/src/test/renderWithVuetify.js b/frontend-vue3/src/test/renderWithVuetify.js
new file mode 100644
index 0000000000..f72d330685
--- /dev/null
+++ b/frontend-vue3/src/test/renderWithVuetify.js
@@ -0,0 +1,65 @@
+import { render as testingLibraryRender } from '@testing-library/vue'
+import i18n from '@/plugins/i18n/index.js'
+import dayjs from '@/plugins/dayjs.js'
+import Vue from 'vue'
+import Vuetify from 'vuetify'
+import VueI18n from '../plugins/i18n/index.js'
+import formBaseComponents from '@/plugins/formBaseComponents'
+import { Wrapper } from '@vue/test-utils'
+import { localize } from 'vee-validate'
+import Vuex from 'vuex'
+
+Vue.use(Vuetify)
+Vue.use(formBaseComponents)
+Vue.use(dayjs)
+Vue.use(Vuex)
+
+export const render = (component, options, callback) => {
+ const root = document.createElement('div')
+ root.setAttribute('data-app', 'true')
+
+ return testingLibraryRender(
+ component,
+ {
+ container: document.body.appendChild(root),
+ vuetify: new Vuetify(),
+ i18n,
+ ...options,
+ },
+ callback
+ )
+}
+
+/**
+ * Set up a Vuex Store
+ * @param {import('vuex').StoreOptions} storeOptions will be in the components this.$store
+ * @return store the Store object (pass this into the options on the render function)
+ */
+export const createVuexStore = (storeOptions) => {
+ return new Vuex.Store(storeOptions)
+}
+
+/**
+ * This function emulates the setLanguage mutation on the Vuex store,
+ * for use in tests which need to set the application language.
+ */
+export const setTestLocale = (locale) => {
+ const language = locale.substring(0, 2)
+ VueI18n.locale = locale
+ Vue.dayjs.locale(locale)
+ localize(language)
+}
+
+/**
+ * Wraps DOM nodes (such as the container object returned from a vue testing library render)
+ * in a vue-test-utils wrapper object, so it is processed by
+ */
+export const snapshotOf = (testingLibraryContainer) => {
+ if (!(testingLibraryContainer instanceof Element)) {
+ throw new Error(
+ 'snapshotOf expects a DOM element as argument, but received ' +
+ testingLibraryContainer.toString()
+ )
+ }
+ return new Wrapper(testingLibraryContainer)
+}
diff --git a/frontend-vue3/src/test/util.js b/frontend-vue3/src/test/util.js
new file mode 100644
index 0000000000..8980e4ec33
--- /dev/null
+++ b/frontend-vue3/src/test/util.js
@@ -0,0 +1,20 @@
+export function touch(element) {
+ const createTrigger = (eventName) => (clientX, clientY) => {
+ const touches = [{ clientX, clientY }]
+ const event = new Event(eventName)
+
+ event.touches = touches
+ event.changedTouches = touches
+ element.element.dispatchEvent(event)
+
+ return touch(element)
+ }
+
+ return {
+ start: createTrigger('touchstart'),
+ move: createTrigger('touchmove'),
+ end: createTrigger('touchend'),
+ }
+}
+
+export const waitForDebounce = () => new Promise((resolve) => setTimeout(resolve, 110))
diff --git a/frontend-vue3/src/views/CampCreate.vue b/frontend-vue3/src/views/CampCreate.vue
new file mode 100644
index 0000000000..b943f88cc8
--- /dev/null
+++ b/frontend-vue3/src/views/CampCreate.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/Camps.vue b/frontend-vue3/src/views/Camps.vue
new file mode 100644
index 0000000000..700c44c125
--- /dev/null
+++ b/frontend-vue3/src/views/Camps.vue
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ camp.title }}
+
+ {{ camp.name }} - {{ camp.motto }}
+
+
+
+
+
+ {{ $t('views.camps.create') }}
+
+
+
+
+
+
+
+
+ {{ $t('views.camps.prototypeCamps') }}
+
+
+
+
+
+ {{ camp.title }}
+
+ {{ camp.name }} - {{ camp.motto }}
+
+
+
+
+
+
+
+
+ {{ $t('views.camps.pastCamps') }}
+
+
+
+
+
+ {{ camp.title }}
+
+ {{ camp.name }} - {{ camp.motto }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/Invitations.vue b/frontend-vue3/src/views/Invitations.vue
new file mode 100644
index 0000000000..8d19f43416
--- /dev/null
+++ b/frontend-vue3/src/views/Invitations.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/NavigationDefault.vue b/frontend-vue3/src/views/NavigationDefault.vue
new file mode 100644
index 0000000000..91f9d2f63f
--- /dev/null
+++ b/frontend-vue3/src/views/NavigationDefault.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ {{ $t('global.navigation.help') }}
+ mdi-open-in-new
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/PageNotFound.vue b/frontend-vue3/src/views/PageNotFound.vue
new file mode 100644
index 0000000000..53d3c9edc2
--- /dev/null
+++ b/frontend-vue3/src/views/PageNotFound.vue
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-tent
+ {{ $t('views.pageNotFound.backToHome') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/Profile.vue b/frontend-vue3/src/views/Profile.vue
new file mode 100644
index 0000000000..f53a813b11
--- /dev/null
+++ b/frontend-vue3/src/views/Profile.vue
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('views.profile.changeEmail') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('global.button.logout') }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/admin/Checklist.vue b/frontend-vue3/src/views/admin/Checklist.vue
new file mode 100644
index 0000000000..c95ca66f55
--- /dev/null
+++ b/frontend-vue3/src/views/admin/Checklist.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/views/admin/Checklists.vue b/frontend-vue3/src/views/admin/Checklists.vue
new file mode 100644
index 0000000000..b55d55ed6a
--- /dev/null
+++ b/frontend-vue3/src/views/admin/Checklists.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/views/admin/Debug.vue b/frontend-vue3/src/views/admin/Debug.vue
new file mode 100644
index 0000000000..ab678065dc
--- /dev/null
+++ b/frontend-vue3/src/views/admin/Debug.vue
@@ -0,0 +1,116 @@
+
+
+
+
+ Debug
+
+
+
+
+
+
+ Version
+
+ {{ version }}
+
+ {{ deploymentTime }}
+
+
+
+
+
+ {{ key }}
+
+ {{ value }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/admin/SideBarAdmin.vue b/frontend-vue3/src/views/admin/SideBarAdmin.vue
new file mode 100644
index 0000000000..2c5bea4806
--- /dev/null
+++ b/frontend-vue3/src/views/admin/SideBarAdmin.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/Activate.vue b/frontend-vue3/src/views/auth/Activate.vue
new file mode 100644
index 0000000000..22b4d47248
--- /dev/null
+++ b/frontend-vue3/src/views/auth/Activate.vue
@@ -0,0 +1,83 @@
+
+
+ {{ $t('views.auth.activate.title') }}
+
+
+
+
+
+
+
+ {{ $t('views.auth.activate.success') }}
+
+
+
+ {{ $t('global.button.login') }}
+
+
+
+
+
+ {{ $t('views.auth.activate.error') }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/Login.vue b/frontend-vue3/src/views/auth/Login.vue
new file mode 100644
index 0000000000..8afc6c4752
--- /dev/null
+++ b/frontend-vue3/src/views/auth/Login.vue
@@ -0,0 +1,309 @@
+
+
+
+
+
+
+
+ {{ $t('global.button.login') }}
+
+
+
+
+
+
+
+ {
+ email = event.shiftKey ? 'admin@example.com' : 'test@example.com'
+ password = 'test'
+ login()
+ }
+ "
+ >
+ Login
+
+
+
+
+ {{ error }}
+ {{ $t('views.auth.login.passwordForgotten') }}
+
+ {{ $t('views.auth.login.resetPassword') }}
+
+
+ {{ $t('views.auth.login.notActivated') }}
+
+ {{ $t('views.auth.login.resendActivation') }}
+
+
+
+
+
+
+
+
+
+ {{ $t('views.auth.login.passwordForgotten') }}
+
+
+
+
+
+ $ecamp
+
+ {{ $t('views.auth.login.provider.ecamp') }}
+
+
+
+
+
+
+
+ {{ $t('views.auth.login.accountless') }}
+
+ {{ $t('views.auth.login.registernow') }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/LoginCallback.vue b/frontend-vue3/src/views/auth/LoginCallback.vue
new file mode 100644
index 0000000000..65d4d1eff2
--- /dev/null
+++ b/frontend-vue3/src/views/auth/LoginCallback.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ {{ $t('views.auth.loginCallback.loginInProgress') }}
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/NavigationAuth.vue b/frontend-vue3/src/views/auth/NavigationAuth.vue
new file mode 100644
index 0000000000..e32e5ef6ee
--- /dev/null
+++ b/frontend-vue3/src/views/auth/NavigationAuth.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+ mdi-script-text-outline
+ {{ $t('global.navigation.news') }}
+
+
+
+ mdi-help
+ {{ $t('global.navigation.help') }}
+
+
+
+
+ {{ $t('global.navigation.help') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/Register.vue b/frontend-vue3/src/views/auth/Register.vue
new file mode 100644
index 0000000000..4851b7a108
--- /dev/null
+++ b/frontend-vue3/src/views/auth/Register.vue
@@ -0,0 +1,236 @@
+
+
+ {{ $t('views.auth.register.title') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('views.auth.register.acceptTermsOfService') }}
+
+
+
+
+ mdi-open-in-new
+
+
+
+
+
+
+ *
+ {{ $t('views.auth.register.requiredField') }}
+
+
+
+
+
+
+ {{ $t('views.auth.register.register') }}
+
+
+
+
+
+
+
+
+ {{ $t('views.auth.register.alreadyHaveAnAccount') }}
+
+ {{ $t('global.button.login') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/RegisterDone.vue b/frontend-vue3/src/views/auth/RegisterDone.vue
new file mode 100644
index 0000000000..0fbcae25cf
--- /dev/null
+++ b/frontend-vue3/src/views/auth/RegisterDone.vue
@@ -0,0 +1,28 @@
+
+
+ {{ $t('views.auth.registerDone.title') }}
+
+
+ {{ $t('views.auth.registerDone.success') }}
+
+
+ {{ $t('views.auth.registerDone.message') }}
+
+
+
+
+ {{ $t('global.button.login') }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/ResendActivation.vue b/frontend-vue3/src/views/auth/ResendActivation.vue
new file mode 100644
index 0000000000..dcbdcb659a
--- /dev/null
+++ b/frontend-vue3/src/views/auth/ResendActivation.vue
@@ -0,0 +1,104 @@
+
+
+
+ {{ $t('views.auth.resendActivation.title') }}
+
+
+
+ {{ $t('views.auth.resendActivation.successMessage') }}
+
+
+
+ {{ $t('views.auth.resendActivation.errorMessage') }}
+
+
+
+
+
+
+ $ecamp
+
+ {{ $t('views.auth.resendActivation.send') }}
+
+
+
+
+
+
+ {{ $t('global.button.login') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/ResetPassword.vue b/frontend-vue3/src/views/auth/ResetPassword.vue
new file mode 100644
index 0000000000..354ea129d1
--- /dev/null
+++ b/frontend-vue3/src/views/auth/ResetPassword.vue
@@ -0,0 +1,179 @@
+
+
+
+ {{ $t('views.auth.resetPassword.title') }}
+
+
+
+
+
+
+
+ {{ $t('views.auth.resetPassword.invalidRequest') }}
+
+
+
+ {{ $t('views.auth.resetPassword.successMessage') }}
+
+
+
+ {{ $t('views.auth.resetPassword.errorMessage') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $ecamp
+
+ {{ $t('views.auth.resetPassword.send') }}
+
+
+
+
+
+
+
+
+ {{ $t('global.button.login') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/auth/ResetPasswordRequest.vue b/frontend-vue3/src/views/auth/ResetPasswordRequest.vue
new file mode 100644
index 0000000000..2deeb88487
--- /dev/null
+++ b/frontend-vue3/src/views/auth/ResetPasswordRequest.vue
@@ -0,0 +1,101 @@
+
+
+
+ {{ $t('views.auth.resetPasswordRequest.title') }}
+
+
+
+ {{ $t('views.auth.resetPasswordRequest.successMessage') }}
+
+
+
+ {{ $t('views.auth.resetPasswordRequest.errorMessage') }}
+
+
+
+
+
+
+ $ecamp
+
+ {{ $t('views.auth.resetPasswordRequest.send') }}
+
+
+
+
+
+
+ {{ $t('global.button.login') }}
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/CampProgram.vue b/frontend-vue3/src/views/camp/CampProgram.vue
new file mode 100644
index 0000000000..1df8b5d5ee
--- /dev/null
+++ b/frontend-vue3/src/views/camp/CampProgram.vue
@@ -0,0 +1,308 @@
+
+
+
+
+
+
+
+
+
+
+ mdi-filter
+ {{ filteredPropertiesCount }}
+
+
+
+ mdi-filter
+
+
+
+
+
+
+
+ mdi-dots-horizontal
+
+ mdi-dots-horizontal
+
+
+
+
+
+
+ mdi-filter
+
+
+ Filter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-lock
+ {{ reminderText }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/Dashboard.vue b/frontend-vue3/src/views/camp/Dashboard.vue
new file mode 100644
index 0000000000..a1cda5ef35
--- /dev/null
+++ b/frontend-vue3/src/views/camp/Dashboard.vue
@@ -0,0 +1,322 @@
+
+
+
+
+
+
+
+
+
+ {{ periods[uri].description }}
+
+
+
+
+
+ {{ $t('views.camp.dashboard.columns.number') }}
+
+
+ {{ $t('views.camp.dashboard.columns.category') }}
+
+
+ {{ $t('views.camp.dashboard.columns.time') }}
+
+
+ {{ $t('views.camp.dashboard.columns.title') }}
+
+
+ {{ $t('views.camp.dashboard.columns.responsible') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('views.camp.dashboard.noEntries') }}
+
+
+ {{ $t('views.camp.dashboard.welcome') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/Invitation.vue b/frontend-vue3/src/views/camp/Invitation.vue
new file mode 100644
index 0000000000..525d0255b0
--- /dev/null
+++ b/frontend-vue3/src/views/camp/Invitation.vue
@@ -0,0 +1,448 @@
+
+
+
+
$tentDay
+
+
+
+
+
+
+
+
+
+
+ {{
+ $t('views.camp.invitation.title')
+ }}
+ {{ invite?.campTitle }}
+
+ {{
+ $t('views.camp.invitation.successfullyRejected')
+ }}
+ {{
+ $t('views.camp.invitation.error')
+ }}
+ {{ $t('views.camp.invitation.notFound') }}
+
+
+
+
+ {{ $t('views.camp.invitation.userAlreadyInCamp') }}
+
+
+ {{ $t('views.camp.invitation.openCamp') }}
+
+
+ {{ $t('views.camp.invitation.useOtherAuth') }}
+
+
+
+
+
+ {{ $t('views.camp.invitation.acceptCurrentAuth') }}
+
+
+ {{ $t('views.camp.invitation.useOtherAuth') }}
+
+
+
+
+
+ {{ $t('global.button.login') }}
+
+
+ {{ $t('views.camp.invitation.register') }}
+
+
+
+ {{ $t('views.camp.invitation.reject') }}
+
+
+
+
+ mdi-tent
+ {{ $t('views.camp.invitation.backToHome') }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/Story.vue b/frontend-vue3/src/views/camp/Story.vue
new file mode 100644
index 0000000000..21accffd66
--- /dev/null
+++ b/frontend-vue3/src/views/camp/Story.vue
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/activity/Activity.vue b/frontend-vue3/src/views/camp/activity/Activity.vue
new file mode 100644
index 0000000000..d091798b31
--- /dev/null
+++ b/frontend-vue3/src/views/camp/activity/Activity.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/activity/SideBarProgram.vue b/frontend-vue3/src/views/camp/activity/SideBarProgram.vue
new file mode 100644
index 0000000000..cf53cf35a4
--- /dev/null
+++ b/frontend-vue3/src/views/camp/activity/SideBarProgram.vue
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/admin/Activity.vue b/frontend-vue3/src/views/camp/admin/Activity.vue
new file mode 100644
index 0000000000..80d34ce061
--- /dev/null
+++ b/frontend-vue3/src/views/camp/admin/Activity.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/admin/AdminMaterialLists.vue b/frontend-vue3/src/views/camp/admin/AdminMaterialLists.vue
new file mode 100644
index 0000000000..d5c3fc9091
--- /dev/null
+++ b/frontend-vue3/src/views/camp/admin/AdminMaterialLists.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+ {{ $t('global.button.create') }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/admin/Checklists.vue b/frontend-vue3/src/views/camp/admin/Checklists.vue
new file mode 100644
index 0000000000..2b67640e57
--- /dev/null
+++ b/frontend-vue3/src/views/camp/admin/Checklists.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/admin/Collaborators.vue b/frontend-vue3/src/views/camp/admin/Collaborators.vue
new file mode 100644
index 0000000000..1bcf86123c
--- /dev/null
+++ b/frontend-vue3/src/views/camp/admin/Collaborators.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/admin/Info.vue b/frontend-vue3/src/views/camp/admin/Info.vue
new file mode 100644
index 0000000000..ded0a8b925
--- /dev/null
+++ b/frontend-vue3/src/views/camp/admin/Info.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/admin/Print.vue b/frontend-vue3/src/views/camp/admin/Print.vue
new file mode 100644
index 0000000000..76ba0ee233
--- /dev/null
+++ b/frontend-vue3/src/views/camp/admin/Print.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+ mdi-file-restore-outline
+ {{ $t('global.button.reset') }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/admin/SideBarAdmin.vue b/frontend-vue3/src/views/camp/admin/SideBarAdmin.vue
new file mode 100644
index 0000000000..ebff6a7fc3
--- /dev/null
+++ b/frontend-vue3/src/views/camp/admin/SideBarAdmin.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/admin/__tests__/Admin.spec.js b/frontend-vue3/src/views/camp/admin/__tests__/Admin.spec.js
new file mode 100644
index 0000000000..655e5acc97
--- /dev/null
+++ b/frontend-vue3/src/views/camp/admin/__tests__/Admin.spec.js
@@ -0,0 +1,140 @@
+import { describe, expect, it } from 'vitest'
+import Vue from 'vue'
+import { fireEvent } from '@testing-library/vue'
+import { render } from '@/test/renderWithVuetify.js'
+import Admin from '../Info.vue'
+import flushPromises from 'flush-promises'
+
+describe('Admin view', () => {
+ it('shows the danger zone when the user has a manager role', async () => {
+ const camp = createCampWithRole('manager')
+ const { getByText } = render(Admin, {
+ props: {
+ camp,
+ },
+ routes: [],
+ store: createStoreObject(),
+ mocks: {
+ api: createApiMock(camp),
+ },
+ stubs: createStubs(),
+ })
+
+ await flushPromises()
+
+ const dangerZone = getByText('Gefahrenzone')
+
+ expect(dangerZone).toBeInTheDocument()
+ await fireEvent.click(dangerZone)
+ await Vue.nextTick()
+ expect(getByText('Lager löschen')).toBeInTheDocument()
+ })
+
+ it("doesn't show the danger zone when the user has a member role", async () => {
+ const camp = createCampWithRole('member')
+ const { queryByText } = render(Admin, {
+ props: {
+ camp,
+ },
+ routes: [],
+ store: createStoreObject(),
+ mocks: {
+ api: createApiMock(camp),
+ },
+ stubs: createStubs(),
+ })
+
+ await flushPromises()
+
+ expect(queryByText('Gefahrenzone')).not.toBeInTheDocument()
+ expect(queryByText('Lager löschen')).not.toBeInTheDocument()
+ })
+
+ it("doesn't show the danger zone when the user has the guest role", async () => {
+ const camp = createCampWithRole('guest')
+ const { queryByText } = render(Admin, {
+ props: {
+ camp,
+ },
+ routes: [],
+ store: createStoreObject(),
+ mocks: {
+ api: createApiMock(camp),
+ },
+ stubs: createStubs(),
+ })
+
+ await flushPromises()
+
+ expect(queryByText('Gefahrenzone')).not.toBeInTheDocument()
+ expect(queryByText('Lager löschen')).not.toBeInTheDocument()
+ })
+})
+
+const USER_URL = '/users/17d341a80579'
+
+const USER = {
+ _meta: {
+ self: USER_URL,
+ },
+}
+
+function createStoreObject() {
+ return {
+ state: {
+ auth: {
+ user: USER,
+ },
+ },
+ getters: {
+ getLoggedInUser: (state) => {
+ return state.auth.user
+ },
+ },
+ }
+}
+
+function createCampWithRole(role) {
+ return {
+ campCollaborations: () => ({
+ items: [
+ {
+ role: role,
+ user: () => USER,
+ _meta: {
+ loading: false,
+ },
+ },
+ ],
+ }),
+ materialLists: () => {},
+ progressLabels: () => {},
+ _meta: { load: Promise.resolve() },
+ }
+}
+
+function createApiMock(camp) {
+ const halJsonResponse = {
+ ...camp,
+ _meta: {
+ loading: false,
+ load: Promise.resolve(camp),
+ },
+ }
+ return {
+ reload: () => Promise.resolve(),
+ get: () => halJsonResponse,
+ }
+}
+
+function createStubs() {
+ return [
+ 'CampSettings',
+ 'CampAddress',
+ 'CampPeriods',
+ 'CampCategories',
+ 'CampActivityProgressLabels',
+ 'CampMaterialLists',
+ 'CampConditionalFields',
+ ]
+}
diff --git a/frontend-vue3/src/views/camp/category/Category.vue b/frontend-vue3/src/views/camp/category/Category.vue
new file mode 100644
index 0000000000..0dab270cab
--- /dev/null
+++ b/frontend-vue3/src/views/camp/category/Category.vue
@@ -0,0 +1,235 @@
+
+
+
+
+
+
+ {{ category.name }}
+
+
+
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+ mdi-content-copy
+
+
+ {{ $t('views.camp.category.category.copyCategory') }}
+
+
+
+
+
+
+
+ mdi-delete
+
+
+ {{ $t('views.camp.category.category.deleteCategory') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('views.camp.category.category.properties') }}
+
+
+
+
+
+
+
+
+
+
+ {{ $t('views.camp.category.category.template') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/category/SideBarCategory.vue b/frontend-vue3/src/views/camp/category/SideBarCategory.vue
new file mode 100644
index 0000000000..4cbc5bfc64
--- /dev/null
+++ b/frontend-vue3/src/views/camp/category/SideBarCategory.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ {{ category.name }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/checklist/Checklist.vue b/frontend-vue3/src/views/camp/checklist/Checklist.vue
new file mode 100644
index 0000000000..3cb1b5e70b
--- /dev/null
+++ b/frontend-vue3/src/views/camp/checklist/Checklist.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/checklist/SideBarChecklist.vue b/frontend-vue3/src/views/camp/checklist/SideBarChecklist.vue
new file mode 100644
index 0000000000..8c340f0e73
--- /dev/null
+++ b/frontend-vue3/src/views/camp/checklist/SideBarChecklist.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+ {{ checklist.name }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/checklistOverview/ChecklistLists.vue b/frontend-vue3/src/views/camp/checklistOverview/ChecklistLists.vue
new file mode 100644
index 0000000000..ac7b166dd9
--- /dev/null
+++ b/frontend-vue3/src/views/camp/checklistOverview/ChecklistLists.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+ {{ checklist.name }}
+
+
+ mdi-chevron-right
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/checklistOverview/ChecklistOverview.vue b/frontend-vue3/src/views/camp/checklistOverview/ChecklistOverview.vue
new file mode 100644
index 0000000000..8a9980ffa9
--- /dev/null
+++ b/frontend-vue3/src/views/camp/checklistOverview/ChecklistOverview.vue
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/checklistOverview/SideBarChecklistOverview.vue b/frontend-vue3/src/views/camp/checklistOverview/SideBarChecklistOverview.vue
new file mode 100644
index 0000000000..ee0e464834
--- /dev/null
+++ b/frontend-vue3/src/views/camp/checklistOverview/SideBarChecklistOverview.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+ {{ checklist.name }}
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/material/MaterialDetail.vue b/frontend-vue3/src/views/camp/material/MaterialDetail.vue
new file mode 100644
index 0000000000..95d61fa5d0
--- /dev/null
+++ b/frontend-vue3/src/views/camp/material/MaterialDetail.vue
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
+ mdi-pencil
+
+ {{
+ $t('global.button.edit')
+ }}
+
+
+
+
+
+ mdi-microsoft-excel
+
+ {{
+ $t('global.button.download')
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/material/MaterialLists.vue b/frontend-vue3/src/views/camp/material/MaterialLists.vue
new file mode 100644
index 0000000000..080166c37f
--- /dev/null
+++ b/frontend-vue3/src/views/camp/material/MaterialLists.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+ {{ $t('global.button.create') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/material/MaterialOverview.vue b/frontend-vue3/src/views/camp/material/MaterialOverview.vue
new file mode 100644
index 0000000000..76c44fd076
--- /dev/null
+++ b/frontend-vue3/src/views/camp/material/MaterialOverview.vue
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
+ mdi-plus
+
+ {{ $t('views.camp.material.materialOverview.createNewList') }}
+
+
+
+
+
+
+ mdi-microsoft-excel
+
+ {{ $t('views.camp.material.materialOverview.download') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/material/SideBarMaterialLists.vue b/frontend-vue3/src/views/camp/material/SideBarMaterialLists.vue
new file mode 100644
index 0000000000..d413ade612
--- /dev/null
+++ b/frontend-vue3/src/views/camp/material/SideBarMaterialLists.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/navigation/NavigationCamp.vue b/frontend-vue3/src/views/camp/navigation/NavigationCamp.vue
new file mode 100644
index 0000000000..7e0716f4af
--- /dev/null
+++ b/frontend-vue3/src/views/camp/navigation/NavigationCamp.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/navigation/desktop/NavTopbar.vue b/frontend-vue3/src/views/camp/navigation/desktop/NavTopbar.vue
new file mode 100644
index 0000000000..cf7fd77559
--- /dev/null
+++ b/frontend-vue3/src/views/camp/navigation/desktop/NavTopbar.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('global.navigation.help') }}
+ mdi-open-in-new
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/navigation/mobile/NavBottombar.vue b/frontend-vue3/src/views/camp/navigation/mobile/NavBottombar.vue
new file mode 100644
index 0000000000..ca8389530a
--- /dev/null
+++ b/frontend-vue3/src/views/camp/navigation/mobile/NavBottombar.vue
@@ -0,0 +1,65 @@
+
+
+
+ {{ $t('views.camp.navigation.mobile.navBottombar.program') }}
+ mdi-view-dashboard
+
+
+ {{ $t('views.camp.navigation.mobile.navBottombar.story') }}
+ mdi-book-open-variant
+
+
+ {{ camp.name }}
+ mdi-tent
+
+
+ {{ $t('views.camp.navigation.mobile.navBottombar.material') }}
+ mdi-package-variant
+
+
+ {{ $t('views.camp.navigation.mobile.navBottombar.more') }}
+ mdi-menu
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/camp/navigation/mobile/NavSidebar.vue b/frontend-vue3/src/views/camp/navigation/mobile/NavSidebar.vue
new file mode 100644
index 0000000000..952e01729f
--- /dev/null
+++ b/frontend-vue3/src/views/camp/navigation/mobile/NavSidebar.vue
@@ -0,0 +1,174 @@
+
+
+
+
+ $ecamp
+
eCamp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('views.camp.navigation.mobile.navSidebar.itemClose') }}
+ mdi-close
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/dev/Controls.vue b/frontend-vue3/src/views/dev/Controls.vue
new file mode 100644
index 0000000000..19fffd3391
--- /dev/null
+++ b/frontend-vue3/src/views/dev/Controls.vue
@@ -0,0 +1,314 @@
+
+
+
+
+
+
+
+
+ Input Table
+
+
+ {{ item.id }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/src/views/dev/Performance.vue b/frontend-vue3/src/views/dev/Performance.vue
new file mode 100644
index 0000000000..0091d98f5e
--- /dev/null
+++ b/frontend-vue3/src/views/dev/Performance.vue
@@ -0,0 +1,88 @@
+
+
+
+
+ {{ numberformat.format(item.collection) }} ms
+ {{ numberformat.format(item.entity) }} ms
+
+
+
+
+
+
+
+
diff --git a/frontend-vue3/tests/globalSetup.js b/frontend-vue3/tests/globalSetup.js
new file mode 100644
index 0000000000..4768a356ff
--- /dev/null
+++ b/frontend-vue3/tests/globalSetup.js
@@ -0,0 +1,3 @@
+export function setup() {
+ process.env.TZ = 'Pacific/Tongatapu'
+}
diff --git a/frontend-vue3/tests/infrastructure/package-lock.spec.js b/frontend-vue3/tests/infrastructure/package-lock.spec.js
new file mode 100644
index 0000000000..e6463eaeb8
--- /dev/null
+++ b/frontend-vue3/tests/infrastructure/package-lock.spec.js
@@ -0,0 +1,8 @@
+import { describe, test, expect } from 'vitest'
+import { lockfileVersion } from '../../package-lock.json'
+
+describe('The package-lock.json', () => {
+ test('uses lockfileVersion 3', () => {
+ expect(lockfileVersion).toBe(3)
+ })
+})
diff --git a/frontend-vue3/tests/setup.js b/frontend-vue3/tests/setup.js
new file mode 100644
index 0000000000..09a5fed2ad
--- /dev/null
+++ b/frontend-vue3/tests/setup.js
@@ -0,0 +1,12 @@
+import { expect, afterEach } from 'vitest'
+import { cleanup } from '@testing-library/vue'
+import '@testing-library/jest-dom/vitest'
+import snapshotSerializer from 'jest-serializer-vue-tjw'
+import 'vitest-canvas-mock'
+
+// runs a cleanup after each test case (e.g. clearing jsdom)
+afterEach(() => {
+ cleanup()
+})
+
+expect.addSnapshotSerializer(snapshotSerializer)
diff --git a/frontend-vue3/vite.config.js b/frontend-vue3/vite.config.js
new file mode 100644
index 0000000000..39aa34abcf
--- /dev/null
+++ b/frontend-vue3/vite.config.js
@@ -0,0 +1,203 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import { comlink } from 'vite-plugin-comlink'
+import * as path from 'path'
+import Components from 'unplugin-vue-components/vite'
+import { sentryVitePlugin } from '@sentry/vite-plugin'
+import { configDefaults } from 'vitest/config'
+import svgLoader from 'vite-svg-loader'
+import Vuetify from 'vite-plugin-vuetify'
+
+const plugins = [
+ comlink(), // must be first
+ vue({
+ template: {
+ compilerOptions: {
+ compatConfig: {
+ MODE: 2,
+ },
+ },
+ },
+ }),
+ Components({
+ resolvers: [],
+ }),
+ svgLoader(),
+ Vuetify({
+ autoImport: {
+ labs: true,
+ },
+ styles: { configFile: 'src/scss/settings.scss' },
+ }),
+]
+const sentryAuthToken = process.env.SENTRY_AUTH_TOKEN
+if (sentryAuthToken) {
+ plugins.push(
+ sentryVitePlugin({
+ authToken: sentryAuthToken,
+ org: process.env.SENTRY_ORG || 'ecamp',
+ project: process.env.SENTRY_FRONTEND_PROJECT || 'ecamp3-frontend',
+ telemetry: false,
+ sourcemaps: {
+ assets: ['./dist/**/*'],
+ },
+ release: {
+ name: process.env.SENTRY_RELEASE_NAME || 'development',
+ },
+ })
+ )
+}
+
+export default defineConfig(({ mode }) => ({
+ server: {
+ port: 3000,
+ allowedHosts: ['frontend-vue3', 'localhost:3000'],
+ },
+ plugins,
+ worker: {
+ plugins: () => [comlink()],
+ },
+ optimizeDeps: {
+ include: [
+ '@intlify/core',
+ '@react-pdf/font',
+ '@react-pdf/layout',
+ '@react-pdf/pdfkit',
+ '@react-pdf/primitives',
+ '@react-pdf/render',
+ '@sentry/browser',
+ '@sentry/vue',
+ '@tiptap/pm/state',
+ '@tiptap/pm/view',
+ '@zxcvbn-ts/core',
+ '@zxcvbn-ts/language-common',
+ '@zxcvbn-ts/language-de',
+ '@zxcvbn-ts/language-en',
+ '@zxcvbn-ts/language-fr',
+ '@zxcvbn-ts/language-it',
+ 'colorjs.io',
+ 'comlink',
+ 'core-js/modules/es.array.concat.js',
+ 'core-js/modules/es.array.find.js',
+ 'core-js/modules/es.array.push.js',
+ 'core-js/modules/es.array.slice.js',
+ 'core-js/modules/es.array.splice.js',
+ 'core-js/modules/es.function.name.js',
+ 'core-js/modules/es.object.to-string.js',
+ 'core-js/modules/es.regexp.exec.js',
+ 'core-js/modules/es.regexp.test.js',
+ 'core-js/modules/es.symbol.description.js',
+ 'core-js/modules/es.symbol.js',
+ 'dayjs',
+ 'dayjs/locale/de',
+ 'dayjs/locale/de-ch',
+ 'dayjs/locale/fr',
+ 'dayjs/locale/it',
+ 'dayjs/plugin/customParseFormat',
+ 'dayjs/plugin/isBetween',
+ 'dayjs/plugin/isSameOrBefore',
+ 'dayjs/plugin/isSameOrAfter',
+ 'dayjs/plugin/localizedFormat',
+ 'dayjs/plugin/timezone',
+ 'dayjs/plugin/utc',
+ 'file-saver',
+ 'linkify-it',
+ 'lodash/camelCase.js',
+ 'lodash/cloneDeep.js',
+ 'lodash/groupBy.js',
+ 'lodash/keyBy.js',
+ 'lodash/sortBy.js',
+ 'lodash/minBy.js',
+ 'lodash/maxBy.js',
+ 'lodash/size.js',
+ 'runes',
+ 'vee-validate',
+ 'vite-plugin-comlink/symbol',
+ 'vue',
+ 'vuedraggable',
+ 'vue-toastification',
+ // 'vuetify/es5/components/VCalendar/modes/column.js',
+ // 'vuetify/es5/components/VCalendar/util/events.js',
+ ],
+ },
+ build: {
+ sourcemap: true,
+ minify: mode === 'development' ? false : 'esbuild',
+ rollupOptions: {
+ external: ['vuetify/lib'],
+ },
+ },
+ resolve: {
+ alias: [
+ // webpack alias @ (import in Vue files)
+ {
+ find: '~@',
+ replacement: path.resolve(__dirname, 'src'),
+ },
+ {
+ find: '@',
+ replacement: path.resolve(__dirname, 'src'),
+ },
+
+ // individual webpack aliases for ~ (node modules)
+ {
+ find: '~@mdi',
+ replacement: path.resolve(__dirname, 'node_modules', '@mdi'),
+ },
+ {
+ find: '~inter-ui',
+ replacement: path.resolve(__dirname, 'node_modules', 'inter-ui'),
+ },
+
+ // find dayjs from commons
+ {
+ find: 'dayjs',
+ replacement: path.resolve(__dirname, 'node_modules', 'dayjs'),
+ },
+ ],
+ preserveSymlinks: true,
+ },
+ css: {
+ preprocessorOptions: {
+ scss: {
+ // additionalData: '@import "./node_modules/vuetify/src/styles/styles.sass";\n', // original default variables from vuetify
+ },
+ sass: {
+ // additionalData: '@import "./src/scss/variables.scss"\n', // vuetify variable overrides
+ },
+ // scss: {
+ // additionalData: `
+ // // original default variables from vuetify
+ // @import "./node_modules/vuetify/lib/styles/settings/_variables.scss";
+ // @import "./node_modules/vuetify/lib/styles/settings/_colors.scss";
+ // @import "./node_modules/vuetify/dist/_component-variables.sass";
+ // @import "./node_modules/vuetify/dist/_component-variables-labs.sass";
+ // `,
+ // },
+ // sass: {
+ // additionalData: '@import "./src/scss/variables.scss"\n', // vuetify variable overrides
+ // },
+ },
+ },
+ test: {
+ environment: 'jsdom',
+ alias: [{ find: /^vue$/, replacement: 'vue/dist/vue.runtime.common.js' }],
+ globalSetup: './tests/globalSetup.js',
+ setupFiles: './tests/setup.js',
+ maxWorkers: 1,
+ minWorkers: 1,
+ coverage: {
+ all: true,
+ exclude: [...configDefaults.coverage.exclude, '**/src/pdf/**'],
+ reporter: ['text', 'lcov', 'html'],
+ reportsDirectory: './data/coverage',
+ },
+ deps: {
+ optimizer: {
+ web: {
+ exclude: ['vue'],
+ },
+ },
+ },
+ },
+}))
diff --git a/frontend-vue3/vue.config.js b/frontend-vue3/vue.config.js
new file mode 100644
index 0000000000..2c74438f9d
--- /dev/null
+++ b/frontend-vue3/vue.config.js
@@ -0,0 +1,26 @@
+export const pluginOptions = {
+ jestSerializer: {
+ attributesToClear: ['id', 'for'],
+ formatting: {
+ indent_char: ' ',
+ indent_inner_html: true,
+ indent_size: 5,
+ inline: [],
+ sep: '\n',
+ wrap_attributes: 'force-aligned',
+ },
+ },
+}
+
+export default {
+ devServer: {
+ useLocalIp: false,
+ allowedHosts: ['ecamp3', 'localhost', '127.0.0.1'],
+ },
+
+ transpileDependencies: ['vuetify'],
+ pluginOptions,
+ css: {
+ sourceMap: true,
+ },
+}
diff --git a/frontend/src/router.js b/frontend/src/router.js
index 0c6afd0333..1c02c9e5d7 100644
--- a/frontend/src/router.js
+++ b/frontend/src/router.js
@@ -16,7 +16,7 @@ const GenericPage = () => import('./components/generic/GenericPage.vue')
/* istanbul ignore next */
export default new Router({
mode: 'history',
- base: '/',
+ base: '/old',
routes: [
...(getEnv().FEATURE_DEVELOPER
? [
diff --git a/frontend/vite.config.js b/frontend/vite.config.js
index 6220af50c8..7998d0e3e9 100644
--- a/frontend/vite.config.js
+++ b/frontend/vite.config.js
@@ -38,6 +38,7 @@ if (sentryAuthToken) {
}
export default defineConfig(({ mode }) => ({
+ base: "/old",
server: {
port: 3000,
allowedHosts: ['frontend', 'localhost:3000'],
diff --git a/print/package-lock.json b/print/package-lock.json
index 2d0ae83600..770bbda9db 100644
--- a/print/package-lock.json
+++ b/print/package-lock.json
@@ -182,7 +182,6 @@
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.3",
@@ -734,7 +733,6 @@
}
],
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=18"
},
@@ -779,7 +777,6 @@
}
],
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=18"
}
@@ -2769,7 +2766,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
"license": "Apache-2.0",
- "peer": true,
"engines": {
"node": ">=8.0.0"
}
@@ -2791,7 +2787,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz",
"integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==",
"license": "Apache-2.0",
- "peer": true,
"engines": {
"node": ">=14"
},
@@ -2804,7 +2799,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz",
"integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@opentelemetry/semantic-conventions": "1.28.0"
},
@@ -2829,7 +2823,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz",
"integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@opentelemetry/api-logs": "0.57.2",
"@types/shimmer": "^1.2.0",
@@ -3235,7 +3228,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz",
"integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@opentelemetry/core": "1.30.1",
"@opentelemetry/semantic-conventions": "1.28.0"
@@ -3261,7 +3253,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz",
"integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@opentelemetry/core": "1.30.1",
"@opentelemetry/resources": "1.30.1",
@@ -3288,7 +3279,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.37.0.tgz",
"integrity": "sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==",
"license": "Apache-2.0",
- "peer": true,
"engines": {
"node": ">=14"
}
@@ -5298,8 +5288,7 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@types/mysql": {
"version": "2.15.26",
@@ -5545,7 +5534,6 @@
"integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.45.0",
"@typescript-eslint/types": "8.45.0",
@@ -5913,7 +5901,6 @@
"integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.45.0",
@@ -6643,7 +6630,6 @@
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz",
"integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/parser": "^7.28.4",
"@vue/compiler-core": "3.5.22",
@@ -6850,7 +6836,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -7251,8 +7236,7 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz",
"integrity": "sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==",
- "license": "Apache-2.0",
- "peer": true
+ "license": "Apache-2.0"
},
"node_modules/bare-fs": {
"version": "4.4.5",
@@ -7462,7 +7446,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.9",
"caniuse-lite": "^1.0.30001746",
@@ -8746,8 +8729,7 @@
"version": "0.0.1495869",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1495869.tgz",
"integrity": "sha512-i+bkd9UYFis40RcnkW7XrOprCujXRAHg62IVh/Ah3G8MmNXpCGt1m0dTFhSdx/AVs8XEMbdOGRwdkR1Bcta8AA==",
- "license": "BSD-3-Clause",
- "peer": true
+ "license": "BSD-3-Clause"
},
"node_modules/didyoumean": {
"version": "1.2.2",
@@ -9061,7 +9043,6 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
- "peer": true,
"bin": {
"esbuild": "bin/esbuild"
},
@@ -9153,7 +9134,6 @@
"integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -9247,7 +9227,6 @@
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -13641,7 +13620,6 @@
"integrity": "sha512-uc47XrtHwkBoES4HFgwgfH9sqwAtJXgAIBq4fFBMZ4hWmgVZoExyn+L4g4VuaecVKXkz1bvlaHcfwHAJPQb5Gw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@oxc-project/types": "^0.87.0"
},
@@ -13887,7 +13865,6 @@
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
@@ -13936,7 +13913,6 @@
"integrity": "sha512-iceu9s70mZyjKs6V2QX7TURkJj1crnKi9csGByWvOWwrR5rwq0U0f49yIlRAzMP4t7K2gRC1MnyMZggMhiwAVg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@oxc-project/types": "^0.81.0"
},
@@ -14426,7 +14402,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -14912,7 +14887,6 @@
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -15318,7 +15292,6 @@
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -15930,7 +15903,6 @@
"integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -16168,7 +16140,6 @@
"integrity": "sha512-j4GMCTa8elGyN9A7x7bEglx0VgSpNUG4W4wNedQ33wSMdnkqQCT8HTwOaVSV4e6yQovcu/3Oc4coJP/l0xhL2Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"chokidar": "^4.0.0",
"immutable": "^5.0.2",
@@ -17132,7 +17103,6 @@
"integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
@@ -17615,7 +17585,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -17862,7 +17831,6 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"napi-postinstall": "^0.3.0"
},
@@ -18127,7 +18095,6 @@
"integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
@@ -18361,7 +18328,6 @@
"integrity": "sha512-3Yc7K2R/RrONB9JtwEh2Y40YP3tQi/3UiNHrwcYDsDBKDKnEu7B8PwmXLm7piDFRbxcnTPvgrV2LZnBpKP8JUw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@rollup/pluginutils": "^5.2.0",
"debug": "^4.4.1"
@@ -18543,7 +18509,6 @@
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/chai": "^5.2.2",
"@vitest/expect": "3.2.4",
@@ -18630,7 +18595,6 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz",
"integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.22",
"@vue/compiler-sfc": "3.5.22",
@@ -18677,7 +18641,6 @@
"integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"debug": "^4.4.0",
"eslint-scope": "^8.2.0",
@@ -18715,7 +18678,6 @@
"integrity": "sha512-BnstPj3KLHLrsqbVU2UOrPmr0+Mv11bsUZG0PyCOzsawCivk8W00GMXHeVUWIDOgNaScCuZah47CZFE+Wnl8mw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@intlify/core-base": "11.1.12",
"@intlify/shared": "11.1.12",
@@ -18737,7 +18699,6 @@
"integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@vue/devtools-api": "^6.6.4"
},
diff --git a/reverse-proxy-nginx.conf b/reverse-proxy-nginx.conf
index 114ceaed2c..d84c642922 100644
--- a/reverse-proxy-nginx.conf
+++ b/reverse-proxy-nginx.conf
@@ -20,41 +20,61 @@ http {
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
-
+
upstream frontend {
server frontend:3000;
}
-
+
+ upstream frontend-prototype {
+ server frontend-prototype:3333;
+ }
+
+ upstream frontend-vue3 {
+ server frontend-vue3:3000;
+ }
+
upstream api {
server api:3001;
}
-
+
upstream http-cache {
server http-cache:8080;
}
-
+
upstream print {
server print:3003;
}
-
+
upstream mail {
server mail:1080;
}
-
+
upstream pgadmin {
server pg-admin:80;
}
-
+
server {
listen 3000;
server_name localhost;
location / {
+ proxy_pass http://frontend-vue3;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ }
+
+ location /old {
proxy_pass http://frontend;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
-
+
+ location /prototype/ {
+ proxy_pass http://frontend-prototype;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ }
+
location /api/ {
# the Set-Cookie: XDEBUG_SESSION=PHPSTORM; path=/; SameSite=Lax header is set too many times
# temporary workaround from https://stackoverflow.com/a/27551259
@@ -67,13 +87,13 @@ http {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
-
+
location /print {
proxy_pass http://print;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
-
+
location /mail {
proxy_pass http://mail;
proxy_set_header Upgrade $http_upgrade;
@@ -92,11 +112,23 @@ http {
server_name localhost;
location / {
+ proxy_pass http://frontend-vue3;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ }
+
+ location /old/ {
proxy_pass http://frontend;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
-
+
+ location /prototype/ {
+ proxy_pass http://frontend-prototype;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ }
+
location /api/ {
# the Set-Cookie: XDEBUG_SESSION=PHPSTORM; path=/; SameSite=Lax header is set too many times
# temporary workaround from https://stackoverflow.com/a/27551259
@@ -109,13 +141,13 @@ http {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
-
+
location /print {
proxy_pass http://print;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
-
+
location /mail {
proxy_pass http://mail;
proxy_set_header Upgrade $http_upgrade;