diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 263e5eb89..000000000 --- a/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -/dist -/src-capacitor -/src-cordova -/.quasar -/node_modules -.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 5c33d2118..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,75 +0,0 @@ -export default { - // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy - // This option interrupts the configuration hierarchy at this file - // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos) - root: true, - - parserOptions: { - ecmaVersion: '2021', // Allows for the parsing of modern ECMAScript features - }, - - env: { - node: true, - browser: true, - 'vue/setup-compiler-macros': true, - }, - - // Rules order is important, please avoid shuffling them - extends: [ - // Base ESLint recommended rules - 'eslint:recommended', - - // Uncomment any of the lines below to choose desired strictness, - // but leave only one uncommented! - // See https://eslint.vuejs.org/rules/#available-rules - // 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention) - 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability) - // 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead) - - // https://github.com/prettier/eslint-config-prettier#installation - // usage with Prettier, provided by 'eslint-config-prettier'. - 'prettier', - ], - - plugins: [ - // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files - // required to lint *.vue files - 'vue', - - // https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674 - // Prettier has not been included as plugin to avoid performance impact - // add it as an extension for your IDE - ], - - globals: { - ga: 'readonly', // Google Analytics - cordova: 'readonly', - __statics: 'readonly', - __QUASAR_SSR__: 'readonly', - __QUASAR_SSR_SERVER__: 'readonly', - __QUASAR_SSR_CLIENT__: 'readonly', - __QUASAR_SSR_PWA__: 'readonly', - process: 'readonly', - Capacitor: 'readonly', - chrome: 'readonly', - }, - - // add your custom rules here - rules: { - 'prefer-promise-reject-errors': 'off', - 'no-unused-vars': 'warn', - 'vue/no-multiple-template-root': 'off', - // allow debugger during development only - 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', - }, - overrides: [ - { - files: ['test/cypress/**/*.*'], - extends: [ - // Add Cypress-specific lint rules, globals and Cypress plugin - // See https://github.com/cypress-io/eslint-plugin-cypress#rules - 'plugin:cypress/recommended', - ], - }, - ], -}; diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..ba1902263 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["plugin:cypress/recommended"] +} diff --git a/Jenkinsfile b/Jenkinsfile index 05ef34791..a9db9d369 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -125,8 +125,10 @@ pipeline { sh "docker-compose ${env.COMPOSE_PARAMS} pull db" sh "docker-compose ${env.COMPOSE_PARAMS} up -d" + def modules = sh(script: 'node test/cypress/docker/find/find.js', returnStdout: true).trim() + echo "E2E MODULES: ${modules}" image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") { - sh 'sh test/cypress/cypressParallel.sh 1' + sh "sh test/cypress/docker/cypressParallel.sh 1 '${modules}'" } } } @@ -183,3 +185,4 @@ pipeline { } } } + diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..70f738bbe --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,87 @@ +import cypress from 'eslint-plugin-cypress'; +import eslint from 'eslint-plugin-import'; +import globals from 'globals'; +import js from '@eslint/js'; +import vue from 'eslint-plugin-vue'; +export default { + plugins: { vue, eslint, cypress }, + languageOptions: { + globals: { + ...globals.node, + ...globals.browser, + ...vue.configs['vue3-strongly-recommended'].globals, + ...cypress.environments.globals.globals, + ga: 'readonly', + cordova: 'readonly', + __statics: 'readonly', + __QUASAR_SSR__: 'readonly', + __QUASAR_SSR_SERVER__: 'readonly', + __QUASAR_SSR_CLIENT__: 'readonly', + __QUASAR_SSR_PWA__: 'readonly', + process: 'readonly', + Capacitor: 'readonly', + chrome: 'readonly', + }, + + ecmaVersion: 2020, + sourceType: 'module', + + parserOptions: { + parser: '@babel/eslint-parser', + }, + }, + rules: { + ...vue.rules['flat/strongly-recommended'], + ...js.configs.recommended.rules, + semi: 'off', + 'generator-star-spacing': 'warn', + 'arrow-parens': 'warn', + 'no-var': 'error', + 'prefer-const': 'error', + 'prefer-template': 'warn', + 'prefer-destructuring': 'off', + 'prefer-spread': 'warn', + 'prefer-rest-params': 'warn', + 'prefer-object-spread': 'warn', + 'prefer-arrow-callback': 'warn', + 'prefer-numeric-literals': 'warn', + 'prefer-exponentiation-operator': 'warn', + 'prefer-regex-literals': 'warn', + 'one-var': [ + 'error', + { + let: 'never', + const: 'never', + }, + ], + 'no-void': 'off', + 'prefer-promise-reject-errors': 'error', + 'multiline-ternary': 'warn', + 'no-restricted-imports': 'warn', + 'no-import-assign': 'warn', + 'no-duplicate-imports': 'warn', + 'no-useless-rename': 'warn', + 'eslint/no-named-as-default': 'warn', + 'eslint/no-named-as-default-member': 'warn', + 'no-unsafe-optional-chaining': 'warn', + 'no-undef': 'error', + 'no-unused-vars': 'error', + 'no-console': 'error', + 'no-debugger': 'error', + 'no-useless-escape': 'error', + 'no-prototype-builtins': 'error', + 'no-async-promise-executor': 'error', + 'no-irregular-whitespace': 'error', + 'no-constant-condition': 'error', + 'no-unsafe-finally': 'error', + 'no-extend-native': 'error', + }, + ignores: [ + '/dist', + '/src-capacitor', + '/src-cordova', + '/.quasar', + '/node_modules', + '.eslintrc.js', + ], +}; diff --git a/package.json b/package.json index 017412ef2..ccff022cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-front", - "version": "25.14.0", + "version": "25.16.0", "description": "Salix frontend", "productName": "Salix", "author": "Verdnatura", @@ -9,7 +9,8 @@ "type": "module", "scripts": { "resetDatabase": "cd ../salix && gulp docker", - "lint": "eslint --ext .js,.vue ./", + "lint": "eslint \"**/*.{vue,js}\" ", + "lint:fix": "eslint \"**/*.{vue,js}\" --fix ", "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore", "test:e2e": "cypress open", "test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run", @@ -31,38 +32,47 @@ "axios": "^1.4.0", "chromium": "^3.0.3", "croppie": "^2.6.5", + "es-module-lexer": "^1.6.0", + "fast-glob": "^3.3.3", "moment": "^2.30.1", "pinia": "^2.1.3", "quasar": "^2.17.7", "validator": "^13.9.0", "vue": "^3.5.13", - "vue-i18n": "^9.3.0", + "vue-i18n": "^9.4.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "^9.20.0", "vue-router": "^4.2.5" }, "devDependencies": { "@commitlint/cli": "^19.2.1", "@commitlint/config-conventional": "^19.1.0", - "@intlify/unplugin-vue-i18n": "^0.8.2", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "^9.20.0", + "@intlify/unplugin-vue-i18n": "^4.0.0", "@pinia/testing": "^0.1.2", "@quasar/app-vite": "^2.0.8", "@quasar/quasar-app-extension-qcalendar": "^4.0.2", "@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0", + "@vue/compiler-sfc": "^3.5.13", "@vue/test-utils": "^2.4.4", "autoprefixer": "^10.4.14", "cypress": "^14.1.0", "cypress-mochawesome-reporter": "^3.8.2", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", + "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-cypress": "^4.1.0", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-vue": "^9.32.0", + "globals": "^16.0.0", "husky": "^8.0.0", "junit-merge": "^2.0.0", "mocha": "^11.1.0", "postcss": "^8.4.23", "prettier": "^3.4.2", "sass": "^1.83.4", - "vitepress": "^1.6.3", - "vitest": "^0.34.0", + "vitest": "^3.0.3", "xunit-viewer": "^10.6.1" }, "engines": { @@ -76,4 +86,4 @@ "vite": "^6.0.11", "vitest": "^0.31.1" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 51fc75469..35b1a9ea8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,39 +5,51 @@ settings: excludeLinksFromLockfile: false dependencies: + '@eslint/eslintrc': + specifier: ^3.2.0 + version: 3.3.1 + '@eslint/js': + specifier: ^9.20.0 + version: 9.24.0 '@quasar/cli': specifier: ^2.4.1 - version: 2.4.1 + version: 2.5.0 '@quasar/extras': specifier: ^1.16.16 version: 1.16.17 axios: specifier: ^1.4.0 - version: 1.7.9 + version: 1.8.4 chromium: specifier: ^3.0.3 version: 3.0.3 croppie: specifier: ^2.6.5 version: 2.6.5 + es-module-lexer: + specifier: ^1.6.0 + version: 1.6.0 + fast-glob: + specifier: ^3.3.3 + version: 3.3.3 moment: specifier: ^2.30.1 version: 2.30.1 pinia: specifier: ^2.1.3 - version: 2.3.1(typescript@5.7.3)(vue@3.5.13) + version: 2.3.1(typescript@5.8.3)(vue@3.5.13) quasar: specifier: ^2.17.7 - version: 2.17.7 + version: 2.18.1 validator: specifier: ^13.9.0 - version: 13.12.0 + version: 13.15.0 vue: specifier: ^3.5.13 - version: 3.5.13(typescript@5.7.3) + version: 3.5.13(typescript@5.8.3) vue-i18n: - specifier: ^9.3.0 - version: 9.14.2(vue@3.5.13) + specifier: ^9.4.0 + version: 9.14.4(vue@3.5.13) vue-router: specifier: ^4.2.5 version: 4.5.0(vue@3.5.13) @@ -45,49 +57,61 @@ dependencies: devDependencies: '@commitlint/cli': specifier: ^19.2.1 - version: 19.7.1(@types/node@22.13.5)(typescript@5.7.3) + version: 19.8.0(@types/node@22.14.0)(typescript@5.8.3) '@commitlint/config-conventional': specifier: ^19.1.0 - version: 19.7.1 + version: 19.8.0 '@intlify/unplugin-vue-i18n': - specifier: ^0.8.2 - version: 0.8.2(vue-i18n@9.14.2) + specifier: ^4.0.0 + version: 4.0.0(vue-i18n@9.14.4) '@pinia/testing': specifier: ^0.1.2 version: 0.1.7(pinia@2.3.1)(vue@3.5.13) '@quasar/app-vite': specifier: ^2.0.8 - version: 2.1.0(@types/node@22.13.5)(eslint@9.20.1)(pinia@2.3.1)(quasar@2.17.7)(sass@1.85.0)(typescript@5.7.3)(vue-router@4.5.0)(vue@3.5.13) + version: 2.2.0(@types/node@22.14.0)(eslint@9.24.0)(pinia@2.3.1)(quasar@2.18.1)(sass@1.86.3)(typescript@5.8.3)(vue-router@4.5.0)(vue@3.5.13) '@quasar/quasar-app-extension-qcalendar': specifier: ^4.0.2 version: 4.1.2 '@quasar/quasar-app-extension-testing-unit-vitest': specifier: ^0.4.0 - version: 0.4.0(@vue/test-utils@2.4.6)(quasar@2.17.7)(typescript@5.7.3)(vite@6.2.0)(vitest@0.34.6)(vue@3.5.13) + version: 0.4.0(@vue/test-utils@2.4.6)(quasar@2.18.1)(typescript@5.8.3)(vite@6.2.5)(vitest@3.1.1)(vue@3.5.13) + '@vue/compiler-sfc': + specifier: ^3.5.13 + version: 3.5.13 '@vue/test-utils': specifier: ^2.4.4 version: 2.4.6 autoprefixer: specifier: ^10.4.14 - version: 10.4.20(postcss@8.5.3) + version: 10.4.21(postcss@8.5.3) cypress: specifier: ^14.1.0 - version: 14.1.0 + version: 14.2.1 cypress-mochawesome-reporter: specifier: ^3.8.2 - version: 3.8.2(cypress@14.1.0)(mocha@11.1.0) + version: 3.8.2(cypress@14.2.1)(mocha@11.1.0) eslint: specifier: ^9.18.0 - version: 9.20.1 + version: 9.24.0 eslint-config-prettier: specifier: ^10.0.1 - version: 10.0.1(eslint@9.20.1) + version: 10.1.1(eslint@9.24.0) + eslint-import-resolver-alias: + specifier: ^1.1.2 + version: 1.1.2(eslint-plugin-import@2.31.0) eslint-plugin-cypress: specifier: ^4.1.0 - version: 4.1.0(eslint@9.20.1) + version: 4.2.0(eslint@9.24.0) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.31.0(eslint@9.24.0) eslint-plugin-vue: specifier: ^9.32.0 - version: 9.32.0(eslint@9.20.1) + version: 9.33.0(eslint@9.24.0) + globals: + specifier: ^16.0.0 + version: 16.0.0 husky: specifier: ^8.0.0 version: 8.0.3 @@ -102,182 +126,19 @@ devDependencies: version: 8.5.3 prettier: specifier: ^3.4.2 - version: 3.5.1 + version: 3.5.3 sass: specifier: ^1.83.4 - version: 1.85.0 - vitepress: - specifier: ^1.6.3 - version: 1.6.3(@algolia/client-search@5.20.3)(@types/node@22.13.5)(axios@1.7.9)(postcss@8.5.3)(react-dom@19.0.0)(react@19.0.0)(sass@1.85.0)(search-insights@2.17.3)(typescript@5.7.3) + version: 1.86.3 vitest: - specifier: ^0.34.0 - version: 0.34.6(sass@1.85.0) + specifier: ^3.0.3 + version: 3.1.1(@types/node@22.14.0)(sass@1.86.3) xunit-viewer: specifier: ^10.6.1 - version: 10.6.1(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0) + version: 10.6.1(@babel/runtime@7.27.0)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.5)(codemirror@6.0.1)(react-dom@19.1.0)(react@19.1.0) packages: - /@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)(search-insights@2.17.3): - resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==} - dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3) - transitivePeerDependencies: - - '@algolia/client-search' - - algoliasearch - - search-insights - dev: true - - /@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)(search-insights@2.17.3): - resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==} - peerDependencies: - search-insights: '>= 1 < 3' - dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3) - search-insights: 2.17.3 - transitivePeerDependencies: - - '@algolia/client-search' - - algoliasearch - dev: true - - /@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3): - resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==} - peerDependencies: - '@algolia/client-search': '>= 4.9.1 < 6' - algoliasearch: '>= 4.9.1 < 6' - dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3) - '@algolia/client-search': 5.20.3 - algoliasearch: 5.20.3 - dev: true - - /@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3): - resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==} - peerDependencies: - '@algolia/client-search': '>= 4.9.1 < 6' - algoliasearch: '>= 4.9.1 < 6' - dependencies: - '@algolia/client-search': 5.20.3 - algoliasearch: 5.20.3 - dev: true - - /@algolia/client-abtesting@5.20.3: - resolution: {integrity: sha512-wPOzHYSsW+H97JkBLmnlOdJSpbb9mIiuNPycUCV5DgzSkJFaI/OFxXfZXAh1gqxK+hf0miKue1C9bltjWljrNA==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/client-analytics@5.20.3: - resolution: {integrity: sha512-XE3iduH9lA7iTQacDGofBQyIyIgaX8qbTRRdj1bOCmfzc9b98CoiMwhNwdTifmmMewmN0EhVF3hP8KjKWwX7Yw==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/client-common@5.20.3: - resolution: {integrity: sha512-IYRd/A/R3BXeaQVT2805lZEdWo54v39Lqa7ABOxIYnUvX2vvOMW1AyzCuT0U7Q+uPdD4UW48zksUKRixShcWxA==} - engines: {node: '>= 14.0.0'} - dev: true - - /@algolia/client-insights@5.20.3: - resolution: {integrity: sha512-QGc/bmDUBgzB71rDL6kihI2e1Mx6G6PxYO5Ks84iL3tDcIel1aFuxtRF14P8saGgdIe1B6I6QkpkeIddZ6vWQw==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/client-personalization@5.20.3: - resolution: {integrity: sha512-zuM31VNPDJ1LBIwKbYGz/7+CSm+M8EhlljDamTg8AnDilnCpKjBebWZR5Tftv/FdWSro4tnYGOIz1AURQgZ+tQ==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/client-query-suggestions@5.20.3: - resolution: {integrity: sha512-Nn872PuOI8qzi1bxMMhJ0t2AzVBqN01jbymBQOkypvZHrrjZPso3iTpuuLLo9gi3yc/08vaaWTAwJfPhxPwJUw==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/client-search@5.20.3: - resolution: {integrity: sha512-9+Fm1ahV8/2goSIPIqZnVitV5yHW5E5xTdKy33xnqGd45A9yVv5tTkudWzEXsbfBB47j9Xb3uYPZjAvV5RHbKA==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/ingestion@1.20.3: - resolution: {integrity: sha512-5GHNTiZ3saLjTNyr6WkP5hzDg2eFFAYWomvPcm9eHWskjzXt8R0IOiW9kkTS6I6hXBwN5H9Zna5mZDSqqJdg+g==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/monitoring@1.20.3: - resolution: {integrity: sha512-KUWQbTPoRjP37ivXSQ1+lWMfaifCCMzTnEcEnXwAmherS5Tp7us6BAqQDMGOD4E7xyaS2I8pto6WlOzxH+CxmA==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/recommend@5.20.3: - resolution: {integrity: sha512-oo/gG77xTTTclkrdFem0Kmx5+iSRFiwuRRdxZETDjwzCI7svutdbwBgV/Vy4D4QpYaX4nhY/P43k84uEowCE4Q==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - - /@algolia/requester-browser-xhr@5.20.3: - resolution: {integrity: sha512-BkkW7otbiI/Er1AiEPZs1h7lxbtSO9p09jFhv3/iT8/0Yz0CY79VJ9iq+Wv1+dq/l0OxnMpBy8mozrieGA3mXQ==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - dev: true - - /@algolia/requester-fetch@5.20.3: - resolution: {integrity: sha512-eAVlXz7UNzTsA1EDr+p0nlIH7WFxo7k3NMxYe8p38DH8YVWLgm2MgOVFUMNg9HCi6ZNOi/A2w/id2ZZ4sKgUOw==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - dev: true - - /@algolia/requester-node-http@5.20.3: - resolution: {integrity: sha512-FqR3pQPfHfQyX1wgcdK6iyqu86yP76MZd4Pzj1y/YLMj9rRmRCY0E0AffKr//nrOFEwv6uY8BQY4fd9/6b0ZCg==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-common': 5.20.3 - dev: true - /@babel/code-frame@7.26.2: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} @@ -295,65 +156,65 @@ packages: resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - /@babel/parser@7.26.9: - resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==} + /@babel/parser@7.27.0: + resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.26.9 + '@babel/types': 7.27.0 - /@babel/runtime@7.26.9: - resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==} + /@babel/runtime@7.27.0: + resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 dev: true - /@babel/types@7.26.9: - resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} + /@babel/types@7.27.0: + resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - /@bufbuild/protobuf@2.2.3: - resolution: {integrity: sha512-tFQoXHJdkEOSwj5tRIZSPNUuXK3RaR7T1nUrPgbYX1pUbvqqaaZAsfo+NXBPsz5rZMSKVFrgK1WL8Q/MSLvprg==} + /@bufbuild/protobuf@2.2.5: + resolution: {integrity: sha512-/g5EzJifw5GF8aren8wZ/G5oMuPoGeS6MQD3ca8ddcvdXR5UELUfdTZITCGNhNXynY/AYl3Z4plmxdj/tRl/hQ==} dev: true /@codemirror/autocomplete@6.18.6: resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==} dependencies: - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.0 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.36.3 + '@codemirror/view': 6.36.5 '@lezer/common': 1.2.3 dev: true - /@codemirror/commands@6.8.0: - resolution: {integrity: sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==} + /@codemirror/commands@6.8.1: + resolution: {integrity: sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==} dependencies: - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.0 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.36.3 + '@codemirror/view': 6.36.5 '@lezer/common': 1.2.3 dev: true - /@codemirror/language@6.10.8: - resolution: {integrity: sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==} + /@codemirror/language@6.11.0: + resolution: {integrity: sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==} dependencies: '@codemirror/state': 6.5.2 - '@codemirror/view': 6.36.3 + '@codemirror/view': 6.36.5 '@lezer/common': 1.2.3 '@lezer/highlight': 1.2.1 '@lezer/lr': 1.4.2 style-mod: 4.1.2 dev: true - /@codemirror/lint@6.8.4: - resolution: {integrity: sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==} + /@codemirror/lint@6.8.5: + resolution: {integrity: sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==} dependencies: '@codemirror/state': 6.5.2 - '@codemirror/view': 6.36.3 + '@codemirror/view': 6.36.5 crelt: 1.0.6 dev: true @@ -361,7 +222,7 @@ packages: resolution: {integrity: sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==} dependencies: '@codemirror/state': 6.5.2 - '@codemirror/view': 6.36.3 + '@codemirror/view': 6.36.5 crelt: 1.0.6 dev: true @@ -374,14 +235,14 @@ packages: /@codemirror/theme-one-dark@6.1.2: resolution: {integrity: sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==} dependencies: - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.0 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.36.3 + '@codemirror/view': 6.36.5 '@lezer/highlight': 1.2.1 dev: true - /@codemirror/view@6.36.3: - resolution: {integrity: sha512-N2bilM47QWC8Hnx0rMdDxO2x2ImJ1FvZWXubwKgjeoOrWwEiFrtpA7SFHcuZ+o2Ze2VzbkgbzWVj4+V18LVkeg==} + /@codemirror/view@6.36.5: + resolution: {integrity: sha512-cd+FZEUlu3GQCYnguYm3EkhJ8KJVisqqUsCOKedBoAt/d9c76JUUap6U0UrpElln5k6VyrEOYliMuDAKIeDQLg==} dependencies: '@codemirror/state': 6.5.2 style-mod: 4.1.2 @@ -395,16 +256,16 @@ packages: dev: true optional: true - /@commitlint/cli@19.7.1(@types/node@22.13.5)(typescript@5.7.3): - resolution: {integrity: sha512-iObGjR1tE/PfDtDTEfd+tnRkB3/HJzpQqRTyofS2MPPkDn1mp3DBC8SoPDayokfAy+xKhF8+bwRCJO25Nea0YQ==} + /@commitlint/cli@19.8.0(@types/node@22.14.0)(typescript@5.8.3): + resolution: {integrity: sha512-t/fCrLVu+Ru01h0DtlgHZXbHV2Y8gKocTR5elDOqIRUzQd0/6hpt2VIWOj9b3NDo7y4/gfxeR2zRtXq/qO6iUg==} engines: {node: '>=v18'} hasBin: true dependencies: - '@commitlint/format': 19.5.0 - '@commitlint/lint': 19.7.1 - '@commitlint/load': 19.6.1(@types/node@22.13.5)(typescript@5.7.3) - '@commitlint/read': 19.5.0 - '@commitlint/types': 19.5.0 + '@commitlint/format': 19.8.0 + '@commitlint/lint': 19.8.0 + '@commitlint/load': 19.8.0(@types/node@22.14.0)(typescript@5.8.3) + '@commitlint/read': 19.8.0 + '@commitlint/types': 19.8.0 tinyexec: 0.3.2 yargs: 17.7.2 transitivePeerDependencies: @@ -412,27 +273,27 @@ packages: - typescript dev: true - /@commitlint/config-conventional@19.7.1: - resolution: {integrity: sha512-fsEIF8zgiI/FIWSnykdQNj/0JE4av08MudLTyYHm4FlLWemKoQvPNUYU2M/3tktWcCEyq7aOkDDgtjrmgWFbvg==} + /@commitlint/config-conventional@19.8.0: + resolution: {integrity: sha512-9I2kKJwcAPwMoAj38hwqFXG0CzS2Kj+SAByPUQ0SlHTfb7VUhYVmo7G2w2tBrqmOf7PFd6MpZ/a1GQJo8na8kw==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 19.5.0 + '@commitlint/types': 19.8.0 conventional-changelog-conventionalcommits: 7.0.2 dev: true - /@commitlint/config-validator@19.5.0: - resolution: {integrity: sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==} + /@commitlint/config-validator@19.8.0: + resolution: {integrity: sha512-+r5ZvD/0hQC3w5VOHJhGcCooiAVdynFlCe2d6I9dU+PvXdV3O+fU4vipVg+6hyLbQUuCH82mz3HnT/cBQTYYuA==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 19.5.0 + '@commitlint/types': 19.8.0 ajv: 8.17.1 dev: true - /@commitlint/ensure@19.5.0: - resolution: {integrity: sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==} + /@commitlint/ensure@19.8.0: + resolution: {integrity: sha512-kNiNU4/bhEQ/wutI1tp1pVW1mQ0QbAjfPRo5v8SaxoVV+ARhkB8Wjg3BSseNYECPzWWfg/WDqQGIfV1RaBFQZg==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 19.5.0 + '@commitlint/types': 19.8.0 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 lodash.snakecase: 4.1.1 @@ -440,48 +301,48 @@ packages: lodash.upperfirst: 4.3.1 dev: true - /@commitlint/execute-rule@19.5.0: - resolution: {integrity: sha512-aqyGgytXhl2ejlk+/rfgtwpPexYyri4t8/n4ku6rRJoRhGZpLFMqrZ+YaubeGysCP6oz4mMA34YSTaSOKEeNrg==} + /@commitlint/execute-rule@19.8.0: + resolution: {integrity: sha512-fuLeI+EZ9x2v/+TXKAjplBJWI9CNrHnyi5nvUQGQt4WRkww/d95oVRsc9ajpt4xFrFmqMZkd/xBQHZDvALIY7A==} engines: {node: '>=v18'} dev: true - /@commitlint/format@19.5.0: - resolution: {integrity: sha512-yNy088miE52stCI3dhG/vvxFo9e4jFkU1Mj3xECfzp/bIS/JUay4491huAlVcffOoMK1cd296q0W92NlER6r3A==} + /@commitlint/format@19.8.0: + resolution: {integrity: sha512-EOpA8IERpQstxwp/WGnDArA7S+wlZDeTeKi98WMOvaDLKbjptuHWdOYYr790iO7kTCif/z971PKPI2PkWMfOxg==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 19.5.0 + '@commitlint/types': 19.8.0 chalk: 5.4.1 dev: true - /@commitlint/is-ignored@19.7.1: - resolution: {integrity: sha512-3IaOc6HVg2hAoGleRK3r9vL9zZ3XY0rf1RsUf6jdQLuaD46ZHnXBiOPTyQ004C4IvYjSWqJwlh0/u2P73aIE3g==} + /@commitlint/is-ignored@19.8.0: + resolution: {integrity: sha512-L2Jv9yUg/I+jF3zikOV0rdiHUul9X3a/oU5HIXhAJLE2+TXTnEBfqYP9G5yMw/Yb40SnR764g4fyDK6WR2xtpw==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 19.5.0 + '@commitlint/types': 19.8.0 semver: 7.7.1 dev: true - /@commitlint/lint@19.7.1: - resolution: {integrity: sha512-LhcPfVjcOcOZA7LEuBBeO00o3MeZa+tWrX9Xyl1r9PMd5FWsEoZI9IgnGqTKZ0lZt5pO3ZlstgnRyY1CJJc9Xg==} + /@commitlint/lint@19.8.0: + resolution: {integrity: sha512-+/NZKyWKSf39FeNpqhfMebmaLa1P90i1Nrb1SrA7oSU5GNN/lksA4z6+ZTnsft01YfhRZSYMbgGsARXvkr/VLQ==} engines: {node: '>=v18'} dependencies: - '@commitlint/is-ignored': 19.7.1 - '@commitlint/parse': 19.5.0 - '@commitlint/rules': 19.6.0 - '@commitlint/types': 19.5.0 + '@commitlint/is-ignored': 19.8.0 + '@commitlint/parse': 19.8.0 + '@commitlint/rules': 19.8.0 + '@commitlint/types': 19.8.0 dev: true - /@commitlint/load@19.6.1(@types/node@22.13.5)(typescript@5.7.3): - resolution: {integrity: sha512-kE4mRKWWNju2QpsCWt428XBvUH55OET2N4QKQ0bF85qS/XbsRGG1MiTByDNlEVpEPceMkDr46LNH95DtRwcsfA==} + /@commitlint/load@19.8.0(@types/node@22.14.0)(typescript@5.8.3): + resolution: {integrity: sha512-4rvmm3ff81Sfb+mcWT5WKlyOa+Hd33WSbirTVUer0wjS1Hv/Hzr07Uv1ULIV9DkimZKNyOwXn593c+h8lsDQPQ==} engines: {node: '>=v18'} dependencies: - '@commitlint/config-validator': 19.5.0 - '@commitlint/execute-rule': 19.5.0 - '@commitlint/resolve-extends': 19.5.0 - '@commitlint/types': 19.5.0 + '@commitlint/config-validator': 19.8.0 + '@commitlint/execute-rule': 19.8.0 + '@commitlint/resolve-extends': 19.8.0 + '@commitlint/types': 19.8.0 chalk: 5.4.1 - cosmiconfig: 9.0.0(typescript@5.7.3) - cosmiconfig-typescript-loader: 6.1.0(@types/node@22.13.5)(cosmiconfig@9.0.0)(typescript@5.7.3) + cosmiconfig: 9.0.0(typescript@5.8.3) + cosmiconfig-typescript-loader: 6.1.0(@types/node@22.14.0)(cosmiconfig@9.0.0)(typescript@5.8.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -490,67 +351,67 @@ packages: - typescript dev: true - /@commitlint/message@19.5.0: - resolution: {integrity: sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==} + /@commitlint/message@19.8.0: + resolution: {integrity: sha512-qs/5Vi9bYjf+ZV40bvdCyBn5DvbuelhR6qewLE8Bh476F7KnNyLfdM/ETJ4cp96WgeeHo6tesA2TMXS0sh5X4A==} engines: {node: '>=v18'} dev: true - /@commitlint/parse@19.5.0: - resolution: {integrity: sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==} + /@commitlint/parse@19.8.0: + resolution: {integrity: sha512-YNIKAc4EXvNeAvyeEnzgvm1VyAe0/b3Wax7pjJSwXuhqIQ1/t2hD3OYRXb6D5/GffIvaX82RbjD+nWtMZCLL7Q==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 19.5.0 + '@commitlint/types': 19.8.0 conventional-changelog-angular: 7.0.0 conventional-commits-parser: 5.0.0 dev: true - /@commitlint/read@19.5.0: - resolution: {integrity: sha512-TjS3HLPsLsxFPQj6jou8/CZFAmOP2y+6V4PGYt3ihbQKTY1Jnv0QG28WRKl/d1ha6zLODPZqsxLEov52dhR9BQ==} + /@commitlint/read@19.8.0: + resolution: {integrity: sha512-6ywxOGYajcxK1y1MfzrOnwsXO6nnErna88gRWEl3qqOOP8MDu/DTeRkGLXBFIZuRZ7mm5yyxU5BmeUvMpNte5w==} engines: {node: '>=v18'} dependencies: - '@commitlint/top-level': 19.5.0 - '@commitlint/types': 19.5.0 + '@commitlint/top-level': 19.8.0 + '@commitlint/types': 19.8.0 git-raw-commits: 4.0.0 minimist: 1.2.8 tinyexec: 0.3.2 dev: true - /@commitlint/resolve-extends@19.5.0: - resolution: {integrity: sha512-CU/GscZhCUsJwcKTJS9Ndh3AKGZTNFIOoQB2n8CmFnizE0VnEuJoum+COW+C1lNABEeqk6ssfc1Kkalm4bDklA==} + /@commitlint/resolve-extends@19.8.0: + resolution: {integrity: sha512-CLanRQwuG2LPfFVvrkTrBR/L/DMy3+ETsgBqW1OvRxmzp/bbVJW0Xw23LnnExgYcsaFtos967lul1CsbsnJlzQ==} engines: {node: '>=v18'} dependencies: - '@commitlint/config-validator': 19.5.0 - '@commitlint/types': 19.5.0 + '@commitlint/config-validator': 19.8.0 + '@commitlint/types': 19.8.0 global-directory: 4.0.1 import-meta-resolve: 4.1.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 dev: true - /@commitlint/rules@19.6.0: - resolution: {integrity: sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==} + /@commitlint/rules@19.8.0: + resolution: {integrity: sha512-IZ5IE90h6DSWNuNK/cwjABLAKdy8tP8OgGVGbXe1noBEX5hSsu00uRlLu6JuruiXjWJz2dZc+YSw3H0UZyl/mA==} engines: {node: '>=v18'} dependencies: - '@commitlint/ensure': 19.5.0 - '@commitlint/message': 19.5.0 - '@commitlint/to-lines': 19.5.0 - '@commitlint/types': 19.5.0 + '@commitlint/ensure': 19.8.0 + '@commitlint/message': 19.8.0 + '@commitlint/to-lines': 19.8.0 + '@commitlint/types': 19.8.0 dev: true - /@commitlint/to-lines@19.5.0: - resolution: {integrity: sha512-R772oj3NHPkodOSRZ9bBVNq224DOxQtNef5Pl8l2M8ZnkkzQfeSTr4uxawV2Sd3ui05dUVzvLNnzenDBO1KBeQ==} + /@commitlint/to-lines@19.8.0: + resolution: {integrity: sha512-3CKLUw41Cur8VMjh16y8LcsOaKbmQjAKCWlXx6B0vOUREplp6em9uIVhI8Cv934qiwkbi2+uv+mVZPnXJi1o9A==} engines: {node: '>=v18'} dev: true - /@commitlint/top-level@19.5.0: - resolution: {integrity: sha512-IP1YLmGAk0yWrImPRRc578I3dDUI5A2UBJx9FbSOjxe9sTlzFiwVJ+zeMLgAtHMtGZsC8LUnzmW1qRemkFU4ng==} + /@commitlint/top-level@19.8.0: + resolution: {integrity: sha512-Rphgoc/omYZisoNkcfaBRPQr4myZEHhLPx2/vTXNLjiCw4RgfPR1wEgUpJ9OOmDCiv5ZyIExhprNLhteqH4FuQ==} engines: {node: '>=v18'} dependencies: find-up: 7.0.0 dev: true - /@commitlint/types@19.5.0: - resolution: {integrity: sha512-DSHae2obMSMkAtTBSOulg5X7/z+rGLxcXQIkg3OmWvY6wifojge5uVMydfhUvs7yQj+V7jNmRZ2Xzl8GJyqRgg==} + /@commitlint/types@19.8.0: + resolution: {integrity: sha512-LRjP623jPyf3Poyfb0ohMj8I3ORyBDOwXAgxxVPbSD0unJuW2mJWeiRfaQinjtccMqC5Wy1HOMfa4btKjbNxbg==} engines: {node: '>=v18'} dependencies: '@types/conventional-commits-parser': 5.0.1 @@ -561,8 +422,8 @@ packages: resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==} dev: true - /@cypress/request@3.0.7: - resolution: {integrity: sha512-LzxlLEMbBOPYB85uXrDqvD4MgcenjRBLIns3zyhx7vTPj/0u2eQhzXvPiGcaJrV38Q9dbkExWp6cOHPJ+EtFYg==} + /@cypress/request@3.0.8: + resolution: {integrity: sha512-h0NFgh1mJmm1nr4jCwkGHwKneVYKghUyWe6TMNrk0B9zsjAJxpg8C4/+BAcmLgCPa1vj1V8rNUaILl+zYRUWBQ==} engines: {node: '>= 6'} dependencies: aws-sign2: 0.7.0 @@ -578,9 +439,9 @@ packages: json-stringify-safe: 5.0.1 mime-types: 2.1.35 performance-now: 2.1.0 - qs: 6.13.1 + qs: 6.14.0 safe-buffer: 5.2.1 - tough-cookie: 5.1.1 + tough-cookie: 5.1.2 tunnel-agent: 0.6.0 uuid: 8.3.2 dev: true @@ -594,62 +455,8 @@ packages: - supports-color dev: true - /@docsearch/css@3.8.2: - resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==} - dev: true - - /@docsearch/js@3.8.2(@algolia/client-search@5.20.3)(react-dom@19.0.0)(react@19.0.0)(search-insights@2.17.3): - resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==} - dependencies: - '@docsearch/react': 3.8.2(@algolia/client-search@5.20.3)(react-dom@19.0.0)(react@19.0.0)(search-insights@2.17.3) - preact: 10.26.2 - transitivePeerDependencies: - - '@algolia/client-search' - - '@types/react' - - react - - react-dom - - search-insights - dev: true - - /@docsearch/react@3.8.2(@algolia/client-search@5.20.3)(react-dom@19.0.0)(react@19.0.0)(search-insights@2.17.3): - resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==} - peerDependencies: - '@types/react': '>= 16.8.0 < 19.0.0' - react: '>= 16.8.0 < 19.0.0' - react-dom: '>= 16.8.0 < 19.0.0' - search-insights: '>= 1 < 3' - peerDependenciesMeta: - '@types/react': - optional: true - react: - optional: true - react-dom: - optional: true - search-insights: - optional: true - dependencies: - '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)(search-insights@2.17.3) - '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3) - '@docsearch/css': 3.8.2 - algoliasearch: 5.20.3 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - search-insights: 2.17.3 - transitivePeerDependencies: - - '@algolia/client-search' - dev: true - - /@esbuild/aix-ppc64@0.21.5: - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - requiresBuild: true - dev: true - optional: true - - /@esbuild/aix-ppc64@0.24.2: - resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + /@esbuild/aix-ppc64@0.25.2: + resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -657,26 +464,8 @@ packages: dev: true optional: true - /@esbuild/aix-ppc64@0.25.0: - resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm64@0.21.5: - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm64@0.24.2: - resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + /@esbuild/android-arm64@0.25.2: + resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -684,26 +473,8 @@ packages: dev: true optional: true - /@esbuild/android-arm64@0.25.0: - resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm@0.21.5: - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm@0.24.2: - resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + /@esbuild/android-arm@0.25.2: + resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -711,26 +482,8 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.25.0: - resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-x64@0.21.5: - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-x64@0.24.2: - resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + /@esbuild/android-x64@0.25.2: + resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -738,26 +491,8 @@ packages: dev: true optional: true - /@esbuild/android-x64@0.25.0: - resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-arm64@0.21.5: - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-arm64@0.24.2: - resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + /@esbuild/darwin-arm64@0.25.2: + resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -765,26 +500,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64@0.25.0: - resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64@0.21.5: - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64@0.24.2: - resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + /@esbuild/darwin-x64@0.25.2: + resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -792,26 +509,8 @@ packages: dev: true optional: true - /@esbuild/darwin-x64@0.25.0: - resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-arm64@0.21.5: - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-arm64@0.24.2: - resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + /@esbuild/freebsd-arm64@0.25.2: + resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -819,26 +518,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.25.0: - resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-x64@0.21.5: - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-x64@0.24.2: - resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + /@esbuild/freebsd-x64@0.25.2: + resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -846,26 +527,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64@0.25.0: - resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64@0.21.5: - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64@0.24.2: - resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + /@esbuild/linux-arm64@0.25.2: + resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -873,26 +536,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm64@0.25.0: - resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm@0.21.5: - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm@0.24.2: - resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + /@esbuild/linux-arm@0.25.2: + resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -900,26 +545,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm@0.25.0: - resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ia32@0.21.5: - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ia32@0.24.2: - resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + /@esbuild/linux-ia32@0.25.2: + resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -927,26 +554,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32@0.25.0: - resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64@0.21.5: - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64@0.24.2: - resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + /@esbuild/linux-loong64@0.25.2: + resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -954,26 +563,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64@0.25.0: - resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.21.5: - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.24.2: - resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + /@esbuild/linux-mips64el@0.25.2: + resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -981,26 +572,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el@0.25.0: - resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.21.5: - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.24.2: - resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + /@esbuild/linux-ppc64@0.25.2: + resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -1008,26 +581,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64@0.25.0: - resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-riscv64@0.21.5: - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-riscv64@0.24.2: - resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + /@esbuild/linux-riscv64@0.25.2: + resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -1035,26 +590,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.25.0: - resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x@0.21.5: - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x@0.24.2: - resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + /@esbuild/linux-s390x@0.25.2: + resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -1062,26 +599,8 @@ packages: dev: true optional: true - /@esbuild/linux-s390x@0.25.0: - resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-x64@0.21.5: - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-x64@0.24.2: - resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + /@esbuild/linux-x64@0.25.2: + resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -1089,17 +608,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.25.0: - resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-arm64@0.24.2: - resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + /@esbuild/netbsd-arm64@0.25.2: + resolution: {integrity: sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -1107,26 +617,8 @@ packages: dev: true optional: true - /@esbuild/netbsd-arm64@0.25.0: - resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64@0.21.5: - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64@0.24.2: - resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + /@esbuild/netbsd-x64@0.25.2: + resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -1134,17 +626,8 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64@0.25.0: - resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-arm64@0.24.2: - resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + /@esbuild/openbsd-arm64@0.25.2: + resolution: {integrity: sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -1152,26 +635,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-arm64@0.25.0: - resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-x64@0.21.5: - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-x64@0.24.2: - resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + /@esbuild/openbsd-x64@0.25.2: + resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -1179,26 +644,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64@0.25.0: - resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/sunos-x64@0.21.5: - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/sunos-x64@0.24.2: - resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + /@esbuild/sunos-x64@0.25.2: + resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -1206,26 +653,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.25.0: - resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64@0.21.5: - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64@0.24.2: - resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + /@esbuild/win32-arm64@0.25.2: + resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -1233,26 +662,8 @@ packages: dev: true optional: true - /@esbuild/win32-arm64@0.25.0: - resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-ia32@0.21.5: - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-ia32@0.24.2: - resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + /@esbuild/win32-ia32@0.25.2: + resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -1260,26 +671,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32@0.25.0: - resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-x64@0.21.5: - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-x64@0.24.2: - resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + /@esbuild/win32-x64@0.25.2: + resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -1287,22 +680,13 @@ packages: dev: true optional: true - /@esbuild/win32-x64@0.25.0: - resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@eslint-community/eslint-utils@4.4.1(eslint@9.20.1): - resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + /@eslint-community/eslint-utils@4.5.1(eslint@9.24.0): + resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 9.20.1 + eslint: 9.24.0 eslint-visitor-keys: 3.4.3 dev: true @@ -1311,8 +695,8 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/config-array@0.19.2: - resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + /@eslint/config-array@0.20.0: + resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: '@eslint/object-schema': 2.1.6 @@ -1322,15 +706,27 @@ packages: - supports-color dev: true - /@eslint/core@0.11.0: - resolution: {integrity: sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==} + /@eslint/config-helpers@0.2.1: + resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@eslint/core@0.12.0: + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: '@types/json-schema': 7.0.15 dev: true - /@eslint/eslintrc@3.2.0: - resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} + /@eslint/core@0.13.0: + resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@types/json-schema': 7.0.15 + dev: true + + /@eslint/eslintrc@3.3.1: + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: ajv: 6.12.6 @@ -1344,23 +740,21 @@ packages: strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - dev: true - /@eslint/js@9.20.0: - resolution: {integrity: sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==} + /@eslint/js@9.24.0: + resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - dev: true /@eslint/object-schema@2.1.6: resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dev: true - /@eslint/plugin-kit@0.2.6: - resolution: {integrity: sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA==} + /@eslint/plugin-kit@0.2.8: + resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - '@eslint/core': 0.11.0 + '@eslint/core': 0.13.0 levn: 0.4.1 dev: true @@ -1392,24 +786,14 @@ packages: engines: {node: '>=18.18'} dev: true - /@iconify-json/simple-icons@1.2.25: - resolution: {integrity: sha512-2E1/gOCO97rF6usfhhiXxwzCb+UhdEsxW3lW1Sew+xZY0COY6dp82Z/r1rUt2fWKneWjuoGcNeJHHXQyG8mIuw==} - dependencies: - '@iconify/types': 2.0.0 - dev: true - - /@iconify/types@2.0.0: - resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - dev: true - - /@inquirer/figures@1.0.10: - resolution: {integrity: sha512-Ey6176gZmeqZuY/W/nZiUyvmb1/qInjcpiZjXWi6nON+nxJpD1bxtSoBxNliGISae32n6OwbY+TSXPZ1CfS4bw==} + /@inquirer/figures@1.0.11: + resolution: {integrity: sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==} engines: {node: '>=18'} dev: true - /@intlify/bundle-utils@4.0.0(vue-i18n@9.14.2): - resolution: {integrity: sha512-klXrYT9VXyKEXsD6UY3pShg0O5MPC07n0TZ5RrSs5ry6T1eZVolIFGJi9c3qcDrh1qjJxgikRnPBmD7qGDqbjw==} - engines: {node: '>= 12'} + /@intlify/bundle-utils@8.0.0(vue-i18n@9.14.4): + resolution: {integrity: sha512-1B++zykRnMwQ+20SpsZI1JCnV/YJt9Oq7AGlEurzkWJOFtFAVqaGc/oV36PBRYeiKnTbY9VYfjBimr2Vt42wLQ==} + engines: {node: '>= 14.16'} peerDependencies: petite-vue-i18n: '*' vue-i18n: '*' @@ -1419,47 +803,38 @@ packages: vue-i18n: optional: true dependencies: - '@intlify/message-compiler': 11.0.0-rc.1 - '@intlify/shared': 11.0.0-rc.1 - jsonc-eslint-parser: 1.4.1 - source-map: 0.6.1 - vue-i18n: 9.14.2(vue@3.5.13) - yaml-eslint-parser: 0.3.2 - dev: true - - /@intlify/core-base@9.14.2: - resolution: {integrity: sha512-DZyQ4Hk22sC81MP4qiCDuU+LdaYW91A6lCjq8AWPvY3+mGMzhGDfOCzvyR6YBQxtlPjFqMoFk9ylnNYRAQwXtQ==} - engines: {node: '>= 16'} - dependencies: - '@intlify/message-compiler': 9.14.2 - '@intlify/shared': 9.14.2 - - /@intlify/message-compiler@11.0.0-rc.1: - resolution: {integrity: sha512-TGw2uBfuTFTegZf/BHtUQBEKxl7Q/dVGLoqRIdw8lFsp9g/53sYn5iD+0HxIzdYjbWL6BTJMXCPUHp9PxDTRPw==} - engines: {node: '>= 16'} - dependencies: - '@intlify/shared': 11.0.0-rc.1 + '@intlify/message-compiler': 9.14.4 + '@intlify/shared': 9.14.4 + acorn: 8.14.1 + escodegen: 2.1.0 + estree-walker: 2.0.2 + jsonc-eslint-parser: 2.4.0 + mlly: 1.7.4 source-map-js: 1.2.1 + vue-i18n: 9.14.4(vue@3.5.13) + yaml-eslint-parser: 1.3.0 dev: true - /@intlify/message-compiler@9.14.2: - resolution: {integrity: sha512-YsKKuV4Qv4wrLNsvgWbTf0E40uRv+Qiw1BeLQ0LAxifQuhiMe+hfTIzOMdWj/ZpnTDj4RSZtkXjJM7JDiiB5LQ==} + /@intlify/core-base@9.14.4: + resolution: {integrity: sha512-vtZCt7NqWhKEtHa3SD/322DlgP5uR9MqWxnE0y8Q0tjDs9H5Lxhss+b5wv8rmuXRoHKLESNgw9d+EN9ybBbj9g==} engines: {node: '>= 16'} dependencies: - '@intlify/shared': 9.14.2 + '@intlify/message-compiler': 9.14.4 + '@intlify/shared': 9.14.4 + + /@intlify/message-compiler@9.14.4: + resolution: {integrity: sha512-vcyCLiVRN628U38c3PbahrhbbXrckrM9zpy0KZVlDk2Z0OnGwv8uQNNXP3twwGtfLsCf4gu3ci6FMIZnPaqZsw==} + engines: {node: '>= 16'} + dependencies: + '@intlify/shared': 9.14.4 source-map-js: 1.2.1 - /@intlify/shared@11.0.0-rc.1: - resolution: {integrity: sha512-8tR1xe7ZEbkabTuE/tNhzpolygUn9OaYp9yuYAF4MgDNZg06C3Qny80bes2/e9/Wm3aVkPUlCw6WgU7mQd0yEg==} - engines: {node: '>= 16'} - dev: true - - /@intlify/shared@9.14.2: - resolution: {integrity: sha512-uRAHAxYPeF+G5DBIboKpPgC/Waecd4Jz8ihtkpJQD5ycb5PwXp0k/+hBGl5dAjwF7w+l74kz/PKA8r8OK//RUw==} + /@intlify/shared@9.14.4: + resolution: {integrity: sha512-P9zv6i1WvMc9qDBWvIgKkymjY2ptIiQ065PjDv7z7fDqH3J/HBRBN5IoiR46r/ujRcU7hCuSIZWvCAFCyuOYZA==} engines: {node: '>= 16'} - /@intlify/unplugin-vue-i18n@0.8.2(vue-i18n@9.14.2): - resolution: {integrity: sha512-cRnzPqSEZQOmTD+p4pwc3RTS9HxreLqfID0keoqZDZweCy/CGRMLLTNd15S4TUf1vSBhPF03DItEFDr1F+8MDA==} + /@intlify/unplugin-vue-i18n@4.0.0(vue-i18n@9.14.4): + resolution: {integrity: sha512-q2Mhqa/mLi0tulfLFO4fMXXvEbkSZpI5yGhNNsLTNJJ41icEGUuyDe+j5zRZIKSkOJRgX6YbCyibTDJdRsukmw==} engines: {node: '>= 14.16'} peerDependencies: petite-vue-i18n: '*' @@ -1473,9 +848,9 @@ packages: vue-i18n-bridge: optional: true dependencies: - '@intlify/bundle-utils': 4.0.0(vue-i18n@9.14.2) - '@intlify/shared': 11.0.0-rc.1 - '@rollup/pluginutils': 4.2.1 + '@intlify/bundle-utils': 8.0.0(vue-i18n@9.14.4) + '@intlify/shared': 9.14.4 + '@rollup/pluginutils': 5.1.4 '@vue/compiler-sfc': 3.5.13 debug: 4.4.0(supports-color@8.1.1) fast-glob: 3.3.3 @@ -1483,10 +858,11 @@ packages: json5: 2.2.3 pathe: 1.1.2 picocolors: 1.1.1 - source-map: 0.6.1 + source-map-js: 1.2.1 unplugin: 1.16.1 - vue-i18n: 9.14.2(vue@3.5.13) + vue-i18n: 9.14.4(vue@3.5.13) transitivePeerDependencies: + - rollup - supports-color dev: true @@ -1502,13 +878,6 @@ packages: wrap-ansi-cjs: /wrap-ansi@7.0.0 dev: true - /@jest/schemas@29.6.3: - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@sinclair/typebox': 0.27.8 - dev: true - /@jridgewell/gen-mapping@0.3.8: resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} @@ -1571,20 +940,17 @@ packages: dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.0 - dev: true + fastq: 1.19.1 /@one-ini/wasm@0.1.1: resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} @@ -1738,7 +1104,7 @@ packages: peerDependencies: pinia: '>=2.2.6' dependencies: - pinia: 2.3.1(typescript@5.7.3)(vue@3.5.13) + pinia: 2.3.1(typescript@5.8.3)(vue@3.5.13) vue-demi: 0.14.10(vue@3.5.13) transitivePeerDependencies: - '@vue/composition-api' @@ -1773,8 +1139,8 @@ packages: config-chain: 1.1.13 dev: false - /@quasar/app-vite@2.1.0(@types/node@22.13.5)(eslint@9.20.1)(pinia@2.3.1)(quasar@2.17.7)(sass@1.85.0)(typescript@5.7.3)(vue-router@4.5.0)(vue@3.5.13): - resolution: {integrity: sha512-BzT1UW6fe3X+akyNgkWNqeIXZSV2+RX4+IYXmYORh09VNKl+Vd8/oOcYWBqh3XWpy4CYkKC+H484dQmaQU6uHA==} + /@quasar/app-vite@2.2.0(@types/node@22.14.0)(eslint@9.24.0)(pinia@2.3.1)(quasar@2.18.1)(sass@1.86.3)(typescript@5.8.3)(vue-router@4.5.0)(vue@3.5.13): + resolution: {integrity: sha512-MvCfJrCbxUYvoGaK5jPq0h0hjO8mbxYOWngf+dIKrxhwb+1h5ERh6aVYEUuCtMIwTMEVfPkCez4DIfZIoReuDw==} engines: {node: ^30 || ^28 || ^26 || ^24 || ^22 || ^20 || ^18, npm: '>= 6.14.12', yarn: '>= 1.17.3'} hasBin: true peerDependencies: @@ -1803,15 +1169,15 @@ packages: dependencies: '@quasar/render-ssr-error': 1.0.3 '@quasar/ssl-certificate': 1.0.0 - '@quasar/vite-plugin': 1.9.0(@vitejs/plugin-vue@5.2.1)(quasar@2.17.7)(vite@6.1.1)(vue@3.5.13) + '@quasar/vite-plugin': 1.9.0(@vitejs/plugin-vue@5.2.3)(quasar@2.18.1)(vite@6.2.5)(vue@3.5.13) '@types/chrome': 0.0.262 '@types/compression': 1.7.5 '@types/cordova': 11.0.3 '@types/express': 4.17.21 - '@vitejs/plugin-vue': 5.2.1(vite@6.2.0)(vue@3.5.13) + '@vitejs/plugin-vue': 5.2.3(vite@6.2.5)(vue@3.5.13) archiver: 7.0.1 chokidar: 3.6.0 - ci-info: 4.1.0 + ci-info: 4.2.0 compression: 1.8.0 confbox: 0.1.8 cross-spawn: 7.0.6 @@ -1819,8 +1185,8 @@ packages: dotenv: 16.4.7 dotenv-expand: 11.0.7 elementtree: 0.1.7 - esbuild: 0.24.2 - eslint: 9.20.1 + esbuild: 0.25.2 + eslint: 9.24.0 express: 4.21.2 fs-extra: 11.3.0 html-minifier-terser: 7.2.0 @@ -1829,18 +1195,19 @@ packages: kolorist: 1.8.0 lodash: 4.17.21 minimist: 1.2.8 + mlly: 1.7.4 open: 10.1.0 - pinia: 2.3.1(typescript@5.7.3)(vue@3.5.13) - quasar: 2.17.7 + pinia: 2.3.1(typescript@5.8.3)(vue@3.5.13) + quasar: 2.18.1 rollup-plugin-visualizer: 5.14.0 - sass-embedded: 1.85.0 + sass-embedded: 1.86.3 semver: 7.7.1 serialize-javascript: 6.0.2 tinyglobby: 0.2.12 - ts-essentials: 9.4.2(typescript@5.7.3) - typescript: 5.7.3 - vite: 6.1.1(@types/node@22.13.5)(sass-embedded@1.85.0)(sass@1.85.0) - vue: 3.5.13(typescript@5.7.3) + ts-essentials: 9.4.2(typescript@5.8.3) + typescript: 5.8.3 + vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3) + vue: 3.5.13(typescript@5.8.3) vue-router: 4.5.0(vue@3.5.13) webpack-merge: 6.0.1 transitivePeerDependencies: @@ -1859,13 +1226,13 @@ packages: - yaml dev: true - /@quasar/cli@2.4.1: - resolution: {integrity: sha512-MrOmlqdkQhBxfPMbSrch3O7ClCAc0sLTLp9AWLzdB7uNaLbxcLP6zXN8+EPhDzFfMyxdG7jBP0FKEi7Wh+ezrQ==} + /@quasar/cli@2.5.0: + resolution: {integrity: sha512-2Vdltr47k7iwjSAYdtpu2ekPdGCmtrKU84wrGMs4taPRsfFyVyRBnxM1jruSvcmk54eA5chwof+ljmrui37AOA==} engines: {node: '>= 16', npm: '>= 5.6.0', yarn: '>= 1.6.0'} hasBin: true dependencies: '@quasar/ssl-certificate': 1.0.0 - ci-info: 4.1.0 + ci-info: 4.2.0 compression: 1.8.0 connect-history-api-fallback: 2.0.0 cors: 2.8.5 @@ -1895,7 +1262,7 @@ packages: '@quasar/quasar-ui-qcalendar': 4.1.2 dev: true - /@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.6)(quasar@2.17.7)(typescript@5.7.3)(vite@6.2.0)(vitest@0.34.6)(vue@3.5.13): + /@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.6)(quasar@2.18.1)(typescript@5.8.3)(vite@6.2.5)(vitest@3.1.1)(vue@3.5.13): resolution: {integrity: sha512-eyzdUdmZiCueNS+5nedjMmzdbpCetSrtdGIwW6KplW1dTzRbLiNvYUjpBOxQGmJCgEhWy9zuswJ7MZ/bTql24Q==} engines: {node: '>= 12.22.1', npm: '>= 6.14.12', yarn: '>= 1.17.3'} peerDependencies: @@ -1911,11 +1278,11 @@ packages: '@vue/test-utils': 2.4.6 happy-dom: 11.2.0 lodash-es: 4.17.21 - quasar: 2.17.7 - vite-jsconfig-paths: 2.0.1(vite@6.2.0) - vite-tsconfig-paths: 4.3.2(typescript@5.7.3)(vite@6.2.0) - vitest: 0.34.6(sass@1.85.0) - vue: 3.5.13(typescript@5.7.3) + quasar: 2.18.1 + vite-jsconfig-paths: 2.0.1(vite@6.2.5) + vite-tsconfig-paths: 4.3.2(typescript@5.8.3)(vite@6.2.5) + vitest: 3.1.1(@types/node@22.14.0)(sass@1.86.3) + vue: 3.5.13(typescript@5.8.3) transitivePeerDependencies: - supports-color - typescript @@ -1940,7 +1307,7 @@ packages: fs-extra: 11.3.0 selfsigned: 2.4.1 - /@quasar/vite-plugin@1.9.0(@vitejs/plugin-vue@5.2.1)(quasar@2.17.7)(vite@6.1.1)(vue@3.5.13): + /@quasar/vite-plugin@1.9.0(@vitejs/plugin-vue@5.2.3)(quasar@2.18.1)(vite@6.2.5)(vue@3.5.13): resolution: {integrity: sha512-r1MFtI2QZJ2g20pe75Zuv4aoi0uoK8oP0yEdzLWRoOLCbhtf2+StJpUza9TydYi3KcvCl9+4HUf3OAWVKoxDmQ==} engines: {node: '>=18'} peerDependencies: @@ -1949,230 +1316,188 @@ packages: vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 vue: ^3.0.0 dependencies: - '@vitejs/plugin-vue': 5.2.1(vite@6.2.0)(vue@3.5.13) - quasar: 2.17.7 - vite: 6.1.1(@types/node@22.13.5)(sass-embedded@1.85.0)(sass@1.85.0) - vue: 3.5.13(typescript@5.7.3) + '@vitejs/plugin-vue': 5.2.3(vite@6.2.5)(vue@3.5.13) + quasar: 2.18.1 + vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3) + vue: 3.5.13(typescript@5.8.3) dev: true - /@rollup/pluginutils@4.2.1: - resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} - engines: {node: '>= 8.0.0'} + /@rollup/pluginutils@5.1.4: + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true dependencies: + '@types/estree': 1.0.7 estree-walker: 2.0.2 - picomatch: 2.3.1 + picomatch: 4.0.2 dev: true - /@rollup/rollup-android-arm-eabi@4.34.8: - resolution: {integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==} + /@rollup/rollup-android-arm-eabi@4.39.0: + resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} cpu: [arm] os: [android] requiresBuild: true dev: true optional: true - /@rollup/rollup-android-arm64@4.34.8: - resolution: {integrity: sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==} + /@rollup/rollup-android-arm64@4.39.0: + resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} cpu: [arm64] os: [android] requiresBuild: true dev: true optional: true - /@rollup/rollup-darwin-arm64@4.34.8: - resolution: {integrity: sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==} + /@rollup/rollup-darwin-arm64@4.39.0: + resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-darwin-x64@4.34.8: - resolution: {integrity: sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==} + /@rollup/rollup-darwin-x64@4.39.0: + resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-freebsd-arm64@4.34.8: - resolution: {integrity: sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==} + /@rollup/rollup-freebsd-arm64@4.39.0: + resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} cpu: [arm64] os: [freebsd] requiresBuild: true dev: true optional: true - /@rollup/rollup-freebsd-x64@4.34.8: - resolution: {integrity: sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==} + /@rollup/rollup-freebsd-x64@4.39.0: + resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} cpu: [x64] os: [freebsd] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.34.8: - resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==} + /@rollup/rollup-linux-arm-gnueabihf@4.39.0: + resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} cpu: [arm] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm-musleabihf@4.34.8: - resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==} + /@rollup/rollup-linux-arm-musleabihf@4.39.0: + resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} cpu: [arm] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.34.8: - resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==} + /@rollup/rollup-linux-arm64-gnu@4.39.0: + resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-musl@4.34.8: - resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==} + /@rollup/rollup-linux-arm64-musl@4.39.0: + resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-loongarch64-gnu@4.34.8: - resolution: {integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==} + /@rollup/rollup-linux-loongarch64-gnu@4.39.0: + resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} cpu: [loong64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-powerpc64le-gnu@4.34.8: - resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==} + /@rollup/rollup-linux-powerpc64le-gnu@4.39.0: + resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} cpu: [ppc64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-riscv64-gnu@4.34.8: - resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==} + /@rollup/rollup-linux-riscv64-gnu@4.39.0: + resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} cpu: [riscv64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-s390x-gnu@4.34.8: - resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==} + /@rollup/rollup-linux-riscv64-musl@4.39.0: + resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-s390x-gnu@4.39.0: + resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} cpu: [s390x] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-x64-gnu@4.34.8: - resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==} + /@rollup/rollup-linux-x64-gnu@4.39.0: + resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-x64-musl@4.34.8: - resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==} + /@rollup/rollup-linux-x64-musl@4.39.0: + resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-arm64-msvc@4.34.8: - resolution: {integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==} + /@rollup/rollup-win32-arm64-msvc@4.39.0: + resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-ia32-msvc@4.34.8: - resolution: {integrity: sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==} + /@rollup/rollup-win32-ia32-msvc@4.39.0: + resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} cpu: [ia32] os: [win32] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-x64-msvc@4.34.8: - resolution: {integrity: sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==} + /@rollup/rollup-win32-x64-msvc@4.39.0: + resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /@shikijs/core@2.5.0: - resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==} - dependencies: - '@shikijs/engine-javascript': 2.5.0 - '@shikijs/engine-oniguruma': 2.5.0 - '@shikijs/types': 2.5.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - hast-util-to-html: 9.0.5 - dev: true - - /@shikijs/engine-javascript@2.5.0: - resolution: {integrity: sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==} - dependencies: - '@shikijs/types': 2.5.0 - '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 3.1.1 - dev: true - - /@shikijs/engine-oniguruma@2.5.0: - resolution: {integrity: sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==} - dependencies: - '@shikijs/types': 2.5.0 - '@shikijs/vscode-textmate': 10.0.2 - dev: true - - /@shikijs/langs@2.5.0: - resolution: {integrity: sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==} - dependencies: - '@shikijs/types': 2.5.0 - dev: true - - /@shikijs/themes@2.5.0: - resolution: {integrity: sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==} - dependencies: - '@shikijs/types': 2.5.0 - dev: true - - /@shikijs/transformers@2.5.0: - resolution: {integrity: sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==} - dependencies: - '@shikijs/core': 2.5.0 - '@shikijs/types': 2.5.0 - dev: true - - /@shikijs/types@2.5.0: - resolution: {integrity: sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==} - dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - dev: true - - /@shikijs/vscode-textmate@10.0.2: - resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - dev: true - - /@sinclair/typebox@0.27.8: - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + /@rtsao/scc@1.1.0: + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} dev: true /@sindresorhus/is@4.6.0: @@ -2207,7 +1532,7 @@ packages: resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} dependencies: '@types/connect': 3.4.38 - '@types/node': 22.13.4 + '@types/node': 22.14.0 dev: true /@types/cacheable-request@6.0.3: @@ -2215,20 +1540,10 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 22.13.4 + '@types/node': 22.14.0 '@types/responselike': 1.0.3 dev: false - /@types/chai-subset@1.3.5: - resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==} - dependencies: - '@types/chai': 4.3.20 - dev: true - - /@types/chai@4.3.20: - resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} - dev: true - /@types/chrome@0.0.262: resolution: {integrity: sha512-TOoj3dqSYE13PD2fRuMQ6X6pggEvL9rRk/yOYOyWE6sfqRWxsJm4VoVm+wr9pkr4Sht/M5t7FFL4vXato8d1gA==} dependencies: @@ -2245,13 +1560,13 @@ packages: /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 22.13.4 + '@types/node': 22.14.0 dev: true /@types/conventional-commits-parser@5.0.1: resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} dependencies: - '@types/node': 22.13.4 + '@types/node': 22.14.0 dev: true /@types/cordova@11.0.3: @@ -2261,17 +1576,17 @@ packages: /@types/cors@2.8.17: resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} dependencies: - '@types/node': 22.13.5 + '@types/node': 22.14.0 dev: true - /@types/estree@1.0.6: - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + /@types/estree@1.0.7: + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} dev: true /@types/express-serve-static-core@4.19.6: resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} dependencies: - '@types/node': 22.13.4 + '@types/node': 22.14.0 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -2300,12 +1615,6 @@ packages: resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} dev: true - /@types/hast@3.0.4: - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - dependencies: - '@types/unist': 3.0.3 - dev: true - /@types/http-cache-semantics@4.0.4: resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} dev: false @@ -2317,7 +1626,7 @@ packages: /@types/http-proxy@1.17.16: resolution: {integrity: sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==} dependencies: - '@types/node': 22.13.4 + '@types/node': 22.14.0 dev: false /@types/json-schema@7.0.15: @@ -2331,30 +1640,9 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 22.13.4 + '@types/node': 22.14.0 dev: false - /@types/linkify-it@5.0.0: - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - dev: true - - /@types/markdown-it@14.1.2: - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} - dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 - dev: true - - /@types/mdast@4.0.4: - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - dependencies: - '@types/unist': 3.0.3 - dev: true - - /@types/mdurl@2.0.0: - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - dev: true - /@types/mime@1.3.5: resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} dev: true @@ -2362,18 +1650,12 @@ packages: /@types/node-forge@1.3.11: resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} dependencies: - '@types/node': 22.13.4 + '@types/node': 22.14.0 - /@types/node@22.13.4: - resolution: {integrity: sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==} + /@types/node@22.14.0: + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} dependencies: - undici-types: 6.20.0 - - /@types/node@22.13.5: - resolution: {integrity: sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==} - dependencies: - undici-types: 6.20.0 - dev: true + undici-types: 6.21.0 /@types/qs@6.9.18: resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==} @@ -2386,21 +1668,21 @@ packages: /@types/responselike@1.0.3: resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: - '@types/node': 22.13.4 + '@types/node': 22.14.0 dev: false /@types/send@0.17.4: resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} dependencies: '@types/mime': 1.3.5 - '@types/node': 22.13.4 + '@types/node': 22.14.0 dev: true /@types/serve-static@1.15.7: resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.13.4 + '@types/node': 22.14.0 '@types/send': 0.17.4 dev: true @@ -2412,24 +1694,16 @@ packages: resolution: {integrity: sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==} dev: true - /@types/unist@3.0.3: - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - dev: true - - /@types/web-bluetooth@0.0.20: - resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - dev: true - /@types/yauzl@2.10.3: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 22.13.5 + '@types/node': 22.14.0 dev: true optional: true - /@uiw/codemirror-extensions-basic-setup@4.23.8(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.36.3): - resolution: {integrity: sha512-XJR/8AEVcE7ufy1BhW2nCN9qSVDYEdCtYLfvhaMwl6Q3qcaYYCGE2K5QbFCy7LsdP/3uZKvc1OskuqatoOPdhQ==} + /@uiw/codemirror-extensions-basic-setup@4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.1)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.36.5): + resolution: {integrity: sha512-zpbmSeNs3OU/f/Eyd6brFnjsBUYwv2mFjWxlAsIRSwTlW+skIT60rQHFBSfsj/5UVSxSLWVeUYczN7AyXvgTGQ==} peerDependencies: '@codemirror/autocomplete': '>=6.0.0' '@codemirror/commands': '>=6.0.0' @@ -2440,16 +1714,16 @@ packages: '@codemirror/view': '>=6.0.0' dependencies: '@codemirror/autocomplete': 6.18.6 - '@codemirror/commands': 6.8.0 - '@codemirror/language': 6.10.8 - '@codemirror/lint': 6.8.4 + '@codemirror/commands': 6.8.1 + '@codemirror/language': 6.11.0 + '@codemirror/lint': 6.8.5 '@codemirror/search': 6.5.10 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.36.3 + '@codemirror/view': 6.36.5 dev: true - /@uiw/react-codemirror@4.23.8(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-/NA5Pj4MmXkLSlmlUm4yfEmRLntrNq5TkQKBSINn7TukXQ4fc+C6Bk0U60Qa4rkvCSgwzZdQ2exyP0t0+2GtqA==} + /@uiw/react-codemirror@4.23.10(@babel/runtime@7.27.0)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.5)(codemirror@6.0.1)(react-dom@19.1.0)(react@19.1.0): + resolution: {integrity: sha512-AbN4eVHOL4ckRuIXpZxkzEqL/1ChVA+BSdEnAKjIB68pLQvKsVoYbiFP8zkXkYc4+Fcgq5KbAjvYqdo4ewemKw==} peerDependencies: '@babel/runtime': '>=7.11.0' '@codemirror/state': '>=6.0.0' @@ -2459,15 +1733,15 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' dependencies: - '@babel/runtime': 7.26.9 - '@codemirror/commands': 6.8.0 + '@babel/runtime': 7.27.0 + '@codemirror/commands': 6.8.1 '@codemirror/state': 6.5.2 '@codemirror/theme-one-dark': 6.1.2 - '@codemirror/view': 6.36.3 - '@uiw/codemirror-extensions-basic-setup': 4.23.8(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.36.3) + '@codemirror/view': 6.36.5 + '@uiw/codemirror-extensions-basic-setup': 4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.1)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.36.5) codemirror: 6.0.1 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) transitivePeerDependencies: - '@codemirror/autocomplete' - '@codemirror/language' @@ -2475,74 +1749,82 @@ packages: - '@codemirror/search' dev: true - /@ungap/structured-clone@1.3.0: - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - dev: true - - /@vitejs/plugin-vue@5.2.1(vite@5.4.14)(vue@3.5.13): - resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==} + /@vitejs/plugin-vue@5.2.3(vite@6.2.5)(vue@3.5.13): + resolution: {integrity: sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 || ^6.0.0 vue: ^3.2.25 dependencies: - vite: 5.4.14(@types/node@22.13.5)(sass@1.85.0) - vue: 3.5.13(typescript@5.7.3) + vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3) + vue: 3.5.13(typescript@5.8.3) dev: true - /@vitejs/plugin-vue@5.2.1(vite@6.2.0)(vue@3.5.13): - resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==} - engines: {node: ^18.0.0 || >=20.0.0} + /@vitest/expect@3.1.1: + resolution: {integrity: sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==} + dependencies: + '@vitest/spy': 3.1.1 + '@vitest/utils': 3.1.1 + chai: 5.2.0 + tinyrainbow: 2.0.0 + dev: true + + /@vitest/mocker@3.1.1(vite@6.2.5): + resolution: {integrity: sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==} peerDependencies: + msw: ^2.4.9 vite: ^5.0.0 || ^6.0.0 - vue: ^3.2.25 - dependencies: - vite: 6.2.0(@types/node@22.13.5)(sass@1.85.0) - vue: 3.5.13(typescript@5.7.3) - dev: true - - /@vitest/expect@0.34.6: - resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} - dependencies: - '@vitest/spy': 0.34.6 - '@vitest/utils': 0.34.6 - chai: 4.5.0 - dev: true - - /@vitest/runner@0.34.6: - resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==} - dependencies: - '@vitest/utils': 0.34.6 - p-limit: 4.0.0 - pathe: 1.1.2 - dev: true - - /@vitest/snapshot@0.34.6: - resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==} + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true dependencies: + '@vitest/spy': 3.1.1 + estree-walker: 3.0.3 magic-string: 0.30.17 - pathe: 1.1.2 - pretty-format: 29.7.0 + vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3) dev: true - /@vitest/spy@0.34.6: - resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==} + /@vitest/pretty-format@3.1.1: + resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==} dependencies: - tinyspy: 2.2.1 + tinyrainbow: 2.0.0 dev: true - /@vitest/utils@0.34.6: - resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} + /@vitest/runner@3.1.1: + resolution: {integrity: sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==} dependencies: - diff-sequences: 29.6.3 - loupe: 2.3.7 - pretty-format: 29.7.0 + '@vitest/utils': 3.1.1 + pathe: 2.0.3 + dev: true + + /@vitest/snapshot@3.1.1: + resolution: {integrity: sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==} + dependencies: + '@vitest/pretty-format': 3.1.1 + magic-string: 0.30.17 + pathe: 2.0.3 + dev: true + + /@vitest/spy@3.1.1: + resolution: {integrity: sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==} + dependencies: + tinyspy: 3.0.2 + dev: true + + /@vitest/utils@3.1.1: + resolution: {integrity: sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==} + dependencies: + '@vitest/pretty-format': 3.1.1 + loupe: 3.1.3 + tinyrainbow: 2.0.0 dev: true /@vue/compiler-core@3.5.13: resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} dependencies: - '@babel/parser': 7.26.9 + '@babel/parser': 7.27.0 '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 @@ -2557,7 +1839,7 @@ packages: /@vue/compiler-sfc@3.5.13: resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} dependencies: - '@babel/parser': 7.26.9 + '@babel/parser': 7.27.0 '@vue/compiler-core': 3.5.13 '@vue/compiler-dom': 3.5.13 '@vue/compiler-ssr': 3.5.13 @@ -2576,30 +1858,6 @@ packages: /@vue/devtools-api@6.6.4: resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - /@vue/devtools-api@7.7.2: - resolution: {integrity: sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==} - dependencies: - '@vue/devtools-kit': 7.7.2 - dev: true - - /@vue/devtools-kit@7.7.2: - resolution: {integrity: sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==} - dependencies: - '@vue/devtools-shared': 7.7.2 - birpc: 0.2.19 - hookable: 5.5.3 - mitt: 3.0.1 - perfect-debounce: 1.0.0 - speakingurl: 14.0.1 - superjson: 2.2.2 - dev: true - - /@vue/devtools-shared@7.7.2: - resolution: {integrity: sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==} - dependencies: - rfdc: 1.4.1 - dev: true - /@vue/reactivity@3.5.13: resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} dependencies: @@ -2626,7 +1884,7 @@ packages: dependencies: '@vue/compiler-ssr': 3.5.13 '@vue/shared': 3.5.13 - vue: 3.5.13(typescript@5.7.3) + vue: 3.5.13(typescript@5.8.3) /@vue/shared@3.5.13: resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} @@ -2634,81 +1892,8 @@ packages: /@vue/test-utils@2.4.6: resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} dependencies: - js-beautify: 1.15.3 - vue-component-type-helpers: 2.2.2 - dev: true - - /@vueuse/core@12.7.0(typescript@5.7.3): - resolution: {integrity: sha512-jtK5B7YjZXmkGNHjviyGO4s3ZtEhbzSgrbX+s5o+Lr8i2nYqNyHuPVOeTdM1/hZ5Tkxg/KktAuAVDDiHMraMVA==} - dependencies: - '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 12.7.0 - '@vueuse/shared': 12.7.0(typescript@5.7.3) - vue: 3.5.13(typescript@5.7.3) - transitivePeerDependencies: - - typescript - dev: true - - /@vueuse/integrations@12.7.0(axios@1.7.9)(focus-trap@7.6.4)(typescript@5.7.3): - resolution: {integrity: sha512-IEq7K4bCl7mn3uKJaWtNXnd1CAPaHLUMuyj5K1/k/pVcItt0VONZW8xiGxdIovJcQjkzOHjImhX5t6gija+0/g==} - peerDependencies: - async-validator: ^4 - axios: ^1 - change-case: ^5 - drauu: ^0.4 - focus-trap: ^7 - fuse.js: ^7 - idb-keyval: ^6 - jwt-decode: ^4 - nprogress: ^0.2 - qrcode: ^1.5 - sortablejs: ^1 - universal-cookie: ^7 - peerDependenciesMeta: - async-validator: - optional: true - axios: - optional: true - change-case: - optional: true - drauu: - optional: true - focus-trap: - optional: true - fuse.js: - optional: true - idb-keyval: - optional: true - jwt-decode: - optional: true - nprogress: - optional: true - qrcode: - optional: true - sortablejs: - optional: true - universal-cookie: - optional: true - dependencies: - '@vueuse/core': 12.7.0(typescript@5.7.3) - '@vueuse/shared': 12.7.0(typescript@5.7.3) - axios: 1.7.9 - focus-trap: 7.6.4 - vue: 3.5.13(typescript@5.7.3) - transitivePeerDependencies: - - typescript - dev: true - - /@vueuse/metadata@12.7.0: - resolution: {integrity: sha512-4VvTH9mrjXqFN5LYa5YfqHVRI6j7R00Vy4995Rw7PQxyCL3z0Lli86iN4UemWqixxEvYfRjG+hF9wL8oLOn+3g==} - dev: true - - /@vueuse/shared@12.7.0(typescript@5.7.3): - resolution: {integrity: sha512-coLlUw2HHKsm7rPN6WqHJQr18WymN4wkA/3ThFaJ4v4gWGWAQQGK+MJxLuJTBs4mojQiazlVWAKNJNpUWGRkNw==} - dependencies: - vue: 3.5.13(typescript@5.7.3) - transitivePeerDependencies: - - typescript + js-beautify: 1.15.4 + vue-component-type-helpers: 2.2.8 dev: true /JSONStream@1.3.5: @@ -2719,9 +1904,9 @@ packages: through: 2.3.8 dev: true - /abbrev@3.0.0: - resolution: {integrity: sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==} - engines: {node: ^18.17.0 || >=20.5.0} + /abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dev: true /abort-controller@3.0.0: @@ -2738,40 +1923,17 @@ packages: mime-types: 2.1.35 negotiator: 0.6.3 - /acorn-jsx@5.3.2(acorn@7.4.1): + /acorn-jsx@5.3.2(acorn@8.14.1): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 7.4.1 - dev: true + acorn: 8.14.1 - /acorn-jsx@5.3.2(acorn@8.14.0): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.14.0 - dev: true - - /acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} - dependencies: - acorn: 8.14.0 - dev: true - - /acorn@7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + /acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} engines: {node: '>=0.4.0'} hasBin: true - dev: true - - /acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true /aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} @@ -2788,7 +1950,6 @@ packages: fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - dev: true /ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} @@ -2799,25 +1960,6 @@ packages: require-from-string: 2.0.2 dev: true - /algoliasearch@5.20.3: - resolution: {integrity: sha512-iNC6BGvipaalFfDfDnXUje8GUlW5asj0cTMsZJwO/0rhsyLx1L7GZFAY8wW+eQ6AM4Yge2p5GSE5hrBlfSD90Q==} - engines: {node: '>= 14.0.0'} - dependencies: - '@algolia/client-abtesting': 5.20.3 - '@algolia/client-analytics': 5.20.3 - '@algolia/client-common': 5.20.3 - '@algolia/client-insights': 5.20.3 - '@algolia/client-personalization': 5.20.3 - '@algolia/client-query-suggestions': 5.20.3 - '@algolia/client-search': 5.20.3 - '@algolia/ingestion': 1.20.3 - '@algolia/monitoring': 1.20.3 - '@algolia/recommend': 5.20.3 - '@algolia/requester-browser-xhr': 5.20.3 - '@algolia/requester-fetch': 5.20.3 - '@algolia/requester-node-http': 5.20.3 - dev: true - /ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} dependencies: @@ -2851,11 +1993,6 @@ packages: color-convert: 2.0.1 dev: true - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true - /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} @@ -2904,6 +2041,13 @@ packages: /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + /array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 dev: true /array-flatten@1.1.1: @@ -2913,6 +2057,64 @@ packages: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} dev: true + /array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + dev: true + + /array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + dev: true + + /array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + dev: true + + /arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + dev: true + /asn1@0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} dependencies: @@ -2924,8 +2126,9 @@ packages: engines: {node: '>=0.8'} dev: true - /assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + /assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} dev: true /astral-regex@2.0.0: @@ -2933,6 +2136,11 @@ packages: engines: {node: '>=8'} dev: true + /async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + dev: true + /async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} dev: true @@ -2945,15 +2153,15 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /autoprefixer@10.4.20(postcss@8.5.3): - resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + /autoprefixer@10.4.21(postcss@8.5.3): + resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: browserslist: 4.24.4 - caniuse-lite: 1.0.30001700 + caniuse-lite: 1.0.30001712 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -2961,6 +2169,13 @@ packages: postcss-value-parser: 4.2.0 dev: true + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.1.0 + dev: true + /aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} dev: true @@ -2969,14 +2184,15 @@ packages: resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} dev: true - /axios@1.7.9: - resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} + /axios@1.8.4: + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} dependencies: follow-redirects: 1.15.9 form-data: 4.0.2 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug + dev: false /b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} @@ -3016,10 +2232,6 @@ packages: engines: {node: '>=8'} dev: true - /birpc@0.2.19: - resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==} - dev: true - /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} dependencies: @@ -3107,10 +2319,10 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001700 - electron-to-chromium: 1.5.102 + caniuse-lite: 1.0.30001712 + electron-to-chromium: 1.5.132 node-releases: 2.0.19 - update-browserslist-db: 1.1.2(browserslist@4.24.4) + update-browserslist-db: 1.1.3(browserslist@4.24.4) dev: true /buffer-builder@0.2.0: @@ -3212,17 +2424,26 @@ packages: es-errors: 1.3.0 function-bind: 1.1.2 - /call-bound@1.0.3: - resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + /call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} engines: {node: '>= 0.4'} dependencies: call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.2.7 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + dev: true + + /call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - dev: true /camel-case@4.1.2: resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} @@ -3246,29 +2467,23 @@ packages: engines: {node: '>=14.16'} dev: false - /caniuse-lite@1.0.30001700: - resolution: {integrity: sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==} + /caniuse-lite@1.0.30001712: + resolution: {integrity: sha512-MBqPpGYYdQ7/hfKiet9SCI+nmN5/hp4ZzveOJubl5DTAMa5oggjAuoi0Z4onBpKPFI2ePGnQuQIzF3VxDjDJig==} dev: true /caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true - /ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - dev: true - - /chai@4.5.0: - resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} - engines: {node: '>=4'} + /chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.4 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.1.0 + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 dev: true /chalk@4.1.2: @@ -3283,22 +2498,13 @@ packages: resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - /character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - dev: true - - /character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - dev: true - /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true - /check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - dependencies: - get-func-name: 2.0.2 + /check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} dev: true /check-more-types@2.24.0: @@ -3350,8 +2556,8 @@ packages: engines: {node: '>=8'} dev: false - /ci-info@4.1.0: - resolution: {integrity: sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==} + /ci-info@4.2.0: + resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} engines: {node: '>=8'} /clean-css@5.3.3: @@ -3446,12 +2652,12 @@ packages: resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==} dependencies: '@codemirror/autocomplete': 6.18.6 - '@codemirror/commands': 6.8.0 - '@codemirror/language': 6.10.8 - '@codemirror/lint': 6.8.4 + '@codemirror/commands': 6.8.1 + '@codemirror/language': 6.11.0 + '@codemirror/lint': 6.8.5 '@codemirror/search': 6.5.10 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.36.3 + '@codemirror/view': 6.36.5 dev: true /color-convert@2.0.1: @@ -3479,10 +2685,6 @@ packages: dependencies: delayed-stream: 1.0.0 - /comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - dev: true - /commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} @@ -3529,7 +2731,7 @@ packages: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} dependencies: - mime-db: 1.53.0 + mime-db: 1.54.0 /compression@1.8.0: resolution: {integrity: sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==} @@ -3636,13 +2838,6 @@ packages: engines: {node: '>= 0.6'} dev: true - /copy-anything@3.0.5: - resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} - engines: {node: '>=12.13'} - dependencies: - is-what: 4.1.16 - dev: true - /core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} dev: true @@ -3657,7 +2852,7 @@ packages: object-assign: 4.1.1 vary: 1.1.2 - /cosmiconfig-typescript-loader@6.1.0(@types/node@22.13.5)(cosmiconfig@9.0.0)(typescript@5.7.3): + /cosmiconfig-typescript-loader@6.1.0(@types/node@22.14.0)(cosmiconfig@9.0.0)(typescript@5.8.3): resolution: {integrity: sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==} engines: {node: '>=v18'} peerDependencies: @@ -3665,13 +2860,13 @@ packages: cosmiconfig: '>=9' typescript: '>=5' dependencies: - '@types/node': 22.13.5 - cosmiconfig: 9.0.0(typescript@5.7.3) + '@types/node': 22.14.0 + cosmiconfig: 9.0.0(typescript@5.8.3) jiti: 2.4.2 - typescript: 5.7.3 + typescript: 5.8.3 dev: true - /cosmiconfig@9.0.0(typescript@5.7.3): + /cosmiconfig@9.0.0(typescript@5.8.3): resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} peerDependencies: @@ -3684,7 +2879,7 @@ packages: import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 - typescript: 5.7.3 + typescript: 5.8.3 dev: true /crc-32@1.2.2: @@ -3737,7 +2932,7 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - /cypress-mochawesome-reporter@3.8.2(cypress@14.1.0)(mocha@11.1.0): + /cypress-mochawesome-reporter@3.8.2(cypress@14.2.1)(mocha@11.1.0): resolution: {integrity: sha512-oJZkNzhNmN9ZD+LmZyFuPb8aWaIijyHyqYh52YOBvR6B6ckfJNCHP3A98a+/nG0H4t46CKTNwo+wNpMa4d2kjA==} engines: {node: '>=14'} hasBin: true @@ -3745,7 +2940,7 @@ packages: cypress: '>=6.2.0' dependencies: commander: 10.0.1 - cypress: 14.1.0 + cypress: 14.2.1 fs-extra: 10.1.0 mochawesome: 7.1.3(mocha@11.1.0) mochawesome-merge: 4.4.1 @@ -3754,13 +2949,13 @@ packages: - mocha dev: true - /cypress@14.1.0: - resolution: {integrity: sha512-pPPj8Uu9NwjaaiXAEcjYZZmgsq6v9Zs1Nw6a+zRF+ANgYSNhH4S32SjFRsvMcuOHR/8dp4GBJhBPqIPSs+TxaA==} + /cypress@14.2.1: + resolution: {integrity: sha512-5xd0E7fUp0pjjib1D7ljkmCwFDgMkWuW06jWiz8dKrI7MNRrDo0C65i4Sh+oZ9YHjMHZRJBR0XZk1DfekOhOUw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true requiresBuild: true dependencies: - '@cypress/request': 3.0.7 + '@cypress/request': 3.0.8 '@cypress/xvfb': 1.2.4(supports-color@8.1.1) '@types/sinonjs__fake-timers': 8.1.1 '@types/sizzle': 2.3.9 @@ -3771,7 +2966,7 @@ packages: cachedir: 2.4.0 chalk: 4.1.2 check-more-types: 2.24.0 - ci-info: 4.1.0 + ci-info: 4.2.0 cli-cursor: 3.1.0 cli-table3: 0.6.5 commander: 6.2.1 @@ -3817,6 +3012,33 @@ packages: assert-plus: 1.0.0 dev: true + /data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + + /data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + + /data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + dev: true + /dateformat@4.6.3: resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} dev: true @@ -3903,11 +3125,9 @@ packages: mimic-response: 3.1.0 dev: false - /deep-eql@4.1.4: - resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + /deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - dependencies: - type-detect: 4.1.0 dev: true /deep-extend@0.6.0: @@ -3961,6 +3181,15 @@ packages: engines: {node: '>=10'} dev: false + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + dev: true + /define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} @@ -3970,6 +3199,15 @@ packages: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + dev: true + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -3978,11 +3216,6 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} - /dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - dev: true - /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -4000,22 +3233,18 @@ packages: dev: true optional: true - /devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - dependencies: - dequal: 2.0.3 - dev: true - - /diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - /diff@5.2.0: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} dev: true + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + /dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: @@ -4041,7 +3270,7 @@ packages: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} dependencies: - type-fest: 4.35.0 + type-fest: 4.39.1 dev: true /dotenv-expand@11.0.7: @@ -4088,8 +3317,8 @@ packages: /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - /electron-to-chromium@1.5.102: - resolution: {integrity: sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==} + /electron-to-chromium@1.5.132: + resolution: {integrity: sha512-QgX9EBvWGmvSRa74zqfnG7+Eno0Ak0vftBll0Pt2/z5b3bEGYL6OUXLgKPtvx73dn3dvwrlyVkjPKRRlhLYTEg==} dev: true /elementtree@0.1.7: @@ -4099,10 +3328,6 @@ packages: sax: 1.1.4 dev: true - /emoji-regex-xs@1.0.0: - resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} - dev: true - /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4132,7 +3357,7 @@ packages: engines: {node: '>=10.2.0'} dependencies: '@types/cors': 2.8.17 - '@types/node': 22.13.5 + '@types/node': 22.14.0 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -4169,6 +3394,63 @@ packages: is-arrayish: 0.2.1 dev: true + /es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + dev: true + /es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -4177,6 +3459,9 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + /es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + /es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -4188,105 +3473,57 @@ packages: engines: {node: '>= 0.4'} dependencies: es-errors: 1.3.0 - get-intrinsic: 1.2.7 + get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 hasown: 2.0.2 - /esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 + /es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + dependencies: + hasown: 2.0.2 dev: true - /esbuild@0.24.2: - resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + /es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + dev: true + + /esbuild@0.25.2: + resolution: {integrity: sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==} engines: {node: '>=18'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/aix-ppc64': 0.24.2 - '@esbuild/android-arm': 0.24.2 - '@esbuild/android-arm64': 0.24.2 - '@esbuild/android-x64': 0.24.2 - '@esbuild/darwin-arm64': 0.24.2 - '@esbuild/darwin-x64': 0.24.2 - '@esbuild/freebsd-arm64': 0.24.2 - '@esbuild/freebsd-x64': 0.24.2 - '@esbuild/linux-arm': 0.24.2 - '@esbuild/linux-arm64': 0.24.2 - '@esbuild/linux-ia32': 0.24.2 - '@esbuild/linux-loong64': 0.24.2 - '@esbuild/linux-mips64el': 0.24.2 - '@esbuild/linux-ppc64': 0.24.2 - '@esbuild/linux-riscv64': 0.24.2 - '@esbuild/linux-s390x': 0.24.2 - '@esbuild/linux-x64': 0.24.2 - '@esbuild/netbsd-arm64': 0.24.2 - '@esbuild/netbsd-x64': 0.24.2 - '@esbuild/openbsd-arm64': 0.24.2 - '@esbuild/openbsd-x64': 0.24.2 - '@esbuild/sunos-x64': 0.24.2 - '@esbuild/win32-arm64': 0.24.2 - '@esbuild/win32-ia32': 0.24.2 - '@esbuild/win32-x64': 0.24.2 - dev: true - - /esbuild@0.25.0: - resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} - engines: {node: '>=18'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.0 - '@esbuild/android-arm': 0.25.0 - '@esbuild/android-arm64': 0.25.0 - '@esbuild/android-x64': 0.25.0 - '@esbuild/darwin-arm64': 0.25.0 - '@esbuild/darwin-x64': 0.25.0 - '@esbuild/freebsd-arm64': 0.25.0 - '@esbuild/freebsd-x64': 0.25.0 - '@esbuild/linux-arm': 0.25.0 - '@esbuild/linux-arm64': 0.25.0 - '@esbuild/linux-ia32': 0.25.0 - '@esbuild/linux-loong64': 0.25.0 - '@esbuild/linux-mips64el': 0.25.0 - '@esbuild/linux-ppc64': 0.25.0 - '@esbuild/linux-riscv64': 0.25.0 - '@esbuild/linux-s390x': 0.25.0 - '@esbuild/linux-x64': 0.25.0 - '@esbuild/netbsd-arm64': 0.25.0 - '@esbuild/netbsd-x64': 0.25.0 - '@esbuild/openbsd-arm64': 0.25.0 - '@esbuild/openbsd-x64': 0.25.0 - '@esbuild/sunos-x64': 0.25.0 - '@esbuild/win32-arm64': 0.25.0 - '@esbuild/win32-ia32': 0.25.0 - '@esbuild/win32-x64': 0.25.0 + '@esbuild/aix-ppc64': 0.25.2 + '@esbuild/android-arm': 0.25.2 + '@esbuild/android-arm64': 0.25.2 + '@esbuild/android-x64': 0.25.2 + '@esbuild/darwin-arm64': 0.25.2 + '@esbuild/darwin-x64': 0.25.2 + '@esbuild/freebsd-arm64': 0.25.2 + '@esbuild/freebsd-x64': 0.25.2 + '@esbuild/linux-arm': 0.25.2 + '@esbuild/linux-arm64': 0.25.2 + '@esbuild/linux-ia32': 0.25.2 + '@esbuild/linux-loong64': 0.25.2 + '@esbuild/linux-mips64el': 0.25.2 + '@esbuild/linux-ppc64': 0.25.2 + '@esbuild/linux-riscv64': 0.25.2 + '@esbuild/linux-s390x': 0.25.2 + '@esbuild/linux-x64': 0.25.2 + '@esbuild/netbsd-arm64': 0.25.2 + '@esbuild/netbsd-x64': 0.25.2 + '@esbuild/openbsd-arm64': 0.25.2 + '@esbuild/openbsd-x64': 0.25.2 + '@esbuild/sunos-x64': 0.25.2 + '@esbuild/win32-arm64': 0.25.2 + '@esbuild/win32-ia32': 0.25.2 + '@esbuild/win32-x64': 0.25.2 dev: true /escalade@3.2.0: @@ -4312,38 +3549,133 @@ packages: engines: {node: '>=10'} dev: true - /eslint-config-prettier@10.0.1(eslint@9.20.1): - resolution: {integrity: sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==} + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /eslint-config-prettier@10.1.1(eslint@9.24.0): + resolution: {integrity: sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 9.20.1 + eslint: 9.24.0 dev: true - /eslint-plugin-cypress@4.1.0(eslint@9.20.1): - resolution: {integrity: sha512-JhqkMY02mw74USwK9OFhectx3YSj6Co1NgWBxlGdKvlqiAp9vdEuQqt33DKGQFvvGS/NWtduuhWXWNnU29xDSg==} + /eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0): + resolution: {integrity: sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==} + engines: {node: '>= 4'} + peerDependencies: + eslint-plugin-import: '>=1.4.0' + dependencies: + eslint-plugin-import: 2.31.0(eslint@9.24.0) + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7(supports-color@8.1.1) + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.12.0(eslint-import-resolver-node@0.3.9)(eslint@9.24.0): + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + debug: 3.2.7(supports-color@8.1.1) + eslint: 9.24.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-cypress@4.2.0(eslint@9.24.0): + resolution: {integrity: sha512-v5cyt0VYb1tEEODBJSE44PocYOwQsckyexJhCs7LtdD3FGO6D2GjnZB2s2Sts4RcxdxECTWX01nObOZRs26bQw==} peerDependencies: eslint: '>=9' dependencies: - eslint: 9.20.1 + eslint: 9.24.0 globals: 15.15.0 dev: true - /eslint-plugin-vue@9.32.0(eslint@9.20.1): - resolution: {integrity: sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==} + /eslint-plugin-import@2.31.0(eslint@9.24.0): + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7(supports-color@8.1.1) + doctrine: 2.1.0 + eslint: 9.24.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(eslint-import-resolver-node@0.3.9)(eslint@9.24.0) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-vue@9.33.0(eslint@9.24.0): + resolution: {integrity: sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.20.1) - eslint: 9.20.1 + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) + eslint: 9.24.0 globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 semver: 7.7.1 - vue-eslint-parser: 9.4.3(eslint@9.20.1) + vue-eslint-parser: 9.4.3(eslint@9.24.0) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color @@ -4357,26 +3689,14 @@ packages: estraverse: 5.3.0 dev: true - /eslint-scope@8.2.0: - resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + /eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 dev: true - /eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - dependencies: - eslint-visitor-keys: 1.3.0 - dev: true - - /eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - dev: true - /eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4385,10 +3705,9 @@ packages: /eslint-visitor-keys@4.2.0: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - dev: true - /eslint@9.20.1: - resolution: {integrity: sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==} + /eslint@9.24.0: + resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -4397,24 +3716,25 @@ packages: jiti: optional: true dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.20.1) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.19.2 - '@eslint/core': 0.11.0 - '@eslint/eslintrc': 3.2.0 - '@eslint/js': 9.20.0 - '@eslint/plugin-kit': 0.2.6 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.1 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.24.0 + '@eslint/plugin-kit': 0.2.8 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.2 - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.0(supports-color@8.1.1) escape-string-regexp: 4.0.0 - eslint-scope: 8.2.0 + eslint-scope: 8.3.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 esquery: 1.6.0 @@ -4439,29 +3759,25 @@ packages: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 - dev: true - - /espree@6.2.1: - resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} - engines: {node: '>=6.0.0'} - dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.2(acorn@7.4.1) - eslint-visitor-keys: 1.3.0 - dev: true /espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 3.4.3 dev: true + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + /esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -4484,6 +3800,12 @@ packages: /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.7 + dev: true + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -4563,6 +3885,11 @@ packages: pify: 2.3.0 dev: true + /expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + engines: {node: '>=12.0.0'} + dev: true + /express@4.21.2: resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} @@ -4647,7 +3974,6 @@ packages: /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true /fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} @@ -4662,11 +3988,9 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.8 - dev: true /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -4676,11 +4000,10 @@ packages: resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} dev: true - /fastq@1.19.0: - resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} + /fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} dependencies: - reusify: 1.0.4 - dev: true + reusify: 1.1.0 /fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} @@ -4774,12 +4097,6 @@ packages: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} dev: true - /focus-trap@7.6.4: - resolution: {integrity: sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==} - dependencies: - tabbable: 6.2.0 - dev: true - /follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -4788,9 +4105,17 @@ packages: peerDependenciesMeta: debug: optional: true + dev: false - /foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + /for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} dependencies: cross-spawn: 7.0.6 @@ -4885,17 +4210,29 @@ packages: /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + /function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - dev: true - - /get-intrinsic@1.2.7: - resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} + /get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} dependencies: call-bind-apply-helpers: 1.0.2 @@ -4932,6 +4269,15 @@ packages: engines: {node: '>=10'} dev: false + /get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + dev: true + /getos@3.2.1: resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} dependencies: @@ -4959,7 +4305,6 @@ packages: engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - dev: true /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} @@ -4976,7 +4321,7 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true dependencies: - foreground-child: 3.3.0 + foreground-child: 3.3.1 jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 @@ -5018,13 +4363,25 @@ packages: /globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - dev: true /globals@15.15.0: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} dev: true + /globals@16.0.0: + resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} + engines: {node: '>=18'} + dev: true + + /globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + dev: true + /globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} dev: true @@ -5098,10 +4455,28 @@ packages: whatwg-mimetype: 3.0.0 dev: true + /has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + dev: true + /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.1 + dev: true + + /has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + dev: true + /has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -5123,37 +4498,11 @@ packages: dependencies: function-bind: 1.1.2 - /hast-util-to-html@9.0.5: - resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - ccount: 2.0.1 - comma-separated-tokens: 2.0.3 - hast-util-whitespace: 3.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.0 - property-information: 7.0.0 - space-separated-tokens: 2.0.2 - stringify-entities: 4.0.4 - zwitch: 2.0.4 - dev: true - - /hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - dependencies: - '@types/hast': 3.0.4 - dev: true - /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true dev: true - /hookable@5.5.3: - resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - dev: true - /html-minifier-terser@7.2.0: resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} engines: {node: ^14.13.1 || >=16.0.0} @@ -5168,10 +4517,6 @@ packages: terser: 5.39.0 dev: true - /html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - dev: true - /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} dev: false @@ -5281,10 +4626,9 @@ packages: /ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - dev: true - /immutable@5.0.3: - resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==} + /immutable@5.1.1: + resolution: {integrity: sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==} dev: true /import-fresh@3.3.1: @@ -5293,7 +4637,6 @@ packages: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true /import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} @@ -5339,20 +4682,29 @@ packages: resolution: {integrity: sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w==} engines: {node: '>=18'} dependencies: - '@inquirer/figures': 1.0.10 + '@inquirer/figures': 1.0.11 ansi-escapes: 4.3.2 cli-width: 4.1.0 external-editor: 3.1.0 mute-stream: 1.0.0 ora: 5.4.1 run-async: 3.0.0 - rxjs: 7.8.1 + rxjs: 7.8.2 string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 dev: true + /internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + dev: true + /ip@1.1.9: resolution: {integrity: sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==} dev: true @@ -5361,10 +4713,37 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + /is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + dev: true + /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: true + /is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + dev: true + + /is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + dependencies: + has-bigints: 1.1.0 + dev: true + /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -5372,6 +4751,19 @@ packages: binary-extensions: 2.3.0 dev: true + /is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + /is-ci@3.0.1: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true @@ -5379,6 +4771,30 @@ packages: ci-info: 3.9.0 dev: false + /is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + dependencies: + hasown: 2.0.2 + dev: true + + /is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + dev: true + + /is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + dev: true + /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -5393,10 +4809,27 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + /is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + dev: true + /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + /is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + dev: true + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -5422,11 +4855,24 @@ packages: engines: {node: '>=8'} dev: true + /is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + dev: true + /is-npm@6.0.0: resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: false + /is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + dev: true + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -5456,6 +4902,28 @@ packages: isobject: 3.0.1 dev: true + /is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + dev: true + + /is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + dev: true + /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -5465,6 +4933,23 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: false + /is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + dev: true + + /is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + dev: true + /is-text-path@2.0.0: resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} engines: {node: '>=8'} @@ -5472,6 +4957,13 @@ packages: text-extensions: 2.4.0 dev: true + /is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.19 + dev: true + /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} @@ -5480,9 +4972,24 @@ packages: engines: {node: '>=10'} dev: true - /is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} + /is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + dev: true + + /is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + dev: true + + /is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 dev: true /is-wsl@2.2.0: @@ -5506,6 +5013,10 @@ packages: /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + /isbinaryfile@5.0.4: resolution: {integrity: sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==} engines: {node: '>= 18.0.0'} @@ -5536,8 +5047,8 @@ packages: hasBin: true dev: true - /js-beautify@1.15.3: - resolution: {integrity: sha512-rKKGuyTxGNlyN4EQKWzNndzXpi0bOl8Gl8YQAW1as/oMz0XhD6sHJO1hTvoBDOSzKuJb9WkwoAb34FfdkKMv2A==} + /js-beautify@1.15.4: + resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} engines: {node: '>=14'} hasBin: true dependencies: @@ -5545,7 +5056,7 @@ packages: editorconfig: 1.0.4 glob: 10.4.5 js-cookie: 3.0.5 - nopt: 8.1.0 + nopt: 7.2.1 dev: true /js-cookie@3.0.5: @@ -5562,7 +5073,6 @@ packages: hasBin: true dependencies: argparse: 2.0.1 - dev: true /jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} @@ -5577,7 +5087,6 @@ packages: /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} @@ -5608,15 +5117,14 @@ packages: hasBin: true dev: true - /jsonc-eslint-parser@1.4.1: - resolution: {integrity: sha512-hXBrvsR1rdjmB2kQmUjf1rEIa+TqHBGMge8pwi++C+Si1ad7EjZrJcpgwym+QGK/pqTx+K7keFAtLlVNdLRJOg==} - engines: {node: '>=8.10.0'} + /jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 7.4.1 - eslint-utils: 2.1.0 - eslint-visitor-keys: 1.3.0 - espree: 6.2.1 - semver: 6.3.1 + acorn: 8.14.1 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.7.1 dev: true /jsonfile@4.0.0: @@ -5716,16 +5224,11 @@ packages: log-update: 4.0.0 p-map: 4.0.0 rfdc: 1.4.1 - rxjs: 7.8.1 + rxjs: 7.8.2 through: 2.3.8 wrap-ansi: 7.0.0 dev: true - /local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} - engines: {node: '>=14'} - dev: true - /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -5836,10 +5339,8 @@ packages: js-tokens: 4.0.0 dev: true - /loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - dependencies: - get-func-name: 2.0.2 + /loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} dev: true /lower-case@2.0.2: @@ -5880,28 +5381,10 @@ packages: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 - /mark.js@8.11.1: - resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} - dev: true - /math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - /mdast-util-to-hast@13.2.0: - resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 - devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.1 - trim-lines: 3.0.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - dev: true - /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -5920,7 +5403,6 @@ packages: /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: true /merge@2.1.1: resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==} @@ -5930,33 +5412,6 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - /micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} - dependencies: - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 - dev: true - - /micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} - dev: true - - /micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} - dependencies: - micromark-util-character: 2.1.1 - micromark-util-encode: 2.0.1 - micromark-util-symbol: 2.0.1 - dev: true - - /micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} - dev: true - - /micromark-util-types@2.0.1: - resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==} - dev: true - /micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -5968,8 +5423,8 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - /mime-db@1.53.0: - resolution: {integrity: sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==} + /mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} /mime-types@2.1.35: @@ -6041,14 +5496,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dev: true - /minisearch@7.1.2: - resolution: {integrity: sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA==} - dev: true - - /mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - dev: true - /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -6058,10 +5505,10 @@ packages: /mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} dependencies: - acorn: 8.14.0 + acorn: 8.14.1 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.5.4 + ufo: 1.6.0 dev: true /mocha@11.1.0: @@ -6115,7 +5562,7 @@ packages: prop-types: 15.8.1 tcomb: 3.2.29 tcomb-validation: 3.4.1 - validator: 13.12.0 + validator: 13.15.0 yargs: 17.7.2 dev: true @@ -6160,8 +5607,8 @@ packages: thenify-all: 1.6.0 dev: true - /nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + /nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -6202,12 +5649,12 @@ packages: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} dev: true - /nopt@8.1.0: - resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} - engines: {node: ^18.17.0 || >=20.5.0} + /nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true dependencies: - abbrev: 3.0.0 + abbrev: 2.0.0 dev: true /normalize-path@3.0.0: @@ -6257,6 +5704,52 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + dev: true + + /object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + dev: true + + /object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + dev: true + + /object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + /on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -6285,14 +5778,6 @@ packages: mimic-fn: 4.0.0 dev: false - /oniguruma-to-es@3.1.1: - resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==} - dependencies: - emoji-regex-xs: 1.0.0 - regex: 6.0.1 - regex-recursion: 6.0.2 - dev: true - /open@10.1.0: resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} engines: {node: '>=18'} @@ -6362,6 +5847,15 @@ packages: resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} dev: true + /own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + dev: true + /p-cancelable@2.1.1: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} @@ -6390,7 +5884,7 @@ packages: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: - yocto-queue: 1.1.1 + yocto-queue: 1.2.1 dev: true /p-locate@4.1.0: @@ -6452,7 +5946,6 @@ packages: engines: {node: '>=6'} dependencies: callsites: 3.1.0 - dev: true /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} @@ -6498,6 +5991,10 @@ packages: engines: {node: '>=12'} dev: false + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + /path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -6517,17 +6014,14 @@ packages: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} dev: true - /pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + /pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} dev: true /pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - /perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} - dev: true - /performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: true @@ -6549,7 +6043,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /pinia@2.3.1(typescript@5.7.3)(vue@3.5.13): + /pinia@2.3.1(typescript@5.8.3)(vue@3.5.13): resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==} peerDependencies: typescript: '>=4.4.4' @@ -6559,14 +6053,14 @@ packages: optional: true dependencies: '@vue/devtools-api': 6.6.4 - typescript: 5.7.3 - vue: 3.5.13(typescript@5.7.3) + typescript: 5.8.3 + vue: 3.5.13(typescript@5.8.3) vue-demi: 0.14.10(vue@3.5.13) transitivePeerDependencies: - '@vue/composition-api' - /pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + /pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} dev: true @@ -6578,6 +6072,11 @@ packages: pathe: 2.0.3 dev: true + /possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + dev: true + /postcss-selector-parser@6.1.2: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} @@ -6594,21 +6093,17 @@ packages: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.8 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 - /preact@10.26.2: - resolution: {integrity: sha512-0gNmv4qpS9HaN3+40CLBAnKe0ZfyE4ZWo5xKlC1rVrr0ckkEvJvAQqKaHANdFKsGstoxrY4AItZ7kZSGVoVjgg==} - dev: true - /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} dev: true - /prettier@3.5.1: - resolution: {integrity: sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==} + /prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} engines: {node: '>=14'} hasBin: true dev: true @@ -6618,15 +6113,6 @@ packages: engines: {node: '>=6'} dev: true - /pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - dev: true - /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -6648,10 +6134,6 @@ packages: react-is: 16.13.1 dev: true - /property-information@7.0.0: - resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} - dev: true - /proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -6668,6 +6150,7 @@ packages: /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false /pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} @@ -6682,7 +6165,6 @@ packages: /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - dev: true /pupa@3.1.0: resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==} @@ -6697,20 +6179,19 @@ packages: dependencies: side-channel: 1.1.0 - /qs@6.13.1: - resolution: {integrity: sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==} + /qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} dependencies: side-channel: 1.1.0 dev: true - /quasar@2.17.7: - resolution: {integrity: sha512-nPJdHoONlcW7WEU2Ody907Wx945Zfyuea/KP4LBaEn5AcL95PUWp8Gz/0zDYNnFw0aCWRtye3SUAdQl5tmrn5w==} + /quasar@2.18.1: + resolution: {integrity: sha512-db/P64Mzpt1uXJ0MapaG+IYJQ9hHDb5KtTCoszwC78DR7sA+Uoj7nBW2EytwYykIExEmqavOvKrdasTvqhkgEg==} engines: {node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1'} /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true /quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} @@ -6746,25 +6227,21 @@ packages: strip-json-comments: 2.0.1 dev: false - /react-dom@19.0.0(react@19.0.0): - resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} + /react-dom@19.1.0(react@19.1.0): + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} peerDependencies: - react: ^19.0.0 + react: ^19.1.0 dependencies: - react: 19.0.0 - scheduler: 0.25.0 + react: 19.1.0 + scheduler: 0.26.0 dev: true /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true - /react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - dev: true - - /react@19.0.0: - resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} + /react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} engines: {node: '>=0.10.0'} dev: true @@ -6827,24 +6304,34 @@ packages: tslib: 1.14.1 dev: true + /reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + dev: true + /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} dev: true - /regex-recursion@6.0.2: - resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + /regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} dependencies: - regex-utilities: 2.3.0 - dev: true - - /regex-utilities@2.3.0: - resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} - dev: true - - /regex@6.0.1: - resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} - dependencies: - regex-utilities: 2.3.0 + 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 dev: true /registry-auth-token@5.1.0: @@ -6897,13 +6384,22 @@ packages: /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - dev: true /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} dev: true + /resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} dependencies: @@ -6925,10 +6421,9 @@ packages: signal-exit: 3.0.7 dev: true - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + /reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true /rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} @@ -6961,32 +6456,33 @@ packages: yargs: 17.7.2 dev: true - /rollup@4.34.8: - resolution: {integrity: sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==} + /rollup@4.39.0: + resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.34.8 - '@rollup/rollup-android-arm64': 4.34.8 - '@rollup/rollup-darwin-arm64': 4.34.8 - '@rollup/rollup-darwin-x64': 4.34.8 - '@rollup/rollup-freebsd-arm64': 4.34.8 - '@rollup/rollup-freebsd-x64': 4.34.8 - '@rollup/rollup-linux-arm-gnueabihf': 4.34.8 - '@rollup/rollup-linux-arm-musleabihf': 4.34.8 - '@rollup/rollup-linux-arm64-gnu': 4.34.8 - '@rollup/rollup-linux-arm64-musl': 4.34.8 - '@rollup/rollup-linux-loongarch64-gnu': 4.34.8 - '@rollup/rollup-linux-powerpc64le-gnu': 4.34.8 - '@rollup/rollup-linux-riscv64-gnu': 4.34.8 - '@rollup/rollup-linux-s390x-gnu': 4.34.8 - '@rollup/rollup-linux-x64-gnu': 4.34.8 - '@rollup/rollup-linux-x64-musl': 4.34.8 - '@rollup/rollup-win32-arm64-msvc': 4.34.8 - '@rollup/rollup-win32-ia32-msvc': 4.34.8 - '@rollup/rollup-win32-x64-msvc': 4.34.8 + '@rollup/rollup-android-arm-eabi': 4.39.0 + '@rollup/rollup-android-arm64': 4.39.0 + '@rollup/rollup-darwin-arm64': 4.39.0 + '@rollup/rollup-darwin-x64': 4.39.0 + '@rollup/rollup-freebsd-arm64': 4.39.0 + '@rollup/rollup-freebsd-x64': 4.39.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 + '@rollup/rollup-linux-arm-musleabihf': 4.39.0 + '@rollup/rollup-linux-arm64-gnu': 4.39.0 + '@rollup/rollup-linux-arm64-musl': 4.39.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-musl': 4.39.0 + '@rollup/rollup-linux-s390x-gnu': 4.39.0 + '@rollup/rollup-linux-x64-gnu': 4.39.0 + '@rollup/rollup-linux-x64-musl': 4.39.0 + '@rollup/rollup-win32-arm64-msvc': 4.39.0 + '@rollup/rollup-win32-ia32-msvc': 4.39.0 + '@rollup/rollup-win32-x64-msvc': 4.39.0 fsevents: 2.3.3 dev: true @@ -7020,25 +6516,52 @@ packages: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - dev: true - /rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + /rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} dependencies: tslib: 2.8.1 dev: true + /safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + dev: true + /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + /safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + dev: true + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /sass-embedded-android-arm64@1.85.0: - resolution: {integrity: sha512-4itDzRwezwrW8+YzMLIwHtMeH+qrBNdBsRn9lTVI15K+cNLC8z5JWJi6UCZ8TNNZr9LDBfsh5jUdjSub0yF7jg==} + /sass-embedded-android-arm64@1.86.3: + resolution: {integrity: sha512-q+XwFp6WgAv+UgnQhsB8KQ95kppvWAB7DSoJp+8Vino8b9ND+1ai3cUUZPE5u4SnLZrgo5NtrbPvN5KLc4Pfyg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [android] @@ -7046,8 +6569,8 @@ packages: dev: true optional: true - /sass-embedded-android-arm@1.85.0: - resolution: {integrity: sha512-pPBT7Ad6G8Mlao8ypVNXW2ya7I/Bhcny+RYZ/EmrunEXfhzCNp4PWV2VAweitPO9RnPIJwvUTkLc8Fu6K3nVmw==} + /sass-embedded-android-arm@1.86.3: + resolution: {integrity: sha512-UyeXrFzZSvrGbvrWUBcspbsbivGgAgebLGJdSqJulgSyGbA6no3DWQ5Qpdd6+OAUC39BlpPu74Wx9s4RrVuaFw==} engines: {node: '>=14.0.0'} cpu: [arm] os: [android] @@ -7055,8 +6578,8 @@ packages: dev: true optional: true - /sass-embedded-android-ia32@1.85.0: - resolution: {integrity: sha512-bwqKq95hzbGbMTeXCMQhH7yEdc2xJVwIXj7rGdD3McvyFWbED6362XRFFPI5YyjfD2wRJd9yWLh/hn+6VyjcYA==} + /sass-embedded-android-ia32@1.86.3: + resolution: {integrity: sha512-gTJjVh2cRzvGujXj5ApPk/owUTL5SiO7rDtNLrzYAzi1N5HRuLYXqk3h1IQY3+eCOBjGl7mQ9XyySbJs/3hDvg==} engines: {node: '>=14.0.0'} cpu: [ia32] os: [android] @@ -7064,8 +6587,8 @@ packages: dev: true optional: true - /sass-embedded-android-riscv64@1.85.0: - resolution: {integrity: sha512-Fgkgay+5EePJXZFHR5Vlkutnsmox2V6nX4U3mfGbSN1xjLRm8F5ST72V2s5Z0mnIFpGvEu/v7hfptgViqMvaxg==} + /sass-embedded-android-riscv64@1.86.3: + resolution: {integrity: sha512-Po3JnyiCS16kd6REo1IMUbFGYtvL9O0rmKaXx5vOuBaJD1LPy2LiSSp7TU7wkJ9IxsTDGzFaSeP1I9qb6D8VVg==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [android] @@ -7073,8 +6596,8 @@ packages: dev: true optional: true - /sass-embedded-android-x64@1.85.0: - resolution: {integrity: sha512-/bG3JgTn3eoIDHCiJNVkLeJgUesat4ghxqYmKMZUJx++4e6iKCDj8XwQTJAgm+QDrsPKXHBacHEANJ9LEAuTqg==} + /sass-embedded-android-x64@1.86.3: + resolution: {integrity: sha512-+7h3jdDv/0kUFx0BvxYlq2fa7CcHiDPlta6k5OxO5K6jyqJwo9hc0Z052BoYEauWTqZ+vK6bB5rv2BIzq4U9nA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [android] @@ -7082,8 +6605,8 @@ packages: dev: true optional: true - /sass-embedded-darwin-arm64@1.85.0: - resolution: {integrity: sha512-plp8TyMz97YFBCB3ndftEvoW29vyfsSBJILM5U84cGzr06SvLh/Npjj8psfUeRw+upEk1zkFtw5u61sRCdgwIw==} + /sass-embedded-darwin-arm64@1.86.3: + resolution: {integrity: sha512-EgLwV4ORm5Hr0DmIXo0Xw/vlzwLnfAiqD2jDXIglkBsc5czJmo4/IBdGXOP65TRnsgJEqvbU3aQhuawX5++x9A==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [darwin] @@ -7091,8 +6614,8 @@ packages: dev: true optional: true - /sass-embedded-darwin-x64@1.85.0: - resolution: {integrity: sha512-LP8Zv8DG57Gn6PmSwWzC0gEZUsGdg36Ps3m0i1fVTOelql7N3HZIrlPYRjJvidL8ZlB3ISxNANebTREUHn/wkQ==} + /sass-embedded-darwin-x64@1.86.3: + resolution: {integrity: sha512-dfKhfrGPRNLWLC82vy/vQGmNKmAiKWpdFuWiePRtg/E95pqw+sCu6080Y6oQLfFu37Iq3MpnXiSpDuSo7UnPWA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [darwin] @@ -7100,8 +6623,8 @@ packages: dev: true optional: true - /sass-embedded-linux-arm64@1.85.0: - resolution: {integrity: sha512-JRIRKVOY5Y8M1zlUOv9AQGju4P6lj8i5vLJZsVYVN/uY8Cd2dDJZPC8EOhjntp+IpF8AOGIHqCeCkHBceIyIjA==} + /sass-embedded-linux-arm64@1.86.3: + resolution: {integrity: sha512-tYq5rywR53Qtc+0KI6pPipOvW7a47ETY69VxfqI9BR2RKw2hBbaz0bIw6OaOgEBv2/XNwcWb7a4sr7TqgkqKAA==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] @@ -7109,8 +6632,8 @@ packages: dev: true optional: true - /sass-embedded-linux-arm@1.85.0: - resolution: {integrity: sha512-18xOAEfazJt1MMVS2TRHV94n81VyMnywOoJ7/S7I79qno/zx26OoqqP4XvH107xu8+mZ9Gg54LrUH6ZcgHk08g==} + /sass-embedded-linux-arm@1.86.3: + resolution: {integrity: sha512-+fVCIH+OR0SMHn2NEhb/VfbpHuUxcPtqMS34OCV3Ka99LYZUJZqth4M3lT/ppGl52mwIVLNYzR4iLe6mdZ6mYA==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] @@ -7118,8 +6641,8 @@ packages: dev: true optional: true - /sass-embedded-linux-ia32@1.85.0: - resolution: {integrity: sha512-4JH+h+gLt9So22nNPQtsKojEsLzjld9ol3zWcOtMGclv+HojZGbCuhJUrLUcK72F8adXYsULmWhJPKROLIwYMA==} + /sass-embedded-linux-ia32@1.86.3: + resolution: {integrity: sha512-CmQ5OkqnaeLdaF+bMqlYGooBuenqm3LvEN9H8BLhjkpWiFW8hnYMetiqMcJjhrXLvDw601KGqA5sr/Rsg5s45g==} engines: {node: '>=14.0.0'} cpu: [ia32] os: [linux] @@ -7127,8 +6650,8 @@ packages: dev: true optional: true - /sass-embedded-linux-musl-arm64@1.85.0: - resolution: {integrity: sha512-aoQjUjK28bvdw9XKTjQeayn8oWQ2QqvoTD11myklGd3IHH7Jj0nwXUstI4NxDueCKt3wghuZoIQkjOheReQxlg==} + /sass-embedded-linux-musl-arm64@1.86.3: + resolution: {integrity: sha512-4zOr2C/eW89rxb4ozTfn7lBzyyM5ZigA1ZSRTcAR26Qbg/t2UksLdGnVX9/yxga0d6aOi0IvO/7iM2DPPRRotg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] @@ -7136,8 +6659,8 @@ packages: dev: true optional: true - /sass-embedded-linux-musl-arm@1.85.0: - resolution: {integrity: sha512-Z1j4ageDVFihqNUBnm89fxY46pY0zD/Clp1D3ZdI7S+D280+AEpbm5vMoH8LLhBQfQLf2w7H++SZGpQwrisudQ==} + /sass-embedded-linux-musl-arm@1.86.3: + resolution: {integrity: sha512-SEm65SQknI4pl+mH5Xf231hOkHJyrlgh5nj4qDbiBG6gFeutaNkNIeRgKEg3cflXchCr8iV/q/SyPgjhhzQb7w==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] @@ -7145,8 +6668,8 @@ packages: dev: true optional: true - /sass-embedded-linux-musl-ia32@1.85.0: - resolution: {integrity: sha512-/cJCSXOfXmQFH8deE+3U9x+BSz8i0d1Tt9gKV/Gat1Xm43Oumw8pmZgno+cDuGjYQInr9ryW5121pTMlj/PBXQ==} + /sass-embedded-linux-musl-ia32@1.86.3: + resolution: {integrity: sha512-84Tcld32LB1loiqUvczWyVBQRCChm0wNLlkT59qF29nxh8njFIVf9yaPgXcSyyjpPoD9Tu0wnq3dvVzoMCh9AQ==} engines: {node: '>=14.0.0'} cpu: [ia32] os: [linux] @@ -7154,8 +6677,8 @@ packages: dev: true optional: true - /sass-embedded-linux-musl-riscv64@1.85.0: - resolution: {integrity: sha512-l+FJxMXkmg42RZq5RFKXg4InX0IA7yEiPHe4kVSdrczP7z3NLxk+W9wVkPnoRKYIMe1qZPPQ25y0TgI4HNWouA==} + /sass-embedded-linux-musl-riscv64@1.86.3: + resolution: {integrity: sha512-IxEqoiD7vdNpiOwccybbV93NljBy64wSTkUOknGy21SyV43C8uqESOwTwW9ywa3KufImKm8L3uQAW/B0KhJMWg==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] @@ -7163,8 +6686,8 @@ packages: dev: true optional: true - /sass-embedded-linux-musl-x64@1.85.0: - resolution: {integrity: sha512-M9ffjcYfFcRvkFA6V3DpOS955AyvmpvPAhL/xNK45d/ma1n1ehTWpd24tVeKiNK5CZkNjjMEfyw2fHa6MpqmEA==} + /sass-embedded-linux-musl-x64@1.86.3: + resolution: {integrity: sha512-ePeTPXUxPK6JgHcUfnrkIyDtyt+zlAvF22mVZv6y1g/PZFm1lSfX+Za7TYHg9KaYqaaXDiw6zICX4i44HhR8rA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] @@ -7172,8 +6695,8 @@ packages: dev: true optional: true - /sass-embedded-linux-riscv64@1.85.0: - resolution: {integrity: sha512-yqPXQWfM+qiIPkfn++48GOlbmSvUZIyL9nwFstBk0k4x40UhbhilfknqeTUpxoHfQzylTGVhrm5JE7MjM+LNZA==} + /sass-embedded-linux-riscv64@1.86.3: + resolution: {integrity: sha512-NuXQ72dwfNLe35E+RaXJ4Noq4EkFwM65eWwCwxEWyJO9qxOx1EXiCAJii6x8kkOh5daWuMU0VAI1B9RsJaqqQQ==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] @@ -7181,8 +6704,8 @@ packages: dev: true optional: true - /sass-embedded-linux-x64@1.85.0: - resolution: {integrity: sha512-NTDeQFZcuVR7COoaRy8pZD6/+QznwBR8kVFsj7NpmvX9aJ7TX/q+OQZHX7Bfb3tsfKXhf1YZozegPuYxRnMKAQ==} + /sass-embedded-linux-x64@1.86.3: + resolution: {integrity: sha512-t8be9zJ5B82+og9bQmIQ83yMGYZMTMrlGA+uGWtYacmwg6w3093dk91Fx0YzNSZBp3Tk60qVYjCZnEIwy60x0g==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] @@ -7190,8 +6713,8 @@ packages: dev: true optional: true - /sass-embedded-win32-arm64@1.85.0: - resolution: {integrity: sha512-gO0VAuxC4AdV+uZYJESRWVVHQWCGzNs0C3OKCAdH4r1vGRugooMi7J/5wbwUdXDA1MV9ICfhlKsph2n3GiPdqA==} + /sass-embedded-win32-arm64@1.86.3: + resolution: {integrity: sha512-4ghuAzjX4q8Nksm0aifRz8hgXMMxS0SuymrFfkfJlrSx68pIgvAge6AOw0edoZoe0Tf5ZbsWUWamhkNyNxkTvw==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [win32] @@ -7199,8 +6722,8 @@ packages: dev: true optional: true - /sass-embedded-win32-ia32@1.85.0: - resolution: {integrity: sha512-PCyn6xeFIBUgBceNypuf73/5DWF2VWPlPqPuBprPsTvpZOMUJeBtP+Lf4mnu3dNy1z76mYVnpaCnQmzZ0zHZaA==} + /sass-embedded-win32-ia32@1.86.3: + resolution: {integrity: sha512-tCaK4zIRq9mLRPxLzBAdYlfCuS/xLNpmjunYxeWkIwlJo+k53h1udyXH/FInnQ2GgEz0xMXyvH3buuPgzwWYsw==} engines: {node: '>=14.0.0'} cpu: [ia32] os: [win32] @@ -7208,8 +6731,8 @@ packages: dev: true optional: true - /sass-embedded-win32-x64@1.85.0: - resolution: {integrity: sha512-AknE2jLp6OBwrR5hQ8pDsG94KhJCeSheFJ2xgbnk8RUjZX909JiNbgh2sNt9LG+RXf4xZa55dDL537gZoCx/iw==} + /sass-embedded-win32-x64@1.86.3: + resolution: {integrity: sha512-zS+YNKfTF4SnOfpC77VTb0qNZyTXrxnAezSoRV0xnw6HlY+1WawMSSB6PbWtmbvyfXNgpmJUttoTtsvJjRCucg==} engines: {node: '>=14.0.0'} cpu: [x64] os: [win32] @@ -7217,49 +6740,49 @@ packages: dev: true optional: true - /sass-embedded@1.85.0: - resolution: {integrity: sha512-x3Vv54g0jv1aPSW8OTA/0GzQCs/HMQOjIkLtZJ3Xsn/I4vnyjKbVTQmFTax9bQjldqLEEkdbvy6ES/cOOnYNwA==} + /sass-embedded@1.86.3: + resolution: {integrity: sha512-3pZSp24ibO1hdopj+W9DuiWsZOb2YY6AFRo/jjutKLBkqJGM1nJjXzhAYfzRV+Xn5BX1eTI4bBTE09P0XNHOZg==} engines: {node: '>=16.0.0'} hasBin: true dependencies: - '@bufbuild/protobuf': 2.2.3 + '@bufbuild/protobuf': 2.2.5 buffer-builder: 0.2.0 colorjs.io: 0.5.2 - immutable: 5.0.3 - rxjs: 7.8.1 + immutable: 5.1.1 + rxjs: 7.8.2 supports-color: 8.1.1 sync-child-process: 1.0.2 varint: 6.0.0 optionalDependencies: - sass-embedded-android-arm: 1.85.0 - sass-embedded-android-arm64: 1.85.0 - sass-embedded-android-ia32: 1.85.0 - sass-embedded-android-riscv64: 1.85.0 - sass-embedded-android-x64: 1.85.0 - sass-embedded-darwin-arm64: 1.85.0 - sass-embedded-darwin-x64: 1.85.0 - sass-embedded-linux-arm: 1.85.0 - sass-embedded-linux-arm64: 1.85.0 - sass-embedded-linux-ia32: 1.85.0 - sass-embedded-linux-musl-arm: 1.85.0 - sass-embedded-linux-musl-arm64: 1.85.0 - sass-embedded-linux-musl-ia32: 1.85.0 - sass-embedded-linux-musl-riscv64: 1.85.0 - sass-embedded-linux-musl-x64: 1.85.0 - sass-embedded-linux-riscv64: 1.85.0 - sass-embedded-linux-x64: 1.85.0 - sass-embedded-win32-arm64: 1.85.0 - sass-embedded-win32-ia32: 1.85.0 - sass-embedded-win32-x64: 1.85.0 + sass-embedded-android-arm: 1.86.3 + sass-embedded-android-arm64: 1.86.3 + sass-embedded-android-ia32: 1.86.3 + sass-embedded-android-riscv64: 1.86.3 + sass-embedded-android-x64: 1.86.3 + sass-embedded-darwin-arm64: 1.86.3 + sass-embedded-darwin-x64: 1.86.3 + sass-embedded-linux-arm: 1.86.3 + sass-embedded-linux-arm64: 1.86.3 + sass-embedded-linux-ia32: 1.86.3 + sass-embedded-linux-musl-arm: 1.86.3 + sass-embedded-linux-musl-arm64: 1.86.3 + sass-embedded-linux-musl-ia32: 1.86.3 + sass-embedded-linux-musl-riscv64: 1.86.3 + sass-embedded-linux-musl-x64: 1.86.3 + sass-embedded-linux-riscv64: 1.86.3 + sass-embedded-linux-x64: 1.86.3 + sass-embedded-win32-arm64: 1.86.3 + sass-embedded-win32-ia32: 1.86.3 + sass-embedded-win32-x64: 1.86.3 dev: true - /sass@1.85.0: - resolution: {integrity: sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==} + /sass@1.86.3: + resolution: {integrity: sha512-iGtg8kus4GrsGLRDLRBRHY9dNVA78ZaS7xr01cWnS7PEMQyFtTqBiyCrfpTYTZXRWM94akzckYjh8oADfFNTzw==} engines: {node: '>=14.0.0'} hasBin: true dependencies: chokidar: 4.0.3 - immutable: 5.0.3 + immutable: 5.1.1 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.1 @@ -7273,12 +6796,8 @@ packages: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} dev: true - /scheduler@0.25.0: - resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} - dev: true - - /search-insights@2.17.3: - resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} + /scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} dev: true /selfsigned@2.4.1: @@ -7346,6 +6865,37 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + dev: true + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + dev: true + + /set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + dev: true + /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -7366,19 +6916,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - /shiki@2.5.0: - resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==} - dependencies: - '@shikijs/core': 2.5.0 - '@shikijs/engine-javascript': 2.5.0 - '@shikijs/engine-oniguruma': 2.5.0 - '@shikijs/langs': 2.5.0 - '@shikijs/themes': 2.5.0 - '@shikijs/types': 2.5.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - dev: true - /side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -7390,18 +6927,18 @@ packages: resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} engines: {node: '>= 0.4'} dependencies: - call-bound: 1.0.3 + call-bound: 1.0.4 es-errors: 1.3.0 - get-intrinsic: 1.2.7 + get-intrinsic: 1.3.0 object-inspect: 1.13.4 /side-channel-weakmap@1.0.2: resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} engines: {node: '>= 0.4'} dependencies: - call-bound: 1.0.3 + call-bound: 1.0.4 es-errors: 1.3.0 - get-intrinsic: 1.2.7 + get-intrinsic: 1.3.0 object-inspect: 1.13.4 side-channel-map: 1.0.1 @@ -7509,15 +7046,6 @@ packages: engines: {node: '>= 8'} dev: true - /space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - dev: true - - /speakingurl@14.0.1: - resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} - engines: {node: '>=0.10.0'} - dev: true - /split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -7552,8 +7080,8 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - /std-env@3.8.0: - resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + /std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} dev: true /streamx@2.22.0: @@ -7581,6 +7109,38 @@ packages: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + /string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + dev: true + + /string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + + /string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + dev: true + /string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: @@ -7592,13 +7152,6 @@ packages: safe-buffer: 5.2.1 dev: true - /stringify-entities@4.0.4: - resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} - dependencies: - character-entities-html4: 2.1.0 - character-entities-legacy: 3.0.0 - dev: true - /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -7633,13 +7186,6 @@ packages: /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - dev: true - - /strip-literal@1.3.0: - resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} - dependencies: - acorn: 8.14.0 - dev: true /style-mod@4.1.2: resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} @@ -7655,17 +7201,10 @@ packages: glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 - pirates: 4.0.6 + pirates: 4.0.7 ts-interface-checker: 0.1.13 dev: true - /superjson@2.2.2: - resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} - engines: {node: '>=16'} - dependencies: - copy-anything: 3.0.5 - dev: true - /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -7679,6 +7218,11 @@ packages: dependencies: has-flag: 4.0.0 + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + /sync-child-process@1.0.2: resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==} engines: {node: '>=16.0.0'} @@ -7691,10 +7235,6 @@ packages: engines: {node: '>=16.0.0'} dev: true - /tabbable@6.2.0: - resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} - dev: true - /tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} dependencies: @@ -7719,7 +7259,7 @@ packages: hasBin: true dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.14.0 + acorn: 8.14.1 commander: 2.20.3 source-map-support: 0.5.21 dev: true @@ -7772,13 +7312,18 @@ packages: picomatch: 4.0.2 dev: true - /tinypool@0.7.0: - resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + /tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + dev: true + + /tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} dev: true - /tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + /tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} dev: true @@ -7787,15 +7332,15 @@ packages: engines: {node: '>=12'} dev: false - /tldts-core@6.1.78: - resolution: {integrity: sha512-jS0svNsB99jR6AJBmfmEWuKIgz91Haya91Z43PATaeHJ24BkMoNRb/jlaD37VYjb0mYf6gRL/HOnvS1zEnYBiw==} + /tldts-core@6.1.85: + resolution: {integrity: sha512-DTjUVvxckL1fIoPSb3KE7ISNtkWSawZdpfxGxwiIrZoO6EbHVDXXUIlIuWympPaeS+BLGyggozX/HTMsRAdsoA==} dev: true - /tldts@6.1.78: - resolution: {integrity: sha512-fSgYrW0ITH0SR/CqKMXIruYIPpNu5aDgUp22UhYoSrnUQwc7SBqifEBFNce7AAcygUPBo6a/gbtcguWdmko4RQ==} + /tldts@6.1.85: + resolution: {integrity: sha512-gBdZ1RjCSevRPFix/hpaUWeak2/RNUZB4/8frF1r5uYMHjFptkiT0JXIebWvgI/0ZHXvxaUDDJshiA0j6GdL3w==} hasBin: true dependencies: - tldts-core: 6.1.78 + tldts-core: 6.1.85 dev: true /tmp@0.0.33: @@ -7819,11 +7364,11 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - /tough-cookie@5.1.1: - resolution: {integrity: sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA==} + /tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} dependencies: - tldts: 6.1.78 + tldts: 6.1.85 dev: true /tree-kill@1.2.2: @@ -7831,11 +7376,7 @@ packages: hasBin: true dev: true - /trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - dev: true - - /ts-essentials@9.4.2(typescript@5.7.3): + /ts-essentials@9.4.2(typescript@5.8.3): resolution: {integrity: sha512-mB/cDhOvD7pg3YCLk2rOtejHjjdSi9in/IBYE13S+8WA5FBSraYf4V/ws55uvs0IvQ/l0wBOlXy5yBNZ9Bl8ZQ==} peerDependencies: typescript: '>=4.1.0' @@ -7843,14 +7384,14 @@ packages: typescript: optional: true dependencies: - typescript: 5.7.3 + typescript: 5.8.3 dev: true /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true - /tsconfck@3.1.5(typescript@5.7.3): + /tsconfck@3.1.5(typescript@5.8.3): resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} engines: {node: ^18 || >=20} hasBin: true @@ -7860,7 +7401,7 @@ packages: typescript: optional: true dependencies: - typescript: 5.7.3 + typescript: 5.8.3 dev: true /tsconfig-paths@3.15.0: @@ -7902,11 +7443,6 @@ packages: prelude-ls: 1.2.1 dev: true - /type-detect@4.1.0: - resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} - engines: {node: '>=4'} - dev: true - /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} @@ -7927,8 +7463,8 @@ packages: engines: {node: '>=12.20'} dev: false - /type-fest@4.35.0: - resolution: {integrity: sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==} + /type-fest@4.39.1: + resolution: {integrity: sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==} engines: {node: '>=16'} dev: true @@ -7939,6 +7475,51 @@ packages: media-typer: 0.3.0 mime-types: 2.1.35 + /typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + dev: true + + /typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + dev: true + + /typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + dev: true + + /typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + dev: true + /typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: @@ -7949,13 +7530,13 @@ packages: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} dev: false - /typescript@5.7.3: - resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + /typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true - /ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + /ufo@1.6.0: + resolution: {integrity: sha512-AkgU2cV/+Xb4Uz6cic0kMZbtM42nbltnGvTVOt/8gMCbO2/z64nE47TOygh7HjgFPkUkVRBEyNFqpqi3zo+BJA==} dev: true /uglify-js@3.19.3: @@ -7966,8 +7547,18 @@ packages: dev: true optional: true - /undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + /unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + dev: true + + /undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} /unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} @@ -7981,39 +7572,6 @@ packages: crypto-random-string: 4.0.0 dev: false - /unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - dependencies: - '@types/unist': 3.0.3 - dev: true - - /unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - dependencies: - '@types/unist': 3.0.3 - dev: true - - /unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - dependencies: - '@types/unist': 3.0.3 - dev: true - - /unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - dev: true - - /unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - dev: true - /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -8031,7 +7589,7 @@ packages: resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} dependencies: - acorn: 8.14.0 + acorn: 8.14.1 webpack-virtual-modules: 0.6.2 dev: true @@ -8039,8 +7597,8 @@ packages: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} - /update-browserslist-db@1.1.2(browserslist@4.24.4): - resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} + /update-browserslist-db@1.1.3(browserslist@4.24.4): + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -8074,7 +7632,6 @@ packages: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.1 - dev: true /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -8088,8 +7645,8 @@ packages: hasBin: true dev: true - /validator@13.12.0: - resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} + /validator@13.15.0: + resolution: {integrity: sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==} engines: {node: '>= 0.10'} /varint@6.0.0: @@ -8109,21 +7666,7 @@ packages: extsprintf: 1.3.0 dev: true - /vfile-message@4.0.2: - resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - dependencies: - '@types/unist': 3.0.3 - unist-util-stringify-position: 4.0.0 - dev: true - - /vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - dependencies: - '@types/unist': 3.0.3 - vfile-message: 4.0.2 - dev: true - - /vite-jsconfig-paths@2.0.1(vite@6.2.0): + /vite-jsconfig-paths@2.0.1(vite@6.2.5): resolution: {integrity: sha512-rabcTTfKs0MdAsQWcZjbIMo5fcp6jthZce7uFEPgVPgpSY+RNOwjzIJOPES6cB/GJZLSoLGfHM9kt5HNmJvp7A==} peerDependencies: vite: '>2.0.0-0' @@ -8132,24 +7675,24 @@ packages: globrex: 0.1.2 recrawl-sync: 2.2.3 tsconfig-paths: 3.15.0 - vite: 6.2.0(@types/node@22.13.5)(sass@1.85.0) + vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3) transitivePeerDependencies: - supports-color dev: true - /vite-node@0.34.6(@types/node@22.13.4)(sass@1.85.0): - resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} - engines: {node: '>=v14.18.0'} + /vite-node@3.1.1(@types/node@22.14.0)(sass@1.86.3): + resolution: {integrity: sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true dependencies: cac: 6.7.14 debug: 4.4.0(supports-color@8.1.1) - mlly: 1.7.4 - pathe: 1.1.2 - picocolors: 1.1.1 - vite: 5.4.14(@types/node@22.13.4)(sass@1.85.0) + es-module-lexer: 1.6.0 + pathe: 2.0.3 + vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3) transitivePeerDependencies: - '@types/node' + - jiti - less - lightningcss - sass @@ -8158,9 +7701,11 @@ packages: - sugarss - supports-color - terser + - tsx + - yaml dev: true - /vite-tsconfig-paths@4.3.2(typescript@5.7.3)(vite@6.2.0): + /vite-tsconfig-paths@4.3.2(typescript@5.8.3)(vite@6.2.5): resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==} peerDependencies: vite: '*' @@ -8170,95 +7715,15 @@ packages: dependencies: debug: 4.4.0(supports-color@8.1.1) globrex: 0.1.2 - tsconfck: 3.1.5(typescript@5.7.3) - vite: 6.2.0(@types/node@22.13.5)(sass@1.85.0) + tsconfck: 3.1.5(typescript@5.8.3) + vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3) transitivePeerDependencies: - supports-color - typescript dev: true - /vite@5.4.14(@types/node@22.13.4)(sass@1.85.0): - resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 22.13.4 - esbuild: 0.21.5 - postcss: 8.5.3 - rollup: 4.34.8 - sass: 1.85.0 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /vite@5.4.14(@types/node@22.13.5)(sass@1.85.0): - resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 22.13.5 - esbuild: 0.21.5 - postcss: 8.5.3 - rollup: 4.34.8 - sass: 1.85.0 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /vite@6.1.1(@types/node@22.13.5)(sass-embedded@1.85.0)(sass@1.85.0): - resolution: {integrity: sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==} + /vite@6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3): + resolution: {integrity: sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -8297,140 +7762,35 @@ packages: yaml: optional: true dependencies: - '@types/node': 22.13.5 - esbuild: 0.24.2 + '@types/node': 22.14.0 + esbuild: 0.25.2 postcss: 8.5.3 - rollup: 4.34.8 - sass: 1.85.0 - sass-embedded: 1.85.0 + rollup: 4.39.0 + sass: 1.86.3 + sass-embedded: 1.86.3 optionalDependencies: fsevents: 2.3.3 dev: true - /vite@6.2.0(@types/node@22.13.5)(sass@1.85.0): - resolution: {integrity: sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==} + /vitest@3.1.1(@types/node@22.14.0)(sass@1.86.3): + resolution: {integrity: sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - dependencies: - '@types/node': 22.13.5 - esbuild: 0.25.0 - postcss: 8.5.3 - rollup: 4.34.8 - sass: 1.85.0 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /vitepress@1.6.3(@algolia/client-search@5.20.3)(@types/node@22.13.5)(axios@1.7.9)(postcss@8.5.3)(react-dom@19.0.0)(react@19.0.0)(sass@1.85.0)(search-insights@2.17.3)(typescript@5.7.3): - resolution: {integrity: sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw==} - hasBin: true - peerDependencies: - markdown-it-mathjax3: ^4 - postcss: ^8 - peerDependenciesMeta: - markdown-it-mathjax3: - optional: true - postcss: - optional: true - dependencies: - '@docsearch/css': 3.8.2 - '@docsearch/js': 3.8.2(@algolia/client-search@5.20.3)(react-dom@19.0.0)(react@19.0.0)(search-insights@2.17.3) - '@iconify-json/simple-icons': 1.2.25 - '@shikijs/core': 2.5.0 - '@shikijs/transformers': 2.5.0 - '@shikijs/types': 2.5.0 - '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.2.1(vite@5.4.14)(vue@3.5.13) - '@vue/devtools-api': 7.7.2 - '@vue/shared': 3.5.13 - '@vueuse/core': 12.7.0(typescript@5.7.3) - '@vueuse/integrations': 12.7.0(axios@1.7.9)(focus-trap@7.6.4)(typescript@5.7.3) - focus-trap: 7.6.4 - mark.js: 8.11.1 - minisearch: 7.1.2 - postcss: 8.5.3 - shiki: 2.5.0 - vite: 5.4.14(@types/node@22.13.5)(sass@1.85.0) - vue: 3.5.13(typescript@5.7.3) - transitivePeerDependencies: - - '@algolia/client-search' - - '@types/node' - - '@types/react' - - async-validator - - axios - - change-case - - drauu - - fuse.js - - idb-keyval - - jwt-decode - - less - - lightningcss - - nprogress - - qrcode - - react - - react-dom - - sass - - sass-embedded - - search-insights - - sortablejs - - stylus - - sugarss - - terser - - typescript - - universal-cookie - dev: true - - /vitest@0.34.6(sass@1.85.0): - resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} - engines: {node: '>=v14.18.0'} - hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.1.1 + '@vitest/ui': 3.1.1 happy-dom: '*' jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@types/debug': + optional: true + '@types/node': + optional: true '@vitest/browser': optional: true '@vitest/ui': @@ -8439,50 +7799,45 @@ packages: optional: true jsdom: optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true dependencies: - '@types/chai': 4.3.20 - '@types/chai-subset': 1.3.5 - '@types/node': 22.13.4 - '@vitest/expect': 0.34.6 - '@vitest/runner': 0.34.6 - '@vitest/snapshot': 0.34.6 - '@vitest/spy': 0.34.6 - '@vitest/utils': 0.34.6 - acorn: 8.14.0 - acorn-walk: 8.3.4 - cac: 6.7.14 - chai: 4.5.0 + '@types/node': 22.14.0 + '@vitest/expect': 3.1.1 + '@vitest/mocker': 3.1.1(vite@6.2.5) + '@vitest/pretty-format': 3.1.1 + '@vitest/runner': 3.1.1 + '@vitest/snapshot': 3.1.1 + '@vitest/spy': 3.1.1 + '@vitest/utils': 3.1.1 + chai: 5.2.0 debug: 4.4.0(supports-color@8.1.1) - local-pkg: 0.4.3 + expect-type: 1.2.1 magic-string: 0.30.17 - pathe: 1.1.2 - picocolors: 1.1.1 - std-env: 3.8.0 - strip-literal: 1.3.0 + pathe: 2.0.3 + std-env: 3.9.0 tinybench: 2.9.0 - tinypool: 0.7.0 - vite: 5.4.14(@types/node@22.13.4)(sass@1.85.0) - vite-node: 0.34.6(@types/node@22.13.4)(sass@1.85.0) + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 2.0.0 + vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3) + vite-node: 3.1.1(@types/node@22.14.0)(sass@1.86.3) why-is-node-running: 2.3.0 transitivePeerDependencies: + - jiti - less - lightningcss + - msw - sass - sass-embedded - stylus - sugarss - supports-color - terser + - tsx + - yaml dev: true - /vue-component-type-helpers@2.2.2: - resolution: {integrity: sha512-6lLY+n2xz2kCYshl59mL6gy8OUUTmkscmDFMO8i7Lj+QKwgnIFUZmM1i/iTYObtrczZVdw7UakPqDTGwVSGaRg==} + /vue-component-type-helpers@2.2.8: + resolution: {integrity: sha512-4bjIsC284coDO9om4HPA62M7wfsTvcmZyzdfR0aUlFXqq4tXxM1APyXpNVxPC8QazKw9OhmZNHBVDA6ODaZsrA==} dev: true /vue-demi@0.14.10(vue@3.5.13): @@ -8497,16 +7852,16 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.5.13(typescript@5.7.3) + vue: 3.5.13(typescript@5.8.3) - /vue-eslint-parser@9.4.3(eslint@9.20.1): + /vue-eslint-parser@9.4.3(eslint@9.24.0): resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' dependencies: debug: 4.4.0(supports-color@8.1.1) - eslint: 9.20.1 + eslint: 9.24.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 @@ -8517,16 +7872,16 @@ packages: - supports-color dev: true - /vue-i18n@9.14.2(vue@3.5.13): - resolution: {integrity: sha512-JK9Pm80OqssGJU2Y6F7DcM8RFHqVG4WkuCqOZTVsXkEzZME7ABejAUqUdA931zEBedc4thBgSUWxeQh4uocJAQ==} + /vue-i18n@9.14.4(vue@3.5.13): + resolution: {integrity: sha512-B934C8yUyWLT0EMud3DySrwSUJI7ZNiWYsEEz2gknTthqKiG4dzWE/WSa8AzCuSQzwBEv4HtG1jZDhgzPfWSKQ==} engines: {node: '>= 16'} peerDependencies: vue: ^3.0.0 dependencies: - '@intlify/core-base': 9.14.2 - '@intlify/shared': 9.14.2 + '@intlify/core-base': 9.14.4 + '@intlify/shared': 9.14.4 '@vue/devtools-api': 6.6.4 - vue: 3.5.13(typescript@5.7.3) + vue: 3.5.13(typescript@5.8.3) /vue-router@4.5.0(vue@3.5.13): resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==} @@ -8534,9 +7889,9 @@ packages: vue: ^3.2.0 dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.13(typescript@5.7.3) + vue: 3.5.13(typescript@5.8.3) - /vue@3.5.13(typescript@5.7.3): + /vue@3.5.13(typescript@5.8.3): resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} peerDependencies: typescript: '*' @@ -8549,7 +7904,7 @@ packages: '@vue/runtime-dom': 3.5.13 '@vue/server-renderer': 3.5.13(vue@3.5.13) '@vue/shared': 3.5.13 - typescript: 5.7.3 + typescript: 5.8.3 /w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -8591,10 +7946,63 @@ packages: engines: {node: '>=12'} dev: true + /which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + dev: true + + /which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + dev: true + + /which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + dev: true + /which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} dev: true + /which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + 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 + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -8700,7 +8108,7 @@ packages: resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} engines: {node: '>=4.0.0'} dependencies: - sax: 1.1.4 + sax: 1.4.1 xmlbuilder: 11.0.1 dev: true @@ -8715,11 +8123,11 @@ packages: sax: 1.4.1 dev: true - /xunit-viewer@10.6.1(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0): + /xunit-viewer@10.6.1(@babel/runtime@7.27.0)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.5)(codemirror@6.0.1)(react-dom@19.1.0)(react@19.1.0): resolution: {integrity: sha512-ZMprLPVhCQJf2KD56tv2hlOjc4T+KnUe1E9DkEBHnuliOq7IOXWJf61pxyBMo/7H83B7Ln0DIeWNMMbx/3I7Jg==} hasBin: true dependencies: - '@uiw/react-codemirror': 4.23.8(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0) + '@uiw/react-codemirror': 4.23.10(@babel/runtime@7.27.0)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.5)(codemirror@6.0.1)(react-dom@19.1.0)(react@19.1.0) chalk: 5.4.1 chokidar: 3.6.0 console-clear: 1.1.1 @@ -8764,17 +8172,18 @@ packages: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} dev: false - /yaml-eslint-parser@0.3.2: - resolution: {integrity: sha512-32kYO6kJUuZzqte82t4M/gB6/+11WAuHiEnK7FreMo20xsCKPeFH5tDBU7iWxR7zeJpNnMXfJyXwne48D0hGrg==} + /yaml-eslint-parser@1.3.0: + resolution: {integrity: sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==} + engines: {node: ^14.17.0 || >=16.0.0} dependencies: - eslint-visitor-keys: 1.3.0 - lodash: 4.17.21 - yaml: 1.10.2 + eslint-visitor-keys: 3.4.3 + yaml: 2.7.1 dev: true - /yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} + /yaml@2.7.1: + resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} + engines: {node: '>= 14'} + hasBin: true dev: true /yargs-parser@18.1.3: @@ -8841,8 +8250,8 @@ packages: engines: {node: '>=10'} dev: true - /yocto-queue@1.1.1: - resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} + /yocto-queue@1.2.1: + resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} engines: {node: '>=12.20'} dev: true @@ -8859,7 +8268,3 @@ packages: compress-commons: 6.0.2 readable-stream: 4.7.0 dev: true - - /zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - dev: true diff --git a/quasar.config.js b/quasar.config.js index 8b6125a90..2bc0be37f 100644 --- a/quasar.config.js +++ b/quasar.config.js @@ -53,7 +53,7 @@ export default configure(function (/* ctx */) { build: { target: { browser: ['es2022', 'edge88', 'firefox78', 'chrome87', 'safari13.1'], - node: 'node18', + node: 'node20', }, vueRouterMode: 'hash', // available values: 'hash', 'history' @@ -92,6 +92,7 @@ export default configure(function (/* ctx */) { vitePlugins: [ [ VueI18nPlugin({ + strictMessage: false, runtimeOnly: false, include: [ path.resolve(__dirname, './src/i18n/locale/**'), diff --git a/quasar.config.js.temporary.compiled.1744020058024.mjs b/quasar.config.js.temporary.compiled.1744020058024.mjs new file mode 100644 index 000000000..54ecb84d9 --- /dev/null +++ b/quasar.config.js.temporary.compiled.1744020058024.mjs @@ -0,0 +1,227 @@ +/* eslint-disable */ +/** + * THIS FILE IS GENERATED AUTOMATICALLY. + * 1. DO NOT edit this file directly as it won't do anything. + * 2. EDIT the original quasar.config file INSTEAD. + * 3. DO NOT git commit this file. It should be ignored. + * + * This file is still here because there was an error in + * the original quasar.config file and this allows you to + * investigate the Node.js stack error. + * + * After you fix the original file, this file will be + * deleted automatically. + **/ + + +// quasar.config.js +import { configure } from "quasar/wrappers"; +import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite"; +import path from "path"; +var __quasar_inject_dirname__ = "/home/jsegarra/Projects/salix-front"; +var target = `http://${process.env.CI ? "back" : "localhost"}:3000`; +var quasar_config_default = configure(function() { + return { + eslint: { + // fix: true, + // include = [], + // exclude = [], + // rawOptions = {}, + warnings: true, + errors: true + }, + // https://v2.quasar.dev/quasar-cli/prefetch-feature + // preFetch: true, + // app boot file (/src/boot) + // --> boot files are part of "main.js" + // https://v2.quasar.dev/quasar-cli/boot-files + boot: ["i18n", "axios", "vnDate", "validations", "quasar", "quasar.defaults"], + // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css + css: ["app.scss"], + // https://github.com/quasarframework/quasar/tree/dev/extras + extras: [ + // 'ionicons-v4', + // 'mdi-v5', + // 'fontawesome-v6', + // 'eva-icons', + // 'themify', + // 'line-awesome', + // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! + "roboto-font", + "material-icons-outlined", + "material-symbols-outlined" + ], + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build + build: { + target: { + browser: ["es2022", "edge88", "firefox78", "chrome87", "safari13.1"], + node: "node20" + }, + vueRouterMode: "hash", + // available values: 'hash', 'history' + // vueRouterBase, + // vueDevtools, + // vueOptionsAPI: false, + // rebuildCache: true, // rebuilds Vite/linter/etc cache on startup + // publicPath: '/', + // analyze: true, + // env: {}, + rawDefine: { + "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) + }, + // ignorePublicFolder: true, + // minify: false, + // polyfillModulePreload: true, + // distDir + extendViteConf(viteConf) { + delete viteConf.build.polyfillModulePreload; + viteConf.build.modulePreload = { + polyfill: false + }; + }, + // viteVuePluginOptions: {}, + alias: { + composables: path.join(__quasar_inject_dirname__, "./src/composables"), + filters: path.join(__quasar_inject_dirname__, "./src/filters") + }, + vitePlugins: [ + [ + VueI18nPlugin({ + strictMessage: false, + runtimeOnly: false, + include: [ + path.resolve(__quasar_inject_dirname__, "./src/i18n/locale/**"), + path.resolve(__quasar_inject_dirname__, "./src/pages/**/locale/**") + ] + }) + ] + ] + }, + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer + devServer: { + server: { + type: "http" + }, + proxy: { + "/api": { + target, + logLevel: "debug", + changeOrigin: true, + secure: false + } + }, + open: false, + allowedHosts: [ + "front", + // Agrega este nombre de host + "localhost" + // Opcional, para pruebas locales + ] + }, + // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework + framework: { + config: { + config: { + dark: "auto" + } + }, + lang: "en-GB", + // iconSet: 'material-icons', // Quasar icon set + // lang: 'en-US', // Quasar language pack + // For special cases outside of where the auto-import strategy can have an impact + // (like functional components as one of the examples), + // you can manually specify Quasar components/directives to be available everywhere: + // + // components: [], + // directives: [], + // Quasar plugins + plugins: ["Notify", "Dialog"], + all: "auto", + autoImportComponentCase: "pascal" + }, + // animations: 'all', // --- includes all animations + // https://v2.quasar.dev/options/animations + animations: [], + // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#property-sourcefiles + // sourceFiles: { + // rootComponent: 'src/App.vue', + // router: 'src/router/index', + // store: 'src/store/index', + // registerServiceWorker: 'src-pwa/register-service-worker', + // serviceWorker: 'src-pwa/custom-service-worker', + // pwaManifestFile: 'src-pwa/manifest.json', + // electronMain: 'src-electron/electron-main', + // electronPreload: 'src-electron/electron-preload' + // }, + // https://v2.quasar.dev/quasar-cli/developing-ssr/configuring-ssr + ssr: { + // ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name! + // will mess up SSR + // extendSSRWebserverConf (esbuildConf) {}, + // extendPackageJson (json) {}, + pwa: false, + // manualStoreHydration: true, + // manualPostHydrationTrigger: true, + prodPort: 3e3, + // The default port that the production server should use + // (gets superseded if process.env.PORT is specified at runtime) + middlewares: [ + "render" + // keep this as last one + ] + }, + // https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa + pwa: { + workboxMode: "generateSW", + // or 'injectManifest' + injectPwaMetaTags: true, + swFilename: "sw.js", + manifestFilename: "manifest.json", + useCredentialsForManifestTag: false + // useFilenameHashes: true, + // extendGenerateSWOptions (cfg) {} + // extendInjectManifestOptions (cfg) {}, + // extendManifestJson (json) {} + // extendPWACustomSWConf (esbuildConf) {} + }, + // Full list of options: https://v2.quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova + cordova: { + // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing + }, + // Full list of options: https://v2.quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor + capacitor: { + hideSplashscreen: true + }, + // Full list of options: https://v2.quasar.dev/quasar-cli/developing-electron-apps/configuring-electron + electron: { + // extendElectronMainConf (esbuildConf) + // extendElectronPreloadConf (esbuildConf) + inspectPort: 5858, + bundler: "packager", + // 'packager' or 'builder' + packager: { + // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options + // OS X / Mac App Store + // appBundleId: '', + // appCategoryType: '', + // osxSign: '', + // protocol: 'myapp://path', + // Windows only + // win32metadata: { ... } + }, + builder: { + // https://www.electron.build/configuration/configuration + appId: "salix-frontend" + } + }, + // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex + bex: { + contentScripts: ["my-content-script"] + // extendBexScriptsConf (esbuildConf) {} + // extendBexManifestJson (json) {} + } + }; +}); +export { + quasar_config_default as default +}; diff --git a/src/boot/__tests__/axios.spec.js b/src/boot/__tests__/axios.spec.js index 7dffaefc1..85d578517 100644 --- a/src/boot/__tests__/axios.spec.js +++ b/src/boot/__tests__/axios.spec.js @@ -9,6 +9,30 @@ vi.mock('src/composables/useSession', () => ({ }), })); +// Mock axios +vi.mock('axios', () => ({ + default: { + create: vi.fn(() => ({ + interceptors: { + request: { use: vi.fn() }, + response: { use: vi.fn() }, + }, + })), + interceptors: { + request: { use: vi.fn() }, + response: { use: vi.fn() }, + }, + defaults: { + baseURL: '', + }, + }, +})); + +vi.mock('src/router', () => ({ + Router: { + push: vi.fn(), + }, +})); vi.mock('src/stores/useStateQueryStore', () => ({ useStateQueryStore: () => ({ add: () => vi.fn(), @@ -29,7 +53,7 @@ describe('Axios boot', () => { 'Accept-Language': 'en-US', Authorization: 'DEFAULT_TOKEN', }, - }) + }), ); }); }); diff --git a/src/boot/quasar.defaults.js b/src/boot/quasar.defaults.js index 9638e2057..e2b195b16 100644 --- a/src/boot/quasar.defaults.js +++ b/src/boot/quasar.defaults.js @@ -1,3 +1,4 @@ +/* eslint-disable eslint/export */ export * from './defaults/qTable'; export * from './defaults/qInput'; export * from './defaults/qSelect'; diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue index c4d9a4149..1fec1e6c9 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -13,13 +13,12 @@ import VnConfirm from './ui/VnConfirm.vue'; import { tMobile } from 'src/composables/tMobile'; import { useArrayData } from 'src/composables/useArrayData'; import { getDifferences, getUpdatedValues } from 'src/filters'; - const { push } = useRouter(); const quasar = useQuasar(); const state = useState(); const stateStore = useStateStore(); const { t } = useI18n(); -const { validate } = useValidator(); +const { validate, validations } = useValidator(); const { notify } = useNotify(); const route = useRoute(); const myForm = ref(null); @@ -119,7 +118,7 @@ const defaultButtons = computed(() => ({ color: 'primary', icon: 'save', label: 'globals.save', - click: async () => await save(), + click: async (evt) => submitForm(evt), type: 'submit', }, reset: { @@ -132,6 +131,13 @@ const defaultButtons = computed(() => ({ ...$props.defaultButtons, })); +const submitForm = async (evt) => { + const isFormValid = await myForm.value.validate(); + if (isFormValid) { + await save(evt); + } +}; + onMounted(async () => { nextTick(() => (componentIsRendered.value = true)); @@ -227,10 +233,9 @@ async function save() { const method = $props.urlCreate ? 'post' : 'patch'; const url = $props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url; - let response; - - if ($props.saveFn) response = await $props.saveFn(body); - else response = await axios[method](url, body); + const response = await Promise.resolve( + $props.saveFn ? $props.saveFn(body) : axios[method](url, body), + ); if ($props.urlCreate) notify('globals.dataCreated', 'positive'); @@ -307,11 +312,13 @@ async function onKeyup(evt) { selectionStart = selectionEnd = selectionStart + 1; return; } - await save(); + await myForm.value.submit(evt); } } defineExpose({ + submitForm, + myForm, save, isLoading, hasChanges, @@ -325,7 +332,7 @@ defineExpose({ <QForm ref="myForm" v-if="formData" - @submit.prevent + @submit.prevent="save" @keyup.prevent="onKeyup" @reset="reset" class="q-pa-md" @@ -339,6 +346,7 @@ defineExpose({ name="form" :data="formData" :validate="validate" + :validations="validations()" :filter="filter" /> <SkeletonForm v-else /> diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue index 85943e91e..34aec96d8 100644 --- a/src/components/FormModelPopup.vue +++ b/src/components/FormModelPopup.vue @@ -41,9 +41,12 @@ const onDataSaved = async (formData, requestResponse) => { emit('onDataSaved', formData, requestResponse); }; -const onClick = async (saveAndContinue) => { +const onClick = async (saveAndContinue = showSaveAndContinueBtn) => { + await formModelRef.value.myForm.validate(true); isSaveAndContinue.value = saveAndContinue; - await formModelRef.value.save(); + if (formModelRef.value) { + await formModelRef.value.submitForm(); + } }; defineExpose({ @@ -59,16 +62,23 @@ defineExpose({ ref="formModelRef" :observe-form-changes="false" :default-actions="false" + @submit="onClick" v-bind="$attrs" @on-data-saved="onDataSaved" + :prevent-submit="false" > - <template #form="{ data, validate }"> + <template #form="{ data, validate, validations }"> <span ref="closeButton" class="close-icon" v-close-popup> <QIcon name="close" size="sm" /> </span> <h1 class="title">{{ title }}</h1> <p>{{ subtitle }}</p> - <slot name="form-inputs" :data="data" :validate="validate" /> + <slot + name="form-inputs" + :data="data" + :validate="validate" + :validations="validations" + /> <div class="q-mt-lg row justify-end"> <QBtn :label="t('globals.cancel')" @@ -87,12 +97,13 @@ defineExpose({ :flat="showSaveAndContinueBtn" :label="t('globals.save')" :title="t('globals.save')" - @click="onClick(false)" + :type="!showSaveAndContinueBtn ? 'submit' : 'button'" color="primary" class="q-ml-sm" :disabled="isLoading" :loading="isLoading" data-cy="FormModelPopup_save" + @click="showSaveAndContinueBtn ? onClick(false) : null" z-max /> <QBtn @@ -100,12 +111,13 @@ defineExpose({ :label="t('globals.isSaveAndContinue')" :title="t('globals.isSaveAndContinue')" color="primary" + :type="showSaveAndContinueBtn ? 'submit' : 'button'" class="q-ml-sm" :disabled="isLoading" :loading="isLoading" data-cy="FormModelPopup_isSaveAndContinue" + @click="showSaveAndContinueBtn ? onClick(true) : null" z-max - @click="onClick(true)" /> </div> </template> diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue index dbb6f1fe6..7329ddae2 100644 --- a/src/components/NavBar.vue +++ b/src/components/NavBar.vue @@ -1,5 +1,5 @@ <script setup> -import { onMounted, ref } from 'vue'; +import { onMounted, ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useState } from 'src/composables/useState'; import { useStateStore } from 'stores/useStateStore'; @@ -18,6 +18,14 @@ const state = useState(); const user = state.getUser(); const appName = 'Lilium'; const pinnedModulesRef = ref(); +const hostname = window.location.hostname; +const env = ref(); + +const getEnvironment = computed(() => { + env.value = hostname.split('-'); + if (env.value.length <= 1) return; + return env.value[0]; +}); onMounted(() => stateStore.setMounted()); const refresh = () => window.location.reload(); @@ -49,6 +57,9 @@ const refresh = () => window.location.reload(); {{ t('globals.backToDashboard') }} </QTooltip> </QBtn> + <QBadge v-if="getEnvironment" color="primary" align="top"> + {{ getEnvironment }} + </QBadge> </RouterLink> <VnBreadcrumbs v-if="$q.screen.gt.sm" /> <QSpinner diff --git a/src/components/TicketProblems.vue b/src/components/TicketProblems.vue index 59be95035..c15e31d80 100644 --- a/src/components/TicketProblems.vue +++ b/src/components/TicketProblems.vue @@ -17,17 +17,6 @@ defineProps({ row: { type: Object, required: true } }); </QTooltip> </QIcon> </router-link> - <QIcon - v-if="row?.reserved" - color="primary" - name="vn:reserva" - size="xs" - data-cy="ticketSaleReservedIcon" - > - <QTooltip> - {{ t('ticketSale.reserved') }} - </QTooltip> - </QIcon> <QIcon v-if="row?.isDeleted" color="primary" diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue index d0e245388..3ce62c5de 100644 --- a/src/components/VnTable/VnColumn.vue +++ b/src/components/VnTable/VnColumn.vue @@ -55,6 +55,8 @@ const $props = defineProps({ }, }); +const label = $props.showLabel && $props.column.label ? $props.column.label : ''; + const defaultSelect = { attrs: { row: $props.row, @@ -62,7 +64,7 @@ const defaultSelect = { class: 'fit', }, forceAttrs: { - label: $props.showLabel && $props.column.label, + label, }, }; @@ -74,7 +76,7 @@ const defaultComponents = { class: 'fit', }, forceAttrs: { - label: $props.showLabel && $props.column.label, + label, }, }, number: { @@ -84,7 +86,7 @@ const defaultComponents = { class: 'fit', }, forceAttrs: { - label: $props.showLabel && $props.column.label, + label, }, }, date: { @@ -96,7 +98,7 @@ const defaultComponents = { class: 'fit', }, forceAttrs: { - label: $props.showLabel && $props.column.label, + label, }, }, time: { @@ -105,7 +107,7 @@ const defaultComponents = { disable: !$props.isEditable, }, forceAttrs: { - label: $props.showLabel && $props.column.label, + label, }, }, checkbox: { @@ -125,7 +127,7 @@ const defaultComponents = { return defaultAttrs; }, forceAttrs: { - label: $props.showLabel && $props.column.label, + label, autofocus: true, }, events: { diff --git a/src/components/VnTable/VnOrder.vue b/src/components/VnTable/VnOrder.vue index 47ed9acf4..fe071a57f 100644 --- a/src/components/VnTable/VnOrder.vue +++ b/src/components/VnTable/VnOrder.vue @@ -70,7 +70,7 @@ function textAlignToFlex(textAlign) { :style="textAlignToFlex(align)" > <span :title="label">{{ label }}</span> - <div v-if="name && model?.index"> + <div v-if="name && (model?.index || vertical)"> <QChip :label="!vertical ? model?.index : ''" :icon=" @@ -83,14 +83,14 @@ function textAlignToFlex(textAlign) { :size="vertical ? '' : 'sm'" :class="[ model?.index ? 'color-vn-text' : 'bg-transparent', - vertical ? 'q-px-none' : '', + vertical ? 'q-mx-none q-py-lg' : '', ]" class="no-box-shadow" :clickable="true" style="min-width: 40px; max-height: 30px" > <div - class="column flex-center" + class="column justify-center text-center" v-if="vertical" :style="!model?.index && 'color: #5d5d5d'" > diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index e214770d2..b8494a875 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -19,6 +19,7 @@ import { useQuasar, date } from 'quasar'; import { useStateStore } from 'stores/useStateStore'; import { useFilterParams } from 'src/composables/useFilterParams'; import { dashIfEmpty, toDate } from 'src/filters'; +import { useTableHeight } from './filters/useTableHeight'; import CrudModel from 'src/components/CrudModel.vue'; import FormModelPopup from 'components/FormModelPopup.vue'; @@ -117,7 +118,7 @@ const $props = defineProps({ }, tableHeight: { type: String, - default: '90vh', + default: undefined, }, footer: { type: Boolean, @@ -166,6 +167,7 @@ const tableRef = ref(); const params = ref(useFilterParams($attrs['data-key']).params); const orders = ref(useFilterParams($attrs['data-key']).orders); const app = inject('app'); +const tableHeight = useTableHeight(); const editingRow = ref(null); const editingField = ref(null); @@ -678,7 +680,7 @@ const rowCtrlClickFunction = computed(() => { table-header-class="bg-header" card-container-class="grid-three" flat - :style="isTableMode && `max-height: ${tableHeight}`" + :style="isTableMode && `max-height: ${$props.tableHeight || tableHeight}`" :virtual-scroll="isTableMode" @virtual-scroll="handleScroll" @row-click="(event, row) => handleRowClick(event, row)" @@ -1042,7 +1044,7 @@ const rowCtrlClickFunction = computed(() => { :model="$attrs['data-key'] + 'Create'" @on-data-saved="(_, res) => createForm.onDataSaved(res)" > - <template #form-inputs="{ data }"> + <template #form-inputs="{ data, validations }"> <slot name="alter-create" :data="data"> <div :style="createComplement?.containerStyle"> <div @@ -1060,6 +1062,7 @@ const rowCtrlClickFunction = computed(() => { :key="column.name" :name="`column-create-${column.name}`" :data="data" + :validations="validations" :column-name="column.name" :label="column.label" > diff --git a/src/components/VnTable/VnTableFilter.vue b/src/components/VnTable/VnTableFilter.vue index 79b903e54..109e2b77e 100644 --- a/src/components/VnTable/VnTableFilter.vue +++ b/src/components/VnTable/VnTableFilter.vue @@ -26,7 +26,12 @@ function columnName(col) { } </script> <template> - <VnFilterPanel v-bind="$attrs" :search-button="true" :disable-submit-event="true"> + <VnFilterPanel + v-bind="$attrs" + :search-button="true" + :disable-submit-event="true" + :search-url + > <template #body="{ params, orders, searchFn }"> <div class="container" @@ -34,13 +39,20 @@ function columnName(col) { :key="col.id" > <div class="filter"> - <VnFilter - ref="tableFilterRef" - :column="col" - :data-key="$attrs['data-key']" - v-model="params[columnName(col)]" - :search-url="searchUrl" - /> + <slot + :name="`filter-${col.name}`" + :params="params" + :column-name="columnName(col)" + :search-fn + > + <VnFilter + ref="tableFilterRef" + :column="col" + :data-key="$attrs['data-key']" + v-model="params[columnName(col)]" + :search-url="searchUrl" + /> + </slot> </div> <div class="order"> <VnTableOrder @@ -77,13 +89,13 @@ function columnName(col) { display: flex; justify-content: center; align-items: center; - height: 45px; + min-height: 45px; gap: 10px; } .filter { width: 70%; - height: 40px; + min-height: 40px; text-align: center; } .order { diff --git a/src/components/VnTable/__tests__/VnVisibleColumns.spec.js b/src/components/VnTable/__tests__/VnVisibleColumns.spec.js index bf767688b..3e4e9ecc8 100644 --- a/src/components/VnTable/__tests__/VnVisibleColumns.spec.js +++ b/src/components/VnTable/__tests__/VnVisibleColumns.spec.js @@ -1,8 +1,7 @@ import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'; import { createWrapper } from 'app/test/vitest/helper'; import VnVisibleColumn from '../VnVisibleColumn.vue'; -import { axios } from 'app/test/vitest/helper'; - +import { default as axios } from 'axios'; describe('VnVisibleColumns', () => { let wrapper; let vm; diff --git a/src/components/VnTable/filters/useTableHeight.js b/src/components/VnTable/filters/useTableHeight.js new file mode 100644 index 000000000..2397ce16f --- /dev/null +++ b/src/components/VnTable/filters/useTableHeight.js @@ -0,0 +1,18 @@ +import { onMounted, nextTick, ref } from 'vue'; + +export function useTableHeight() { + const tableHeight = ref('90vh'); + + onMounted(async () => { + await nextTick(); + let height = 100; + Array.from(document.querySelectorAll('[role="toolbar"]')) + .filter((element) => window.getComputedStyle(element).display !== 'none') + .forEach(() => { + height -= 10; + }); + tableHeight.value = `${height}vh`; + }); + + return tableHeight; +} diff --git a/src/components/__tests__/CrudModel.spec.js b/src/components/__tests__/CrudModel.spec.js index f6c93e0d5..c620d29ad 100644 --- a/src/components/__tests__/CrudModel.spec.js +++ b/src/components/__tests__/CrudModel.spec.js @@ -1,4 +1,6 @@ -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { createWrapper } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; + import CrudModel from 'components/CrudModel.vue'; import { vi, afterEach, beforeEach, beforeAll, describe, expect, it } from 'vitest'; diff --git a/src/components/__tests__/EditTableCellValueForm.spec.js b/src/components/__tests__/EditTableCellValueForm.spec.js index fa47d8f73..acba27519 100644 --- a/src/components/__tests__/EditTableCellValueForm.spec.js +++ b/src/components/__tests__/EditTableCellValueForm.spec.js @@ -1,4 +1,5 @@ -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { createWrapper } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; import EditForm from 'components/EditTableCellValueForm.vue'; import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest'; diff --git a/src/components/__tests__/FilterItemForm.spec.js b/src/components/__tests__/FilterItemForm.spec.js index 210d6bf02..fb8332c31 100644 --- a/src/components/__tests__/FilterItemForm.spec.js +++ b/src/components/__tests__/FilterItemForm.spec.js @@ -1,4 +1,6 @@ -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { createWrapper } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; + import FilterItemForm from 'src/components/FilterItemForm.vue'; import { vi, beforeAll, describe, expect, it } from 'vitest'; @@ -38,9 +40,9 @@ describe('FilterItemForm', () => { { relation: 'producer', scope: { fields: ['name'] } }, { relation: 'ink', scope: { fields: ['name'] } }, ], - where: {"name":{"like":"%bolas de madera%"}}, + where: { name: { like: '%bolas de madera%' } }, }; - + expect(axios.get).toHaveBeenCalledWith('Items/withName', { params: { filter: JSON.stringify(expectedFilter) }, }); @@ -79,4 +81,4 @@ describe('FilterItemForm', () => { vm.selectItem({ id: 12345 }); expect(wrapper.emitted('itemSelected')[0]).toEqual([12345]); }); -}); \ No newline at end of file +}); diff --git a/src/components/__tests__/FormModel.spec.js b/src/components/__tests__/FormModel.spec.js index 3dce04374..20e99b55b 100644 --- a/src/components/__tests__/FormModel.spec.js +++ b/src/components/__tests__/FormModel.spec.js @@ -1,5 +1,7 @@ import { describe, expect, it, beforeAll, vi, afterAll } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { createWrapper } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; + import FormModel from 'src/components/FormModel.vue'; describe('FormModel', () => { diff --git a/src/components/__tests__/Leftmenu.spec.js b/src/components/__tests__/Leftmenu.spec.js index 0bcc587ac..22b2b5fb7 100644 --- a/src/components/__tests__/Leftmenu.spec.js +++ b/src/components/__tests__/Leftmenu.spec.js @@ -1,6 +1,7 @@ -import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; -import Leftmenu from 'components/LeftMenu.vue'; +import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; +import { default as axios } from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; +import LeftMenu from 'components/LeftMenu.vue'; import * as vueRouter from 'vue-router'; import { useNavigationStore } from 'src/stores/useNavigationStore'; @@ -101,7 +102,7 @@ function mount(source = 'main') { vi.spyOn(axios, 'get').mockResolvedValue({ data: [], }); - const wrapper = createWrapper(Leftmenu, { + const wrapper = createWrapper(LeftMenu, { propsData: { source, }, @@ -164,7 +165,7 @@ describe('getRoutes', () => { }); }); -describe('Leftmenu as card', () => { +describe('LeftMenu as card', () => { beforeAll(() => { vm = mount('card').vm; }); @@ -173,7 +174,7 @@ describe('Leftmenu as card', () => { vm.getRoutes(); }); }); -describe('Leftmenu as main', () => { +describe('LeftMenu as main', () => { beforeEach(() => { vm = mount().vm; }); diff --git a/src/components/common/SendEmailDialog.vue b/src/components/common/SendEmailDialog.vue index 254eb9cf9..a8209bdf7 100644 --- a/src/components/common/SendEmailDialog.vue +++ b/src/components/common/SendEmailDialog.vue @@ -60,7 +60,7 @@ async function confirm() { v-model="address" is-outlined autofocus - data-cy="SendEmailNotifiactionDialogInput" + data-cy="SendEmailNotificationDialogInput" /> </QCardSection> <QCardActions align="right"> diff --git a/src/components/common/SendSmsDialog.vue b/src/components/common/SendSmsDialog.vue index 269a4ec9a..a953abd75 100644 --- a/src/components/common/SendSmsDialog.vue +++ b/src/components/common/SendSmsDialog.vue @@ -1,15 +1,15 @@ <script setup> -import {useDialogPluginComponent} from 'quasar'; -import {useI18n} from 'vue-i18n'; -import {computed, ref} from 'vue'; +import { useDialogPluginComponent } from 'quasar'; +import { useI18n } from 'vue-i18n'; +import { computed, ref } from 'vue'; import VnInput from 'components/common/VnInput.vue'; import axios from 'axios'; -import useNotify from "composables/useNotify"; +import useNotify from 'composables/useNotify'; const MESSAGE_MAX_LENGTH = 160; -const {t} = useI18n(); -const {notify} = useNotify(); +const { t } = useI18n(); +const { notify } = useNotify(); const props = defineProps({ title: { type: String, @@ -34,7 +34,7 @@ const props = defineProps({ }); const emit = defineEmits([...useDialogPluginComponent.emits, 'sent']); -const {dialogRef, onDialogHide} = useDialogPluginComponent(); +const { dialogRef, onDialogHide } = useDialogPluginComponent(); const smsRules = [ (val) => (val && val.length > 0) || t("The message can't be empty"), @@ -43,10 +43,10 @@ const smsRules = [ t("The message it's too long"), ]; -const message = ref(''); +const message = ref(t('routeDelay')); const charactersRemaining = computed( - () => MESSAGE_MAX_LENGTH - new Blob([message.value]).size + () => MESSAGE_MAX_LENGTH - new Blob([message.value]).size, ); const charactersChipColor = computed(() => { @@ -114,7 +114,7 @@ const onSubmit = async () => { <QTooltip> {{ t( - 'Special characters like accents counts as a multiple' + 'Special characters like accents counts as a multiple', ) }} </QTooltip> @@ -144,7 +144,10 @@ const onSubmit = async () => { max-width: 450px; } </style> + <i18n> +en: + routeDelay: "Your order has been delayed in transit.\nDelivery will take place throughout the day.\nWe apologize for the inconvenience and appreciate your patience." es: Message: Mensaje Send: Enviar @@ -153,4 +156,5 @@ es: The destination can't be empty: El destinatario no puede estar vacio The message can't be empty: El mensaje no puede estar vacio The message it's too long: El mensaje es demasiado largo -</i18n> + routeDelay: "Retraso en ruta.\nInformamos que la ruta que lleva su pedido ha sufrido un retraso y la entrega se hará a lo largo del dĂa.\nDisculpe las molestias." + </i18n> diff --git a/src/components/common/VnAccountNumber.vue b/src/components/common/VnAccountNumber.vue index 56add7329..8bff3e261 100644 --- a/src/components/common/VnAccountNumber.vue +++ b/src/components/common/VnAccountNumber.vue @@ -1,35 +1,14 @@ <script setup> -import { nextTick, ref } from 'vue'; import VnInput from './VnInput.vue'; import { useAccountShortToStandard } from 'src/composables/useAccountShortToStandard'; -const $props = defineProps({ - insertable: { - type: Boolean, - default: false, - }, -}); - -const emit = defineEmits(['update:modelValue', 'accountShortToStandard']); const model = defineModel({ prop: 'modelValue' }); -const inputRef = ref(false); - -function setCursorPosition(pos) { - const input = inputRef.value.vnInputRef.$el.querySelector('input'); - input.focus(); - input.setSelectionRange(pos, pos); -} - -async function handleUpdateModel(val) { - model.value = val?.at(-1) === '.' ? useAccountShortToStandard(val) : val; - await nextTick(() => setCursorPosition(0)); -} </script> <template> <VnInput v-model="model" ref="inputRef" - :insertable - @update:model-value="handleUpdateModel" + @keydown.tab="model = useAccountShortToStandard($event.target.value) ?? model" + @input="model = $event.target.value.replace(/[^\d.]/g, '')" /> </template> diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue index 21cdc9df5..0b9cc2cce 100644 --- a/src/components/common/VnCard.vue +++ b/src/components/common/VnCard.vue @@ -1,5 +1,5 @@ <script setup> -import { onBeforeMount, computed } from 'vue'; +import { onBeforeMount, computed, markRaw } from 'vue'; import { useRoute, useRouter, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router'; import { useArrayData } from 'src/composables/useArrayData'; import { useStateStore } from 'stores/useStateStore'; @@ -26,18 +26,14 @@ const route = useRoute(); const stateStore = useStateStore(); const router = useRouter(); const entityId = computed(() => props.id || route?.params?.id); -const arrayData = useArrayData(props.dataKey, { - url: props.url, - userFilter: props.filter, - oneRecord: true, -}); +let arrayData = getArrayData(entityId.value, props.url); onBeforeRouteLeave(() => { stateStore.cardDescriptorChangeValue(null); }); onBeforeMount(async () => { - stateStore.cardDescriptorChangeValue(props.descriptor); + stateStore.cardDescriptorChangeValue(markRaw(props.descriptor)); const route = router.currentRoute.value; try { @@ -61,16 +57,31 @@ onBeforeRouteUpdate(async (to, from) => { }); async function fetch(id, append = false) { - const regex = /\/(\d+)/; if (props.idInWhere) arrayData.store.filter.where = { id }; - else if (!regex.test(props.url)) arrayData.store.url = `${props.url}/${id}`; - else arrayData.store.url = props.url.replace(regex, `/${id}`); + else { + arrayData = getArrayData(id); + } await arrayData.fetch({ append, updateRouter: false }); emit('onFetch', arrayData.store.data); } function hasRouteParam(params, valueToCheck = ':addressId') { return Object.values(params).includes(valueToCheck); } + +function formatUrl(id) { + const newId = id || entityId.value; + const regex = /\/(\d+)/; + if (!regex.test(props.url)) return `${props.url}/${newId}`; + return props.url.replace(regex, `/${newId}`); +} + +function getArrayData(id, url) { + return useArrayData(props.dataKey, { + url: url ?? formatUrl(id), + userFilter: props.filter, + oneRecord: true, + }); +} </script> <template> <template v-if="visual"> diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index bee300f4e..de22e4857 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -35,6 +35,10 @@ const $props = defineProps({ type: String, default: null, }, + hasFile: { + type: Boolean, + default: false, + }, }); const warehouses = ref(); @@ -90,6 +94,7 @@ function defaultData() { if ($props.formInitialData) return (dms.value = $props.formInitialData); return addDefaultData({ reference: route.params.id, + hasFile: $props.hasFile, }); } diff --git a/src/components/common/VnDmsInput.vue b/src/components/common/VnDmsInput.vue index 25d625d5d..5a3ef351b 100644 --- a/src/components/common/VnDmsInput.vue +++ b/src/components/common/VnDmsInput.vue @@ -15,7 +15,7 @@ const editDownloadDisabled = ref(false); const $props = defineProps({ defaultDmsCode: { type: String, - default: 'InvoiceIn', + default: 'invoiceIn', }, disable: { type: Boolean, diff --git a/src/components/common/VnDropdown.vue b/src/components/common/VnDropdown.vue new file mode 100644 index 000000000..1b3f2237b --- /dev/null +++ b/src/components/common/VnDropdown.vue @@ -0,0 +1,53 @@ +<script setup> +import { ref } from 'vue'; +import VnSelect from './VnSelect.vue'; + +const stateBtnDropdownRef = ref(); + +const emit = defineEmits(['changeState']); + +const $props = defineProps({ + disable: { + type: Boolean, + default: null, + }, + options: { + type: Array, + default: null, + }, + optionLabel: { + type: String, + default: 'name', + }, + optionValue: { + type: String, + default: 'id', + }, +}); + +async function changeState(value) { + stateBtnDropdownRef.value?.hide(); + emit('changeState', value); +} +</script> + +<template> + <QBtnDropdown + ref="stateBtnDropdownRef" + color="black" + text-color="white" + :label="$t('globals.changeState')" + :disable="$props.disable" + > + <VnSelect + :options="$props.options" + :option-label="$props.optionLabel" + :option-value="$props.optionValue" + hide-selected + hide-dropdown-icon + focus-on-mount + @update:model-value="changeState" + > + </VnSelect> + </QBtnDropdown> +</template> diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue index 804147539..e2f18866a 100644 --- a/src/components/common/VnLog.vue +++ b/src/components/common/VnLog.vue @@ -1,5 +1,5 @@ <script setup> -import { ref, onUnmounted, watch } from 'vue'; +import { ref, onMounted, onUnmounted, watch, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute, useRouter } from 'vue-router'; import axios from 'axios'; @@ -11,11 +11,11 @@ import { useCapitalize } from 'src/composables/useCapitalize'; import { useValidator } from 'src/composables/useValidator'; import VnAvatar from '../ui/VnAvatar.vue'; import VnLogValue from './VnLogValue.vue'; -import FetchData from '../FetchData.vue'; -import VnSelect from './VnSelect.vue'; import VnUserLink from '../ui/VnUserLink.vue'; import VnPaginate from '../ui/VnPaginate.vue'; +import VnLogFilter from 'src/components/common/VnLogFilter.vue'; import RightMenu from './RightMenu.vue'; +import { useFilterParams } from 'src/composables/useFilterParams'; const stateStore = useStateStore(); const validationsStore = useValidator(); @@ -72,39 +72,8 @@ const filter = { }; const paginate = ref(); -const actions = ref(); -const changeInput = ref(); -const searchInput = ref(); -const userRadio = ref(); -const userSelect = ref(); -const dateFrom = ref(); -const dateFromDialog = ref(false); -const dateTo = ref(); -const dateToDialog = ref(false); -const selectedFilters = ref({}); -const userTypes = [ - { label: 'All', value: undefined }, - { label: 'User', value: { neq: null } }, - { label: 'System', value: null }, -]; -const checkboxOptions = ref({ - insert: { - label: 'Creates', - selected: false, - }, - update: { - label: 'Edits', - selected: false, - }, - delete: { - label: 'Deletes', - selected: false, - }, - select: { - label: 'Accesses', - selected: false, - }, -}); +const dataKey = computed(() => `${props.model}Log`); +const userParams = ref(useFilterParams(dataKey.value).params); let validations = models; let pointRecord = ref(null); @@ -246,131 +215,55 @@ async function setLogTree(data) { function filterByRecord(modelLog) { byRecord.value = true; const { id, model } = modelLog; - - searchInput.value = id; - selectedFilters.value.changedModelId = id; - selectedFilters.value.changedModel = model; - applyFilter(); + applyFilter({ changedModelId: id, changedModel: model }); } -async function applyFilter() { - filter.where = { and: [] }; - if ( - !selectedFilters.value.changedModel || - (!selectedFilters.value.changedModelValue && - !selectedFilters.value.changedModelId) - ) - byRecord.value = false; - - if (!byRecord.value) filter.where.and.push({ originFk: route.params.id }); - - if (Object.keys(selectedFilters.value).length) { - filter.where.and.push(selectedFilters.value); - } - - paginate.value.fetch({ filter }); +async function applyFilter(params = {}) { + paginate.value.arrayData.resetPagination(); + paginate.value.arrayData.applyFilter({ + filter: {}, + params: { originFk: route.params.id, ...params }, + }); } -function setDate(type) { - let from = dateFrom.value - ? date.formatDate(dateFrom.value.split('-').reverse().join('-'), 'YYYY-MM-DD') - : undefined; - from = date.adjustDate(from, { hour: 0, minute: 0, second: 0, millisecond: 0 }, true); - - let to = dateTo.value - ? date.formatDate(dateTo.value.split('-').reverse().join('-'), 'YYYY-MM-DD') - : date.formatDate(dateFrom.value.split('-').reverse().join('-'), 'YYYY-MM-DD'); - to = date.adjustDate( - to, - { hour: 21, minute: 59, second: 59, millisecond: 999 }, - true, - ); - - switch (type) { - case 'from': - return { between: [from, to] }; - case 'to': { - if (dateFrom.value) { +function exprBuilder(param, value) { + switch (param) { + case 'changedModelValue': + return { [param]: { like: `%${value}%` } }; + case 'change': + if (value) return { - between: [from, to], + or: [ + { oldJson: { like: `%${value}%` } }, + { newJson: { like: `%${value}%` } }, + { description: { like: `%${value}%` } }, + ], }; - } - return { lte: to }; - } + break; + case 'action': + if (value?.length) return { [param]: { inq: value } }; + break; + case 'from': + return { creationDate: { gte: value } }; + case 'to': + return { creationDate: { lte: value } }; + case 'userType': + if (value === 'User') return { userFk: { neq: null } }; + if (value === 'System') return { userFk: null }; + break; + default: + return { [param]: value }; } } -function selectFilter(type, dateType) { - const filter = {}; - const actions = { inq: [] }; - let reload = true; - - if (type === 'search') { - if (/^\s*[0-9]+\s*$/.test(searchInput.value) || props.byRecord) { - selectedFilters.value.changedModelId = searchInput.value.trim(); - } else if (!searchInput.value) { - selectedFilters.value.changedModelId = undefined; - selectedFilters.value.changedModelValue = undefined; - } else { - selectedFilters.value.changedModelValue = { like: `%${searchInput.value}%` }; - } - } - if (type === 'action' && selectedFilters.value.changedModel === null) { - selectedFilters.value.changedModel = undefined; - } - if (type === 'userRadio') { - selectedFilters.value.userFk = userRadio.value; - } - if (type === 'change') { - if (changeInput.value) - selectedFilters.value.or = [ - { oldJson: { like: `%${changeInput.value}%` } }, - { newJson: { like: `%${changeInput.value}%` } }, - { description: { like: `%${changeInput.value}%` } }, - ]; - else selectedFilters.value.or = undefined; - } - if (type === 'userSelect') { - selectedFilters.value.userFk = - userSelect.value !== null ? userSelect.value : undefined; - } - if (type === 'date') { - if (!dateFrom.value && !dateTo.value) { - selectedFilters.value.creationDate = undefined; - } else if (dateType === 'to') { - selectedFilters.value.creationDate = setDate('to'); - } else if (dateType === 'from') { - selectedFilters.value.creationDate = setDate('from'); - } - } - - Object.keys(checkboxOptions.value).forEach((key) => { - if (checkboxOptions.value[key].selected) actions.inq.push(key); - }); - selectedFilters.value.action = actions.inq.length ? actions : undefined; - - Object.keys(selectedFilters.value).forEach((key) => { - if (selectedFilters.value[key]) filter[key] = selectedFilters.value[key]; - }); - - if (reload) applyFilter(filter); -} - async function clearFilter() { - selectedFilters.value = {}; byRecord.value = false; - userSelect.value = undefined; - searchInput.value = undefined; - changeInput.value = undefined; - dateFrom.value = undefined; - dateTo.value = undefined; - userRadio.value = undefined; - Object.keys(checkboxOptions.value).forEach( - (opt) => (checkboxOptions.value[opt].selected = false), - ); await applyFilter(); } +onMounted(() => { + stateStore.rightDrawerChangeValue(true); +}); onUnmounted(() => { stateStore.rightDrawer = false; }); @@ -383,32 +276,18 @@ watch( ); </script> <template> - <FetchData - :url="`${props.model}Logs/${route.params.id}/models`" - :filter="{ order: ['changedModel'] }" - @on-fetch=" - (data) => - (actions = data.map((item) => { - const changedModel = item.changedModel; - return { - locale: useCapitalize( - validations[changedModel]?.locale?.name ?? changedModel, - ), - value: changedModel, - }; - })) - " - auto-load - /> <VnPaginate ref="paginate" - :data-key="`${model}Log`" - :url="`${model}Logs`" + :data-key + :url="dataKey + 's'" :user-filter="filter" :skeleton="false" auto-load @on-fetch="setLogTree" + @on-change="setLogTree" search-url="logs" + :exprBuilder + :order="['creationDate DESC', 'id DESC']" > <template #body> <div @@ -467,6 +346,7 @@ watch( backgroundColor: useColor(modelLog.model), }" :title="`${modelLog.model} #${modelLog.id}`" + data-cy="vnLog-model-chip" > {{ t(modelLog.modelI18n) }} </QChip> @@ -561,9 +441,7 @@ watch( }}: </span> <VnLogValue - :value=" - value.val.val - " + :value="value.val" :name="value.name" /> </QItem> @@ -582,6 +460,7 @@ watch( }`, ) " + data-cy="vnLog-action-icon" /> </div> </QItem> @@ -616,7 +495,7 @@ watch( {{ prop.nameI18n }}: </span> <VnLogValue - :value="prop.val.val" + :value="prop.val" :name="prop.name" /> <span @@ -647,7 +526,7 @@ watch( </span> <span v-if="log.action == 'update'"> <VnLogValue - :value="prop.old.val" + :value="prop.old" :name="prop.name" /> <span @@ -658,7 +537,7 @@ watch( </span> → <VnLogValue - :value="prop.val.val" + :value="prop.val" :name="prop.name" /> <span @@ -670,7 +549,7 @@ watch( </span> <span v-else="prop.old.val"> <VnLogValue - :value="prop.val.val" + :value="prop.val" :name="prop.name" /> <span @@ -699,181 +578,12 @@ watch( </VnPaginate> <RightMenu> <template #right-panel> - <QList dense> - <QSeparator /> - <QItem class="q-mt-sm"> - <QInput - :label="t('globals.search')" - v-model="searchInput" - class="full-width" - clearable - filled - clear-icon="close" - @keyup.enter="() => selectFilter('search')" - @focusout="() => selectFilter('search')" - @clear="() => selectFilter('search')" - > - <template #append> - <QIcon name="info" class="cursor-pointer"> - <QTooltip>{{ t('tooltips.search') }}</QTooltip> - </QIcon> - </template> - </QInput> - </QItem> - <QItem> - <VnSelect - class="full-width" - :label="t('globals.entity')" - v-model="selectedFilters.changedModel" - option-label="locale" - option-value="value" - filled - :options="actions" - @update:model-value="selectFilter('action')" - hide-selected - /> - </QItem> - <QItem class="q-mt-sm"> - <QOptionGroup - size="sm" - v-model="userRadio" - :options="userTypes" - color="primary" - @update:model-value="selectFilter('userRadio')" - right-label - > - <template #label="{ label }"> - {{ t(`Users.${label}`) }} - </template> - </QOptionGroup> - </QItem> - <QItem class="q-mt-sm"> - <QItemSection v-if="userRadio !== null"> - <VnSelect - class="full-width" - :label="t('globals.user')" - v-model="userSelect" - filled - :url="`${model}Logs/${route.params.id}/editors`" - :fields="['id', 'nickname', 'name', 'image']" - sort-by="nickname" - @update:model-value="selectFilter('userSelect')" - hide-selected - > - <template #option="{ opt, itemProps }"> - <QItem - v-bind="itemProps" - class="q-pa-xs row items-center" - > - <QItemSection class="col-3 items-center"> - <VnAvatar :worker-id="opt.id" /> - </QItemSection> - <QItemSection class="col-9 justify-center"> - <span>{{ opt.name }}</span> - <span class="text-grey">{{ opt.nickname }}</span> - </QItemSection> - </QItem> - </template> - </VnSelect> - </QItemSection> - </QItem> - <QItem class="q-mt-sm"> - <QInput - :label="t('globals.changes')" - v-model="changeInput" - class="full-width" - filled - clearable - clear-icon="close" - @keyup.enter="selectFilter('change')" - @focusout="selectFilter('change')" - @clear="selectFilter('change')" - > - <template #append> - <QIcon name="info" class="cursor-pointer"> - <QTooltip max-width="250px">{{ - t('tooltips.changes') - }}</QTooltip> - </QIcon> - </template> - </QInput> - </QItem> - <QItem - :class="index == 'create' ? 'q-mt-md' : 'q-mt-xs'" - v-for="(checkboxOption, index) in checkboxOptions" - :key="index" - > - <QCheckbox - size="sm" - v-model="checkboxOption.selected" - :label="t(`actions.${checkboxOption.label}`)" - @update:model-value="selectFilter" - /> - </QItem> - <QItem class="q-mt-sm"> - <QInput - class="full-width" - :label="t('globals.date')" - @click="dateFromDialog = true" - @focus="(evt) => evt.target.blur()" - @clear="selectFilter('date', 'to')" - v-model="dateFrom" - clearable - filled - clear-icon="close" - /> - </QItem> - <QItem class="q-mt-sm"> - <QInput - class="full-width" - :label="t('globals.to')" - @click="dateToDialog = true" - @focus="(evt) => evt.target.blur()" - @clear="selectFilter('date', 'from')" - v-model="dateTo" - clearable - filled - clear-icon="close" - /> - </QItem> - </QList> + <VnLogFilter :data-key /> </template> </RightMenu> - <QDialog v-model="dateFromDialog"> - <QDate - :years-in-month-view="false" - v-model="dateFrom" - dense - flat - minimal - filled - @update:model-value=" - (value) => { - dateFromDialog = false; - dateFrom = date.formatDate(value, 'DD-MM-YYYY'); - selectFilter('date', 'from'); - } - " - /> - </QDialog> - <QDialog v-model="dateToDialog"> - <QDate - v-model="dateTo" - dense - flat - minimal - @update:model-value=" - (value) => { - dateToDialog = false; - dateTo = date.formatDate(value, 'DD-MM-YYYY'); - selectFilter('date', 'to'); - } - " - /> - </QDialog> <QPageSticky position="bottom-right" :offset="[25, 25]"> <QBtn - v-if="Object.values(selectedFilters).some((filter) => filter !== undefined)" + v-if="Object.keys(userParams).some((filter) => filter !== 'originFk')" color="primary" icon="filter_alt_off" size="md" diff --git a/src/components/common/VnLogFilter.vue b/src/components/common/VnLogFilter.vue index b5941239c..c7be68e9e 100644 --- a/src/components/common/VnLogFilter.vue +++ b/src/components/common/VnLogFilter.vue @@ -1,77 +1,249 @@ <script setup> -import { ref } from 'vue'; import { useI18n } from 'vue-i18n'; -import FetchData from 'components/FetchData.vue'; -import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; +import VnTableFilter from '../VnTable/VnTableFilter.vue'; +import VnSelect from './VnSelect.vue'; +import { useRoute } from 'vue-router'; +import VnInput from './VnInput.vue'; +import { ref, computed, watch } from 'vue'; +import VnInputDate from './VnInputDate.vue'; +import { useFilterParams } from 'src/composables/useFilterParams'; +import FetchData from '../FetchData.vue'; +import { useValidator } from 'src/composables/useValidator'; +import { useCapitalize } from 'src/composables/useCapitalize'; +import VnAvatar from '../ui/VnAvatar.vue'; -const { t } = useI18n(); -const props = defineProps({ +const $props = defineProps({ dataKey: { type: String, - required: true, + default: null, }, }); -const workers = ref(); +const { t } = useI18n(); +const route = useRoute(); +const validationsStore = useValidator(); +const { models } = validationsStore; +const entities = ref([]); +const editors = ref([]); +const userParams = ref(useFilterParams($props.dataKey).params); +let validations = models; +const userTypes = [ + { value: 'All', label: t(`Users.All`) }, + { value: 'User', label: t(`Users.User`) }, + { value: 'System', label: t(`Users.System`) }, +]; +const checkboxOptions = ref([ + { name: 'insert', label: 'Creates', selected: false }, + { name: 'update', label: 'Edits', selected: false }, + { name: 'delete', label: 'Deletes', selected: false }, + { name: 'select', label: 'Accesses', selected: false }, +]); +const columns = computed(() => [ + { name: 'changedModelValue' }, + { name: 'changedModel' }, + { name: 'userType', orderBy: false }, + { name: 'userFk' }, + { name: 'change', orderBy: false }, + { name: 'action' }, + { name: 'from', orderBy: 'creationDate' }, + { name: 'to', orderBy: 'creationDate' }, +]); + +const userParamsWatcher = watch( + () => userParams.value, + (params) => { + if (params.action) { + params.action.forEach((option) => { + checkboxOptions.value.find((o) => o.name === option).selected = true; + }); + userParamsWatcher(); + } + }, +); + +function getActions() { + const actions = checkboxOptions.value + .filter((option) => option.selected) + ?.map((o) => o.name); + return actions.length ? actions : null; +} </script> <template> <FetchData - url="Workers/activeWithInheritedRole" - :filter="{ where: { role: 'salesPerson' } }" - @on-fetch="(data) => (workers = data)" + :url="`${dataKey}s/${route.params.id}/models`" + :filter="{ order: ['changedModel'] }" + @on-fetch=" + (data) => + (entities = data.map((item) => { + const changedModel = item.changedModel; + return { + locale: useCapitalize( + validations[changedModel]?.locale?.name ?? changedModel, + ), + value: changedModel, + }; + })) + " auto-load /> - <VnFilterPanel :data-key="props.dataKey" :search-button="true"> - <template #tags="{ tag, formatFn }"> - <div class="q-gutter-x-xs"> - <strong>{{ t(`params.${tag.label}`) }}: </strong> - <span>{{ formatFn(tag.value) }}</span> + <FetchData + :url="`${dataKey}s/${route.params.id}/editors`" + :filter="{ fields: ['id', 'nickname', 'name', 'image'] }" + sort-by="nickname" + @on-fetch="(data) => (editors = data)" + auto-load + /> + <VnTableFilter + v-if="dataKey" + :data-key + :columns="columns" + :redirect="false" + :hiddenTags="['originFk', 'creationDate']" + search-url="logs" + :showTagChips="false" + > + <template #filter-changedModelValue="{ params, columnName, searchFn }"> + <VnInput + :label="t('globals.search')" + v-model="params[columnName]" + @keyup.enter="searchFn" + @blur="searchFn" + @remove="searchFn" + :info="t('tooltips.search')" + dense + filled + data-cy="vnLog-search" + /> + </template> + <template #filter-changedModel="{ params, columnName, searchFn }"> + <VnSelect + :label="t('globals.entity')" + v-model="params[columnName]" + option-label="locale" + option-value="value" + :options="entities" + @update:model-value="() => searchFn()" + dense + filled + data-cy="vnLog-entity" + /> + </template> + <template #filter-userType="{ params, columnName, searchFn }"> + <QOptionGroup + class="text-left" + size="sm" + v-model="params[columnName]" + :options="userTypes" + color="primary" + @update:model-value=" + () => { + params.userFk = null; + searchFn(); + } + " + /> + </template> + <template #filter-userFk="{ params, columnName, searchFn }"> + <VnSelect + :label="t('globals.user')" + v-model="params[columnName]" + :options="editors" + @update:modelValue="() => searchFn()" + :disable="params.userType === 'System'" + dense + filled + > + <template #option="{ opt, itemProps }"> + <QItem v-bind="itemProps" class="q-pa-xs row items-center"> + <QItemSection class="col-3 items-center"> + <VnAvatar :worker-id="opt.id" /> + </QItemSection> + <QItemSection class="col-9 justify-center"> + <span>{{ opt.name }}</span> + <span class="text-grey">{{ opt.nickname }}</span> + </QItemSection> + </QItem> + </template> + </VnSelect> + </template> + <template #filter-change="{ params, columnName, searchFn }"> + <VnInput + :label="t('globals.changes')" + v-model="params[columnName]" + @keyup.enter="searchFn" + @blur="searchFn" + @remove="searchFn" + :info="t('tooltips.changes')" + dense + filled + /> + </template> + <template #filter-action="{ searchFn }"> + <div class="column"> + <QCheckbox + v-for="checkboxOption in checkboxOptions" + :key="checkboxOption" + size="sm" + v-model="checkboxOption.selected" + :label="t(`actions.${checkboxOption.label}`)" + @update:model-value=" + () => searchFn(undefined, 'action', getActions()) + " + data-cy="vnLog-checkbox" + /> </div> </template> - <template #body="{ params, searchFn }"> - <QDate - v-model="params.created" - @update:model-value="searchFn()" + <template #filter-from="{ params, columnName, searchFn }"> + <VnInputDate + :label="t('globals.from')" + v-model="params[columnName]" dense - flat - minimal - > - </QDate> - <QSeparator /> - <QItem> - <QItemSection v-if="!workers"> - <QSkeleton type="QInput" class="full-width" /> - </QItemSection> - <QItemSection v-if="workers"> - <QSelect - :label="t('User')" - v-model="params.userFk" - @update:model-value="searchFn()" - :options="workers" - option-value="id" - option-label="name" - emit-value - map-options - use-input - :input-debounce="0" - /> - </QItemSection> - </QItem> + filled + @update:modelValue="() => searchFn()" + /> </template> - </VnFilterPanel> + <template #filter-to="{ params, columnName, searchFn }"> + <VnInputDate + :label="t('globals.to')" + v-model="params[columnName]" + dense + filled + @update:modelValue="() => searchFn()" + /> + </template> + </VnTableFilter> </template> - <i18n> -en: - params: - search: Contains - userFk: User - created: Created es: + tooltips: + search: Buscar por identificador o concepto + changes: Buscar por cambios. Los atributos deben buscarse por su nombre interno, para obtenerlo situar el cursor sobre el atributo. + actions: + Creates: Crea + Edits: Modifica + Deletes: Elimina + Accesses: Accede + Users: + User: Usuario + All: Todo + System: Sistema params: - search: Contiene - userFk: Usuario - created: Creada - User: Usuario + changedModel: Entity + +en: + tooltips: + search: Search by identifier or concept + changes: Search by changes. Attributes must be searched by their internal name, to get it place the cursor over the attribute. + actions: + Creates: Creates + Edits: Edits + Deletes: Deletes + Accesses: Accesses + Users: + User: User + All: All + System: System + params: + changedModel: Entidad </i18n> diff --git a/src/components/common/VnLogValue.vue b/src/components/common/VnLogValue.vue index df0be4011..3f1617ce7 100644 --- a/src/components/common/VnLogValue.vue +++ b/src/components/common/VnLogValue.vue @@ -5,18 +5,24 @@ import { computed } from 'vue'; const descriptorStore = useDescriptorStore(); const $props = defineProps({ - name: { type: [String], default: undefined }, + value: { type: Object, default: () => {} }, + name: { type: String, default: undefined }, }); const descriptor = computed(() => descriptorStore.has($props.name)); </script> <template> - <VnJsonValue v-bind="$attrs" /> - <QIcon - name="launch" - class="link" - v-if="$attrs.value && descriptor" - :data-cy="'iconLaunch-' + $props.name" - /> - <component :is="descriptor" :id="$attrs.value" v-if="$attrs.value && descriptor" /> + <VnJsonValue :value="value.val" /> + <span + v-if="(value.id || typeof value.val == 'number') && descriptor" + style="margin-left: 2px" + > + <QIcon + name="launch" + class="link" + :data-cy="'iconLaunch-' + $props.name" + style="padding-bottom: 2px" + /> + <component :is="descriptor" :id="value.id ?? value.val" /> + </span> </template> diff --git a/src/components/common/VnSection.vue b/src/components/common/VnSection.vue index 4bd17124f..34eb14601 100644 --- a/src/components/common/VnSection.vue +++ b/src/components/common/VnSection.vue @@ -40,10 +40,6 @@ const $props = defineProps({ type: Boolean, default: true, }, - keepData: { - type: Boolean, - default: true, - }, }); const route = useRoute(); @@ -61,7 +57,6 @@ onBeforeMount(() => { if ($props.dataKey) arrayData = useArrayData($props.dataKey, { searchUrl: 'table', - keepData: $props.keepData, ...$props.arrayDataProps, navigate: $props.redirect, }); diff --git a/src/components/common/__tests__/VnChangePassword.spec.js b/src/components/common/__tests__/VnChangePassword.spec.js index f5a967bb5..b610ce44d 100644 --- a/src/components/common/__tests__/VnChangePassword.spec.js +++ b/src/components/common/__tests__/VnChangePassword.spec.js @@ -1,4 +1,5 @@ -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import VnChangePassword from 'src/components/common/VnChangePassword.vue'; import { vi, beforeEach, afterEach, beforeAll, describe, expect, it } from 'vitest'; import { Notify } from 'quasar'; diff --git a/src/components/common/__tests__/VnDms.spec.js b/src/components/common/__tests__/VnDms.spec.js index 03028aee7..66d946db3 100644 --- a/src/components/common/__tests__/VnDms.spec.js +++ b/src/components/common/__tests__/VnDms.spec.js @@ -1,4 +1,5 @@ -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { createWrapper } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; import { vi, afterEach, beforeEach, beforeAll, describe, expect, it } from 'vitest'; import VnDms from 'src/components/common/VnDms.vue'; @@ -40,7 +41,10 @@ describe('VnDms', () => { companyFk: 2, dmsTypeFk: 3, description: 'This is a test description', - files: { name: 'example.txt', content: new Blob(['file content'], { type: 'text/plain' })}, + files: { + name: 'example.txt', + content: new Blob(['file content'], { type: 'text/plain' }), + }, }; const expectedBody = { @@ -59,7 +63,7 @@ describe('VnDms', () => { url: '/test', formInitialData: { id: 1, reference: 'test' }, model: 'Worker', - } + }, }); wrapper = wrapper.wrapper; vm = wrapper.vm; @@ -98,7 +102,7 @@ describe('VnDms', () => { expect(vm.getUrl()).toBe('/test'); }); - it('should returns url dms/"props.formInitialData.id"/updateFile when prop url is null', async () => { + it('should returns url dms/"props.formInitialData.id"/updateFile when prop url is null', async () => { await wrapper.setProps({ url: null }); expect(vm.getUrl()).toBe('dms/1/updateFile'); }); @@ -113,7 +117,9 @@ describe('VnDms', () => { describe('save', () => { it('should save data correctly', async () => { await vm.save(); - expect(postMock).toHaveBeenCalledWith(vm.getUrl(), expect.any(FormData), { params: expectedBody }); + expect(postMock).toHaveBeenCalledWith(vm.getUrl(), expect.any(FormData), { + params: expectedBody, + }); expect(wrapper.emitted('onDataSaved')).toBeTruthy(); }); }); @@ -127,8 +133,8 @@ describe('VnDms', () => { warehouseFk: 2, companyFk: 3, dmsTypeFk: 2, - description: 'This is a test description' - } + description: 'This is a test description', + }; await wrapper.setProps({ formInitialData: testData }); vm.defaultData(); @@ -137,10 +143,10 @@ describe('VnDms', () => { it('should add reference with "route.params.id" to dms if formInitialData is null', async () => { await wrapper.setProps({ formInitialData: null }); - vm.route.params.id= '111'; + vm.route.params.id = '111'; vm.defaultData(); expect(vm.dms.reference).toBe('111'); }); }); -}); \ No newline at end of file +}); diff --git a/src/components/common/__tests__/VnDmsList.spec.js b/src/components/common/__tests__/VnDmsList.spec.js index 22101239e..ee62f6971 100644 --- a/src/components/common/__tests__/VnDmsList.spec.js +++ b/src/components/common/__tests__/VnDmsList.spec.js @@ -1,4 +1,6 @@ -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { createWrapper } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; + import VnDmsList from 'src/components/common/VnDmsList.vue'; import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest'; diff --git a/src/components/common/__tests__/VnLog.spec.js b/src/components/common/__tests__/VnLog.spec.js index 53d2732a0..fcb516cc5 100644 --- a/src/components/common/__tests__/VnLog.spec.js +++ b/src/components/common/__tests__/VnLog.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import VnLog from 'src/components/common/VnLog.vue'; describe('VnLog', () => { @@ -108,27 +109,4 @@ describe('VnLog', () => { expect(vm.logTree[0].originFk).toEqual(1); expect(vm.logTree[0].logs[0].user.name).toEqual('salesPerson'); }); - - it('should correctly set the selectedFilters when filtering', () => { - vm.searchInput = '1'; - vm.userSelect = '21'; - vm.checkboxOptions.insert.selected = true; - vm.checkboxOptions.update.selected = true; - - vm.selectFilter('search'); - vm.selectFilter('userSelect'); - - expect(vm.selectedFilters.changedModelId).toEqual('1'); - expect(vm.selectedFilters.userFk).toEqual('21'); - expect(vm.selectedFilters.action).toEqual({ inq: ['insert', 'update'] }); - }); - - it('should correctly set the date from', () => { - vm.dateFrom = '18-09-2023'; - vm.selectFilter('date', 'from'); - expect(vm.selectedFilters.creationDate.between).toEqual([ - new Date('2023-09-18T00:00:00.000Z'), - new Date('2023-09-18T21:59:59.999Z'), - ]); - }); }); diff --git a/src/components/common/__tests__/VnLogFilter.spec.js b/src/components/common/__tests__/VnLogFilter.spec.js new file mode 100644 index 000000000..a28fa85b1 --- /dev/null +++ b/src/components/common/__tests__/VnLogFilter.spec.js @@ -0,0 +1,28 @@ +import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; +import { createWrapper } from 'app/test/vitest/helper'; +import VnLogFilter from 'src/components/common/VnLogFilter.vue'; + +describe('VnLogFilter', () => { + let vm; + beforeAll(async () => { + vm = createWrapper(VnLogFilter, { + props: { + dataKey: 'ClaimLog', + }, + }).vm; + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should getActions selected', async () => { + vm.checkboxOptions.find((o) => o.name == 'insert').selected = true; + vm.checkboxOptions.find((o) => o.name == 'update').selected = true; + + const actions = vm.getActions(); + + expect(actions.length).toEqual(2); + expect(actions).toEqual(['insert', 'update']); + }); +}); diff --git a/src/components/common/__tests__/VnNotes.spec.js b/src/components/common/__tests__/VnNotes.spec.js index 2603bf03c..e0514cc7b 100644 --- a/src/components/common/__tests__/VnNotes.spec.js +++ b/src/components/common/__tests__/VnNotes.spec.js @@ -1,16 +1,7 @@ -import { - describe, - it, - expect, - vi, - beforeAll, - afterEach, - beforeEach, - afterAll, -} from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { describe, it, expect, vi, afterEach, beforeEach, afterAll } from 'vitest'; +import { createWrapper } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; import VnNotes from 'src/components/ui/VnNotes.vue'; -import vnDate from 'src/boot/vnDate'; describe('VnNotes', () => { let vm; @@ -18,6 +9,7 @@ describe('VnNotes', () => { let spyFetch; let postMock; let patchMock; + let deleteMock; let expectedInsertBody; let expectedUpdateBody; const defaultOptions = { @@ -57,6 +49,7 @@ describe('VnNotes', () => { beforeEach(() => { postMock = vi.spyOn(axios, 'post'); patchMock = vi.spyOn(axios, 'patch'); + deleteMock = vi.spyOn(axios, 'delete'); }); afterEach(() => { @@ -153,4 +146,16 @@ describe('VnNotes', () => { ); }); }); + + describe('delete', () => { + it('Should call axios.delete with url and vnPaginateRef.fetch', async () => { + generateWrapper(); + createSpyFetch(); + + await vm.deleteNote({ id: 1 }); + + expect(deleteMock).toHaveBeenCalledWith(`${vm.$props.url}/1`); + expect(spyFetch).toHaveBeenCalled(); + }); + }); }); diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue index 2ec6bea78..a6c23be2e 100644 --- a/src/components/ui/CardSummary.vue +++ b/src/components/ui/CardSummary.vue @@ -159,6 +159,7 @@ async function fetch() { display: flex; flex-direction: row; margin-top: 2px; + align-items: start; .label { color: var(--vn-label-color); width: 9em; @@ -169,9 +170,15 @@ async function fetch() { flex-grow: 0; flex-shrink: 0; } + &.ellipsis > .value { + text-overflow: ellipsis; + white-space: pre; + } .value { color: var(--vn-text-color); overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } } .header { @@ -203,27 +210,21 @@ async function fetch() { } .vn-card-group { - display: flex; - flex-direction: column; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 16px; } .vn-card-content { display: flex; flex-direction: column; + overflow: hidden; + white-space: nowrap; text-overflow: ellipsis; > div { max-height: 70px; } } - -@media (min-width: 1010px) { - .vn-card-group { - flex-direction: row; - } - .vn-card-content { - flex: 1; - } -} </style> <style lang="scss" scoped> .summaryHeader .vn-label-value { diff --git a/src/components/ui/VnDescriptor.vue b/src/components/ui/VnDescriptor.vue index 47da98d74..994233eb0 100644 --- a/src/components/ui/VnDescriptor.vue +++ b/src/components/ui/VnDescriptor.vue @@ -30,7 +30,7 @@ const $props = defineProps({ default: null, }, toModule: { - type: String, + type: Object, default: null, }, }); @@ -252,6 +252,10 @@ const toModule = computed(() => { content: ':'; } } + &.ellipsis > .value { + text-overflow: ellipsis; + white-space: pre; + } .value { color: var(--vn-text-color); font-size: 14px; diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index 85cc8cde2..dc9e4e776 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -61,6 +61,10 @@ const $props = defineProps({ type: Object, default: null, }, + showTagChips: { + type: Boolean, + default: true, + }, }); const emit = defineEmits([ @@ -88,13 +92,14 @@ const userOrders = ref(useFilterParams($props.dataKey).orders); defineExpose({ search, params: userParams, remove }); const isLoading = ref(false); -async function search(evt) { +async function search(evt, name, value) { try { if (evt && $props.disableSubmitEvent) return; store.filter.where = {}; isLoading.value = true; const filter = { ...userParams.value, ...$props.modelValue }; + if (name) filter[name] = value; store.userParamsChanged = true; await arrayData.addFilter({ params: filter, @@ -214,7 +219,7 @@ const getLocale = (label) => { </QTooltip> </QBtn> <QForm @submit="search" id="filterPanelForm" @keyup.enter="search()"> - <QList dense> + <QList dense v-if="showTagChips"> <QItem class="q-mt-xs"> <QItemSection top> <QItemLabel header lines="1" class="text-uppercase q-py-xs q-px-none"> diff --git a/src/components/ui/VnLinkMail.vue b/src/components/ui/VnLinkMail.vue index a54f463f5..6c5129a9b 100644 --- a/src/components/ui/VnLinkMail.vue +++ b/src/components/ui/VnLinkMail.vue @@ -1,8 +1,11 @@ <script setup> +import { dashIfEmpty } from 'src/filters'; + defineProps({ email: { type: [String], default: null } }); </script> <template> <QBtn + class="q-pr-xs" v-if="email" flat round @@ -13,4 +16,5 @@ defineProps({ email: { type: [String], default: null } }); :href="`mailto:${email}`" @click.stop /> + <span>{{ dashIfEmpty(email) }}</span> </template> diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue index a9e9bc0fc..e34a70011 100644 --- a/src/components/ui/VnLinkPhone.vue +++ b/src/components/ui/VnLinkPhone.vue @@ -1,7 +1,7 @@ <script setup> import { ref, reactive, useAttrs, onBeforeMount, capitalize } from 'vue'; import axios from 'axios'; -import { parsePhone } from 'src/filters'; +import { dashIfEmpty, parsePhone } from 'src/filters'; import useOpenURL from 'src/composables/useOpenURL'; const props = defineProps({ @@ -12,49 +12,65 @@ const props = defineProps({ const phone = ref(props.phoneNumber); const config = reactive({ - sip: { icon: 'phone', href: `sip:${props.phoneNumber}` }, 'say-simple': { icon: 'vn:saysimple', url: null, channel: props.channel, }, + sip: { icon: 'phone', href: `sip:${props.phoneNumber}` }, }); -const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip'; + +const attrs = useAttrs(); +const types = Object.keys(config) + .filter((key) => key in attrs) + .sort(); +const activeTypes = types.length ? types : ['sip']; onBeforeMount(async () => { if (!phone.value) return; - let { channel } = config[type]; - if (type === 'say-simple') { - const { url, defaultChannel } = (await axios.get('SaySimpleConfigs/findOne')) - .data; - if (!channel) channel = defaultChannel; + for (const type of activeTypes) { + if (type === 'say-simple') { + let { channel } = config[type]; + const { url, defaultChannel } = (await axios.get('SaySimpleConfigs/findOne')) + .data; + if (!channel) channel = defaultChannel; - phone.value = await parsePhone(props.phoneNumber, props.country?.toLowerCase()); - config[ - type - ].url = `${url}?customerIdentity=%2B${phone.value}&channelId=${channel}`; + phone.value = await parsePhone( + props.phoneNumber, + props.country?.toLowerCase(), + ); + config[type].url = + `${url}?customerIdentity=%2B${phone.value}&channelId=${channel}`; + } } }); -function handleClick() { +function handleClick(type) { if (config[type].url) useOpenURL(config[type].url); else if (config[type].href) window.location.href = config[type].href; } </script> + <template> - <QBtn - v-if="phone" - flat - round - :icon="config[type].icon" - size="sm" - color="primary" - padding="none" - @click.stop="handleClick" - > - <QTooltip> - {{ capitalize(type).replace('-', '') }} - </QTooltip> - </QBtn> + <div class="flex items-center gap-2"> + <template v-for="type in activeTypes"> + <QBtn + :key="type" + v-if="phone" + flat + round + :icon="config[type].icon" + size="sm" + color="primary" + padding="none" + @click.stop="() => handleClick(type)" + > + <QTooltip> + {{ capitalize(type).replace('-', '') }} + </QTooltip> + </QBtn></template + > + <span>{{ dashIfEmpty(phone) }}</span> + </div> </template> diff --git a/src/components/ui/VnLv.vue b/src/components/ui/VnLv.vue index ee3791291..aa7342742 100644 --- a/src/components/ui/VnLv.vue +++ b/src/components/ui/VnLv.vue @@ -43,7 +43,7 @@ const val = computed(() => $props.value); <span style="color: var(--vn-label-color)">{{ label }}</span> </slot> </div> - <div class="value"> + <div class="value" v-if="value || $slots.value"> <slot name="value"> <span :title="value" style="text-overflow: ellipsis"> {{ dash ? dashIfEmpty(value) : value }} diff --git a/src/components/ui/VnMoreOptions.vue b/src/components/ui/VnMoreOptions.vue index 984e2b64f..bc81233d5 100644 --- a/src/components/ui/VnMoreOptions.vue +++ b/src/components/ui/VnMoreOptions.vue @@ -9,7 +9,7 @@ data-cy="descriptor-more-opts" > <QTooltip> - {{ $t('components.cardDescriptor.moreOptions') }} + {{ $t('components.vnDescriptor.moreOptions') }} </QTooltip> <QMenu ref="menuRef" data-cy="descriptor-more-opts-menu"> <QList data-cy="descriptor-more-opts_list"> diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue index b7e6ccbec..9cedbccfa 100644 --- a/src/components/ui/VnNotes.vue +++ b/src/components/ui/VnNotes.vue @@ -18,10 +18,10 @@ import VnInput from 'components/common/VnInput.vue'; const emit = defineEmits(['onFetch']); -const $attrs = useAttrs(); - -const isRequired = computed(() => { - return Object.keys($attrs).includes('required'); +const originalAttrs = useAttrs(); +const $attrs = computed(() => { + const { required, deletable, ...rest } = originalAttrs; + return rest; }); const $props = defineProps({ @@ -53,6 +53,11 @@ function handleClick(e) { else insert(); } +async function deleteNote(e) { + await axios.delete(`${$props.url}/${e.id}`); + await vnPaginateRef.value.fetch(); +} + async function insert() { if (!newNote.text || ($props.selectType && !newNote.observationTypeFk)) return; @@ -157,7 +162,7 @@ const handleObservationTypes = (data) => { v-model="newNote.observationTypeFk" option-label="description" style="flex: 0.15" - :required="isRequired" + :required="'required' in originalAttrs" @keyup.enter.stop="insert" /> <VnInput @@ -165,11 +170,10 @@ const handleObservationTypes = (data) => { type="textarea" :label="$props.justInput && newNote.text ? '' : t('Add note here...')" filled - size="lg" autogrow autofocus @keyup.enter.stop="handleClick" - :required="isRequired" + :required="'required' in originalAttrs" clearable > <template #append> @@ -239,6 +243,21 @@ const handleObservationTypes = (data) => { </QBadge> </div> <span v-text="toDateHourMin(note.created)" /> + <div> + <QIcon + v-if="'deletable' in originalAttrs" + name="delete" + size="sm" + class="cursor-pointer" + color="primary" + @click="deleteNote(note)" + data-cy="notesRemoveNoteBtn" + > + <QTooltip> + {{ t('ticketNotes.removeNote') }} + </QTooltip> + </QIcon> + </div> </div> </QCardSection> <QCardSection class="q-pa-xs q-my-none q-py-none"> diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue index b067381f6..8fbfb067f 100644 --- a/src/components/ui/VnPaginate.vue +++ b/src/components/ui/VnPaginate.vue @@ -115,7 +115,7 @@ onMounted(async () => { }); onBeforeUnmount(() => { - if (!store.keepData) arrayData.reset(['data']); + arrayData.reset(['data']); arrayData.resetPagination(); }); @@ -215,6 +215,7 @@ defineExpose({ paginate, userParams: arrayData.store.userParams, currentFilter: arrayData.store.currentFilter, + arrayData, }); </script> diff --git a/src/components/ui/__tests__/CardSummary.spec.js b/src/components/ui/__tests__/CardSummary.spec.js index 2f7f90882..ff6f60697 100644 --- a/src/components/ui/__tests__/CardSummary.spec.js +++ b/src/components/ui/__tests__/CardSummary.spec.js @@ -1,5 +1,7 @@ import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { createWrapper } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; + import CardSummary from 'src/components/ui/CardSummary.vue'; import * as vueRouter from 'vue-router'; diff --git a/src/components/ui/__tests__/Paginate.spec.js b/src/components/ui/__tests__/Paginate.spec.js index a67dfcdc6..968643b67 100644 --- a/src/components/ui/__tests__/Paginate.spec.js +++ b/src/components/ui/__tests__/Paginate.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import VnPaginate from 'src/components/ui/VnPaginate.vue'; describe('VnPaginate', () => { diff --git a/src/components/ui/__tests__/VnLinkPhone.spec.js b/src/components/ui/__tests__/VnLinkPhone.spec.js index a34ef90a5..3c92adf95 100644 --- a/src/components/ui/__tests__/VnLinkPhone.spec.js +++ b/src/components/ui/__tests__/VnLinkPhone.spec.js @@ -1,5 +1,5 @@ import { describe, it, expect, beforeAll, vi } from 'vitest'; -import { axios } from 'app/test/vitest/helper'; +import axios from 'axios'; import parsePhone from 'src/filters/parsePhone'; describe('parsePhone filter', () => { diff --git a/src/components/ui/__tests__/VnSms.spec.js b/src/components/ui/__tests__/VnSms.spec.js index e0f8c1868..4f4fd7d49 100644 --- a/src/components/ui/__tests__/VnSms.spec.js +++ b/src/components/ui/__tests__/VnSms.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import VnSms from 'src/components/ui/VnSms.vue'; describe('VnSms', () => { diff --git a/src/composables/__tests__/downloadFile.spec.js b/src/composables/__tests__/downloadFile.spec.js index f83a973b0..0cd38043f 100644 --- a/src/composables/__tests__/downloadFile.spec.js +++ b/src/composables/__tests__/downloadFile.spec.js @@ -1,5 +1,5 @@ import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest'; -import { axios } from 'app/test/vitest/helper'; +import axios from 'axios'; import { downloadFile } from 'src/composables/downloadFile'; import { useSession } from 'src/composables/useSession'; const session = useSession(); diff --git a/src/composables/__tests__/useAcl.spec.js b/src/composables/__tests__/useAcl.spec.js index 6cb29984c..86cd58fa0 100644 --- a/src/composables/__tests__/useAcl.spec.js +++ b/src/composables/__tests__/useAcl.spec.js @@ -1,5 +1,7 @@ import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest'; -import { axios, flushPromises } from 'app/test/vitest/helper'; +import axios from 'axios'; + +import { flushPromises } from '@vue/test-utils'; import { useAcl } from 'src/composables/useAcl'; describe('useAcl', () => { diff --git a/src/composables/__tests__/useArrayData.spec.js b/src/composables/__tests__/useArrayData.spec.js index a610ba9eb..a3fbbdd5d 100644 --- a/src/composables/__tests__/useArrayData.spec.js +++ b/src/composables/__tests__/useArrayData.spec.js @@ -1,15 +1,39 @@ import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'; -import { axios, flushPromises } from 'app/test/vitest/helper'; +import { default as axios } from 'axios'; import { useArrayData } from 'composables/useArrayData'; import { useRouter } from 'vue-router'; import * as vueRouter from 'vue-router'; +import { setActivePinia, createPinia } from 'pinia'; describe('useArrayData', () => { const filter = '{"limit":20,"skip":0}'; const params = { supplierFk: 2 }; + beforeEach(() => { - vi.spyOn(useRouter(), 'replace'); - vi.spyOn(useRouter(), 'push'); + setActivePinia(createPinia()); + + // Mock route + vi.spyOn(vueRouter, 'useRoute').mockReturnValue({ + path: 'mockSection/list', + matched: [], + query: {}, + params: {}, + meta: { moduleName: 'mockName' }, + }); + + // Mock router + vi.spyOn(vueRouter, 'useRouter').mockReturnValue({ + push: vi.fn(), + replace: vi.fn(), + currentRoute: { + value: { + path: 'mockSection/list', + params: { id: 1 }, + meta: { moduleName: 'mockName' }, + matched: [{ path: 'mockName/:id' }], + }, + }, + }); }); afterEach(() => { @@ -17,103 +41,69 @@ describe('useArrayData', () => { }); it('should fetch and replace url with new params', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] }); + vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: [] }); - const arrayData = useArrayData('ArrayData', { url: 'mockUrl' }); + const arrayData = useArrayData('ArrayData', { + url: 'mockUrl', + searchUrl: 'params', + }); arrayData.store.userParams = params; - arrayData.fetch({}); + await arrayData.fetch({}); - await flushPromises(); const routerReplace = useRouter().replace.mock.calls[0][0]; - expect(axios.get.mock.calls[0][1].params).toEqual({ - filter, - supplierFk: 2, + expect(axios.get).toHaveBeenCalledWith('mockUrl', { + signal: expect.any(Object), + params: { + filter, + supplierFk: 2, + }, }); - expect(routerReplace.path).toEqual('mockSection/list'); + + expect(routerReplace.path).toBe('mockSection/list'); expect(JSON.parse(routerReplace.query.params)).toEqual( expect.objectContaining(params), ); }); - it('should get data and send new URL without keeping parameters, if there is only one record', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }] }); + it('should redirect to detail when single record is returned with navigation', async () => { + vi.spyOn(axios, 'get').mockResolvedValueOnce({ + data: [{ id: 1 }], + }); - const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} }); + const arrayData = useArrayData('ArrayData', { + url: 'mockUrl', + navigate: {}, + }); arrayData.store.userParams = params; - arrayData.fetch({}); + await arrayData.fetch({}); - await flushPromises(); const routerPush = useRouter().push.mock.calls[0][0]; - expect(axios.get.mock.calls[0][1].params).toEqual({ - filter, - supplierFk: 2, - }); - expect(routerPush.path).toEqual('mockName/1'); + expect(routerPush.path).toBe('mockName/1'); expect(routerPush.query).toBeUndefined(); }); - it('should get data and send new URL keeping parameters, if you have more than one record', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }, { id: 2 }] }); - - vi.spyOn(vueRouter, 'useRoute').mockReturnValue({ - matched: [], - query: {}, - params: {}, - meta: { moduleName: 'mockName' }, - path: 'mockName/1', - }); - vi.spyOn(vueRouter, 'useRouter').mockReturnValue({ - push: vi.fn(), - replace: vi.fn(), - currentRoute: { - value: { - params: { - id: 1, - }, - meta: { moduleName: 'mockName' }, - matched: [{ path: 'mockName/:id' }], - }, - }, - }); - - const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} }); - - arrayData.store.userParams = params; - arrayData.fetch({}); - - await flushPromises(); - const routerPush = useRouter().push.mock.calls[0][0]; - - expect(axios.get.mock.calls[0][1].params).toEqual({ - filter, - supplierFk: 2, - }); - expect(routerPush.path).toEqual('mockName/'); - expect(routerPush.query.params).toBeDefined(); - }); - - it('should return one record', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ + it('should return one record when oneRecord is true', async () => { + vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: [ { id: 1, name: 'Entity 1' }, { id: 2, name: 'Entity 2' }, ], }); - const arrayData = useArrayData('ArrayData', { url: 'mockUrl', oneRecord: true }); + + const arrayData = useArrayData('ArrayData', { + url: 'mockUrl', + oneRecord: true, + }); + await arrayData.fetch({}); - expect(arrayData.store.data).toEqual({ id: 1, name: 'Entity 1' }); - }); - - it('should handle empty data gracefully if has to return one record', async () => { - vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] }); - const arrayData = useArrayData('ArrayData', { url: 'mockUrl', oneRecord: true }); - await arrayData.fetch({}); - - expect(arrayData.store.data).toBeUndefined(); + expect(arrayData.store.data).toEqual({ + id: 1, + name: 'Entity 1', + }); }); }); diff --git a/src/composables/__tests__/useRole.spec.js b/src/composables/__tests__/useRole.spec.js index d0bca5342..017301a1b 100644 --- a/src/composables/__tests__/useRole.spec.js +++ b/src/composables/__tests__/useRole.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it } from 'vitest'; -import { axios, flushPromises } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { flushPromises } from '@vue/test-utils'; import { useRole } from 'composables/useRole'; const role = useRole(); @@ -23,18 +24,19 @@ describe('useRole', () => { name: `T'Challa`, nickname: 'Black Panther', lang: 'en', + worker: { department: { departmentFk: 155 } }, }; const expectedUser = { id: 999, name: `T'Challa`, nickname: 'Black Panther', lang: 'en', + departmentFk: 155, }; const expectedRoles = ['salesPerson', 'admin']; - vi.spyOn(axios, 'get') - .mockResolvedValueOnce({ + vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: { roles: rolesData, user: fetchedUser }, - }) + }); vi.spyOn(role.state, 'setUser'); vi.spyOn(role.state, 'setRoles'); diff --git a/src/composables/__tests__/useSession.spec.js b/src/composables/__tests__/useSession.spec.js index 789b149ec..e86847b70 100644 --- a/src/composables/__tests__/useSession.spec.js +++ b/src/composables/__tests__/useSession.spec.js @@ -1,5 +1,5 @@ import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest'; -import { axios } from 'app/test/vitest/helper'; +import axios from 'axios'; import { useSession } from 'composables/useSession'; import { useState } from 'composables/useState'; @@ -75,6 +75,7 @@ describe('session', () => { userConfig: { darkMode: false, }, + worker: { department: { departmentFk: 155 } }, }; const rolesData = [ { @@ -143,7 +144,7 @@ describe('session', () => { await session.destroy(); // this clears token and user for any other test }); }, - {} + {}, ); describe('RenewToken', () => { @@ -175,7 +176,7 @@ describe('session', () => { await session.checkValidity(); expect(sessionStorage.getItem('token')).toEqual(expectedToken); expect(sessionStorage.getItem('tokenMultimedia')).toEqual( - expectedTokenMultimedia + expectedTokenMultimedia, ); }); it('Should renewToken', async () => { @@ -204,7 +205,7 @@ describe('session', () => { await session.checkValidity(); expect(sessionStorage.getItem('token')).not.toEqual(expectedToken); expect(sessionStorage.getItem('tokenMultimedia')).not.toEqual( - expectedTokenMultimedia + expectedTokenMultimedia, ); }); }); diff --git a/src/composables/__tests__/useTokenConfig.spec.js b/src/composables/__tests__/useTokenConfig.spec.js index a25a4abb1..92664e65a 100644 --- a/src/composables/__tests__/useTokenConfig.spec.js +++ b/src/composables/__tests__/useTokenConfig.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it } from 'vitest'; -import { axios, flushPromises } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { flushPromises } from '@vue/test-utils'; import { useTokenConfig } from 'composables/useTokenConfig'; const tokenConfig = useTokenConfig(); diff --git a/src/composables/useAcl.js b/src/composables/useAcl.js index ede359186..52704fee9 100644 --- a/src/composables/useAcl.js +++ b/src/composables/useAcl.js @@ -30,9 +30,16 @@ export function useAcl() { return false; } + function hasAcl(model, prop, accessType) { + const modelAcl = state.getAcls().value[model]; + const propAcl = modelAcl?.[prop] || modelAcl?.['*']; + return !!(propAcl?.[accessType] || propAcl?.['*']); + } + return { fetch, hasAny, state, + hasAcl, }; } diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index d1c1b01b8..2e880a16d 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -5,12 +5,11 @@ import { useArrayDataStore } from 'stores/useArrayDataStore'; import { buildFilter } from 'filters/filterPanel'; import { isDialogOpened } from 'src/filters'; -const arrayDataStore = useArrayDataStore(); - export function useArrayData(key, userOptions) { key ??= useRoute().meta.moduleName; if (!key) throw new Error('ArrayData: A key is required to use this composable'); + const arrayDataStore = useArrayDataStore(); // Move inside function if (!arrayDataStore.get(key)) arrayDataStore.set(key); @@ -56,7 +55,6 @@ export function useArrayData(key, userOptions) { 'searchUrl', 'navigate', 'mapKey', - 'keepData', 'oneRecord', ]; if (typeof userOptions === 'object') { @@ -108,7 +106,7 @@ export function useArrayData(key, userOptions) { store.hasMoreData = limit && response.data.length >= limit; if (!append && !isDialogOpened() && updateRouter) { - if (updateStateParams(response.data)?.redirect && !store.keepData) return; + if (updateStateParams(response.data)?.redirect) return; } store.isLoading = false; canceller = null; @@ -189,7 +187,7 @@ export function useArrayData(key, userOptions) { store.order = order; resetPagination(); - fetch({}); + await fetch({}); index++; return { index, order }; diff --git a/src/composables/useFilterParams.js b/src/composables/useFilterParams.js index 07dcdf99b..7c3f3bdeb 100644 --- a/src/composables/useFilterParams.js +++ b/src/composables/useFilterParams.js @@ -14,7 +14,7 @@ export function useFilterParams(key) { watch( () => arrayData.value.store?.currentFilter, (val, oldValue) => (val || oldValue) && setUserParams(val), - { immediate: true, deep: true } + { immediate: true, deep: true }, ); function parseOrder(urlOrders) { @@ -54,7 +54,7 @@ export function useFilterParams(key) { Object.assign(params, item); }); delete params[key]; - } else if (value && typeof value === 'object') { + } else if (value && typeof value === 'object' && !Array.isArray(value)) { const param = Object.values(value)[0]; if (typeof param == 'string') params[key] = param.replaceAll('%', ''); } diff --git a/src/composables/useRole.js b/src/composables/useRole.js index ff54b409c..e4e4f52c7 100644 --- a/src/composables/useRole.js +++ b/src/composables/useRole.js @@ -13,6 +13,7 @@ export function useRole() { name: data.user.name, nickname: data.user.nickname, lang: data.user.lang || 'es', + departmentFk: data.user?.worker?.department?.departmentFk, }; state.setUser(userData); state.setRoles(roles); diff --git a/src/composables/useSession.js b/src/composables/useSession.js index e69819a68..36b31ab0a 100644 --- a/src/composables/useSession.js +++ b/src/composables/useSession.js @@ -60,7 +60,7 @@ export function useSession() { const { data: isValidToken } = await axios.get('VnUsers/validateToken'); if (isValidToken) destroyTokenPromises = Object.entries(tokens).map(([key, url]) => - destroyToken(url, storage, key) + destroyToken(url, storage, key), ); } } finally { diff --git a/src/composables/useValidator.js b/src/composables/useValidator.js index 7a7032608..ae6c47d91 100644 --- a/src/composables/useValidator.js +++ b/src/composables/useValidator.js @@ -78,7 +78,8 @@ export function useValidator() { if (min >= 0) if (Math.floor(value) < min) return t('inputMin', { value: min }); }, - custom: (value) => validation.bindedFunction(value) || 'Invalid value', + custom: (value) => + eval(`(${validation.bindedFunction})`)(value) || 'Invalid value', }; }; diff --git a/src/css/app.scss b/src/css/app.scss index b299973d1..dd5dbe247 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -340,3 +340,6 @@ input::-webkit-inner-spin-button { .containerShrinked { width: 70%; } +.q-item__section--main ~ .q-item__section--side { + padding-inline: 0; +} diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index c62305f95..7bcf90793 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -370,6 +370,11 @@ globals: countryCodeFk: Country companyFk: Company nickname: Alias + changedModel: Entity + changedModelValue: Search + changedModelId: Entity id + userFk: User + action: Action model: Model fuel: Fuel active: Active @@ -842,6 +847,7 @@ travel: availabledHour: Availabled hour thermographs: Thermographs hb: HB + roundedCc: Rounded CC basicData: daysInForward: Automatic movement (Raid) isRaid: Raid @@ -884,7 +890,7 @@ components: openCard: View openSummary: Summary viewSummary: Summary - cardDescriptor: + vnDescriptor: mainList: Main list summary: Summary moreOptions: More options diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 86d15e985..b2512193d 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -371,6 +371,11 @@ globals: countryCodeFk: PaĂs companyFk: Empresa nickname: Alias + changedModel: Entidad + changedModelValue: Buscar + changedModelId: Id de entidad + userFk: Usuario + action: AcciĂłn errors: statusUnauthorized: Acceso denegado statusInternalServerError: Ha ocurrido un error interno del servidor @@ -925,6 +930,7 @@ travel: availabled: F. Disponible availabledHour: Hora Disponible hb: HB + roundedCc: CC redondeado basicData: daysInForward: Desplazamiento automatico (redada) isRaid: Redada @@ -968,7 +974,7 @@ components: openCard: Ficha openSummary: Detalles viewSummary: Vista previa - cardDescriptor: + vnDescriptor: mainList: Listado principal summary: Resumen moreOptions: Más opciones diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue index eafd62df6..f3eabb531 100644 --- a/src/pages/Account/Card/AccountDescriptorMenu.vue +++ b/src/pages/Account/Card/AccountDescriptorMenu.vue @@ -100,12 +100,8 @@ const onChangePass = (oldPass) => { }; onMounted(() => { - hasitManagementAccess.value = useAcl().hasAny([ - { model: 'VnUser', props: 'higherPrivileges', accessType: 'WRITE' }, - ]); - hasSysadminAccess.value = useAcl().hasAny([ - { model: 'VnUser', props: 'adminUser', accessType: 'WRITE' }, - ]); + hasitManagementAccess.value = useAcl().hasAcl('VnUser', 'higherPrivileges', 'WRITE'); + hasSysadminAccess.value = useAcl().hasAcl('VnUser', 'adminUser', 'WRITE'); }); </script> <template> @@ -227,7 +223,7 @@ onMounted(() => { <QItemSection>{{ t('account.card.actions.deactivateUser.name') }}</QItemSection> </QItem> <QItem - v-if="useAcl().hasAny([{ model: 'VnRole', props: '*', accessType: 'WRITE' }])" + v-if="useAcl().hasAcl('VnRole', '*', 'WRITE')" v-ripple clickable @click="showSyncDialog = true" diff --git a/src/pages/Account/Card/AccountDescriptorProxy.vue b/src/pages/Account/Card/AccountDescriptorProxy.vue index de3220fea..6a4b3e267 100644 --- a/src/pages/Account/Card/AccountDescriptorProxy.vue +++ b/src/pages/Account/Card/AccountDescriptorProxy.vue @@ -6,7 +6,7 @@ import AccountSummary from './AccountSummary.vue'; <QPopupProxy style="max-width: 10px"> <AccountDescriptor v-if="$attrs.id" - v-bind="$attrs.id" + v-bind="$attrs" :summary="AccountSummary" :proxy-render="true" /> diff --git a/src/pages/Claim/Card/ClaimSummary.vue b/src/pages/Claim/Card/ClaimSummary.vue index 5d06d5627..67d57004f 100644 --- a/src/pages/Claim/Card/ClaimSummary.vue +++ b/src/pages/Claim/Card/ClaimSummary.vue @@ -21,6 +21,7 @@ import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorP import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue'; import ClaimDescriptorMenu from './ClaimDescriptorMenu.vue'; +import VnDropdown from 'src/components/common/VnDropdown.vue'; const route = useRoute(); const router = useRouter(); @@ -36,7 +37,7 @@ const $props = defineProps({ }); const entityId = computed(() => $props.id || route.params.id); -const ClaimStates = ref([]); +const claimStates = ref([]); const claimDmsRef = ref(); const claimDms = ref([]); const multimediaDialog = ref(); @@ -173,7 +174,9 @@ function openDialog(dmsId) { } async function changeState(value) { - await axios.patch(`Claims/updateClaim/${entityId.value}`, { claimStateFk: value }); + await axios.patch(`Claims/updateClaim/${entityId.value}`, { + claimStateFk: value, + }); router.go(route.fullPath); } @@ -183,13 +186,18 @@ function claimUrl(section) { </script> <template> + <FetchData + url="ClaimStates" + :filter="{ fields: ['id', 'description'] }" + @on-fetch="(data) => (claimStates = data)" + auto-load + /> <FetchData url="ClaimDms" :filter="claimDmsFilter" @on-fetch="(data) => setClaimDms(data)" ref="claimDmsRef" /> - <FetchData url="ClaimStates" @on-fetch="(data) => (ClaimStates = data)" auto-load /> <CardSummary ref="summary" :url="`Claims/${entityId}/getSummary`" @@ -201,34 +209,11 @@ function claimUrl(section) { {{ claim.id }} - {{ claim.client.name }} ({{ claim.client.id }}) </template> <template #header-right> - <QBtnDropdown - side - top - color="black" - text-color="white" - :label="t('globals.changeState')" - > - <QList> - <QVirtualScroll - class="max-container-height" - :items="ClaimStates" - separator - v-slot="{ item, index }" - > - <QItem - :key="index" - dense - clickable - v-close-popup - @click="changeState(item.id)" - > - <QItemSection> - <QItemLabel>{{ item.description }}</QItemLabel> - </QItemSection> - </QItem> - </QVirtualScroll> - </QList> - </QBtnDropdown> + <VnDropdown + :options="claimStates" + option-label="description" + @change-state="changeState" + /> </template> <template #menu="{ entity }"> <ClaimDescriptorMenu :claim="entity.claim" /> diff --git a/src/pages/Claim/Card/ClaimSummaryAction.vue b/src/pages/Claim/Card/ClaimSummaryAction.vue index 577ac2a65..be3b9e896 100644 --- a/src/pages/Claim/Card/ClaimSummaryAction.vue +++ b/src/pages/Claim/Card/ClaimSummaryAction.vue @@ -88,13 +88,13 @@ const columns = [ auto-load > <template #column-itemFk="{ row }"> - <span class="link"> + <span class="link" @click.stop> {{ row.itemFk }} <ItemDescriptorProxy :id="row.itemFk" /> </span> </template> <template #column-ticketFk="{ row }"> - <span class="link"> + <span class="link" @click.stop> {{ row.ticketFk }} <TicketDescriptorProxy :id="row.ticketFk" /> </span> diff --git a/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js b/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js index b208f1704..2142f41f2 100644 --- a/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js +++ b/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue'; describe('ClaimDescriptorMenu', () => { diff --git a/src/pages/Claim/Card/__tests__/ClaimLines.spec.js b/src/pages/Claim/Card/__tests__/ClaimLines.spec.js index 2f2c0e298..d975fb514 100644 --- a/src/pages/Claim/Card/__tests__/ClaimLines.spec.js +++ b/src/pages/Claim/Card/__tests__/ClaimLines.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import ClaimLines from '/src/pages/Claim/Card/ClaimLines.vue'; describe('ClaimLines', () => { diff --git a/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js b/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js index d93c96132..2a5176d0a 100644 --- a/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js +++ b/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import ClaimLinesImport from 'pages/Claim/Card/ClaimLinesImport.vue'; describe('ClaimLinesImport', () => { diff --git a/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js b/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js index c38852af1..b14338b5c 100644 --- a/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js +++ b/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js @@ -1,7 +1,7 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import ClaimPhoto from 'pages/Claim/Card/ClaimPhoto.vue'; - describe('ClaimPhoto', () => { let vm; @@ -61,7 +61,7 @@ describe('ClaimPhoto', () => { title: 'This file will be deleted', icon: 'delete', data: { index: 1 }, - promise: vm.deleteDms + promise: vm.deleteDms, }, }) ); diff --git a/src/pages/Claim/ClaimFilter.vue b/src/pages/Claim/ClaimFilter.vue index 51460f7e4..45eb89382 100644 --- a/src/pages/Claim/ClaimFilter.vue +++ b/src/pages/Claim/ClaimFilter.vue @@ -115,6 +115,7 @@ const props = defineProps({ <i18n> en: params: + departmentFk: Department search: Contains clientFk: Customer clientName: Customer @@ -127,6 +128,7 @@ en: zoneFk: Zone es: params: + departmentFk: Departamento search: Contiene clientFk: Cliente clientName: Cliente diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue index 06996c2c1..e0d9928f9 100644 --- a/src/pages/Claim/ClaimList.vue +++ b/src/pages/Claim/ClaimList.vue @@ -134,7 +134,7 @@ const columns = computed(() => [ const STATE_COLOR = { pending: 'bg-warning', - managed: 'bg-info', + loses: 'bg-negative', resolved: 'bg-positive', }; </script> diff --git a/src/pages/Customer/Card/CustomerBalance.vue b/src/pages/Customer/Card/CustomerBalance.vue index 11db92eab..4855fadc0 100644 --- a/src/pages/Customer/Card/CustomerBalance.vue +++ b/src/pages/Customer/Card/CustomerBalance.vue @@ -20,11 +20,12 @@ import VnFilter from 'components/VnTable/VnFilter.vue'; import CustomerNewPayment from 'src/pages/Customer/components/CustomerNewPayment.vue'; import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; +import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; const { openConfirmationModal } = useVnConfirm(); const { sendEmail, openReport } = usePrintService(); const { t } = useI18n(); -const { hasAny } = useAcl(); +const { hasAcl } = useAcl(); const quasar = useQuasar(); const route = useRoute(); @@ -89,15 +90,7 @@ const columns = computed(() => [ { align: 'left', label: t('Employee'), - columnField: { - component: 'userLink', - attrs: ({ row }) => { - return { - workerId: row.workerFk, - name: row.userName, - }; - }, - }, + name: 'workerFk', cardVisible: true, }, { @@ -131,7 +124,6 @@ const columns = computed(() => [ align: 'left', name: 'balance', label: t('Balance'), - format: ({ balance }) => toCurrency(balance), cardVisible: true, }, { @@ -146,12 +138,14 @@ const columns = computed(() => [ actions: [ { title: t('globals.downloadPdf'), + isPrimary: true, icon: 'cloud_download', show: (row) => row.isInvoice, action: (row) => showBalancePdf(row), }, { title: t('Send compensation'), + isPrimary: true, icon: 'outgoing_mail', show: (row) => !!row.isCompensation, action: ({ id }) => @@ -256,6 +250,12 @@ const showBalancePdf = ({ id }) => { <template #column-balance="{ rowIndex }"> {{ toCurrency(balances[rowIndex]?.balance) }} </template> + <template #column-workerFk="{ row }"> + <span class="link" @click.stop> + {{ row.userName }} + <WorkerDescriptorProxy :id="row.workerFk" /> + </span> + </template> <template #column-description="{ row }"> <span class="link" v-if="row.isInvoice" @click.stop> {{ t('bill', { ref: row.description }) }} @@ -276,9 +276,7 @@ const showBalancePdf = ({ id }) => { > <VnInput v-model="scope.value" - :disable=" - !hasAny([{ model: 'Receipt', props: '*', accessType: 'WRITE' }]) - " + :disable="!hasAcl('Receipt', '*', 'WRITE')" @keypress.enter="scope.set" autofocus /> diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue index 93909eb9c..baa728868 100644 --- a/src/pages/Customer/Card/CustomerFiscalData.vue +++ b/src/pages/Customer/Card/CustomerFiscalData.vue @@ -79,7 +79,7 @@ async function acceptPropagate({ isEqualizated }) { observe-form-changes @on-data-saved="checkEtChanges" > - <template #form="{ data, validate }"> + <template #form="{ data, validate, validations }"> <VnRow> <VnInput :label="t('Social name')" @@ -112,6 +112,7 @@ async function acceptPropagate({ isEqualizated }) { v-model="data.sageTaxTypeFk" data-cy="sageTaxTypeFk" :required="data.isTaxDataChecked" + :rules="[(val) => validations.required(data.isTaxDataChecked, val)]" /> <VnSelect :label="t('Sage transaction type')" @@ -122,6 +123,9 @@ async function acceptPropagate({ isEqualizated }) { data-cy="sageTransactionTypeFk" v-model="data.sageTransactionTypeFk" :required="data.isTaxDataChecked" + :rules="[ + (val) => validations.required(data.sageTransactionTypeFk, val), + ]" > <template #option="scope"> <QItem v-bind="scope.itemProps"> diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index a9179d924..af7231d6f 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -84,29 +84,31 @@ const sumRisk = ({ clientRisks }) => { <VnLv :label="t('customer.summary.customerId')" :value="entity.id" /> <VnLv :label="t('globals.name')" :value="entity.name" /> <VnLv :label="t('customer.summary.contact')" :value="entity.contact" /> - <VnLv :value="entity.phone"> - <template #label> - {{ t('customer.extendedList.tableVisibleColumns.phone') }} + <VnLv :label="t('customer.extendedList.tableVisibleColumns.phone')"> + <template #value> <VnLinkPhone :phone-number="entity.phone" /> </template> </VnLv> - <VnLv :value="entity.mobile"> - <template #label> - {{ t('customer.summary.mobile') }} - <VnLinkPhone :phone-number="entity.mobile" /> + <VnLv :label="t('customer.summary.mobile')"> + <template #value> <VnLinkPhone + sip say-simple :phone-number="entity.mobile" :channel="entity.country?.saySimpleCountry?.channel" - class="q-ml-xs" /> </template> </VnLv> - <VnLv :value="entity.email" copy - ><template #label> - {{ t('globals.params.email') }} - <VnLinkMail email="entity.email"></VnLinkMail> </template - ></VnLv> + <VnLv + :label="t('globals.params.email')" + :value="entity.email" + class="ellipsis" + copy + > + <template #value> + <VnLinkMail :email="entity.email" /> + </template> + </VnLv> <VnLv :label="t('globals.department')"> <template #value> <span class="link" v-text="entity.department?.name" /> diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue index 55a7f565e..c30b11528 100644 --- a/src/pages/Customer/CustomerFilter.vue +++ b/src/pages/Customer/CustomerFilter.vue @@ -72,6 +72,7 @@ const exprBuilder = (param, value) => { option-value="id" option-label="name" url="Departments" + no-one="true" /> </QItemSection> </QItem> @@ -154,6 +155,7 @@ en: city: City phone: Phone email: Email + departmentFk: Department isToBeMailed: Mailed isEqualizated: Equailized businessTypeFk: Business type @@ -166,6 +168,7 @@ en: postcode: Postcode es: params: + departmentFk: Departamento search: Contiene fi: NIF isActive: Activo diff --git a/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue b/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue index 64e3baeb5..f7d4163d1 100644 --- a/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue +++ b/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue @@ -192,8 +192,10 @@ en: date: L. O. Date credit: Credit I. defaulterSinced: From + departmentFk: Department es: params: + departmentFk: Departamento clientFk: Cliente countryFk: PaĂs paymentMethod: F. Pago diff --git a/src/pages/Customer/Notifications/CustomerNotifications.vue b/src/pages/Customer/Notifications/CustomerNotifications.vue index b30ed6f76..cbbd6d205 100644 --- a/src/pages/Customer/Notifications/CustomerNotifications.vue +++ b/src/pages/Customer/Notifications/CustomerNotifications.vue @@ -127,6 +127,7 @@ es: Identifier: Identificador Social name: RazĂłn social Phone: TelĂ©fono + Postcode: CĂłdigo postal City: PoblaciĂłn Email: Email Campaign consumption: Consumo campaña diff --git a/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js b/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js index 466a544b4..a9c845cec 100644 --- a/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js +++ b/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import CustomerPayments from 'src/pages/Customer/Payments/CustomerPayments.vue'; describe('CustomerPayments', () => { diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue index f852c160a..bc76f5985 100644 --- a/src/pages/Customer/components/CustomerAddressEdit.vue +++ b/src/pages/Customer/components/CustomerAddressEdit.vue @@ -93,10 +93,26 @@ const updateAddressTicket = async () => { }; const updateObservations = async (payload) => { - await axios.post('AddressObservations/crud', payload); + await axios.post('AddressObservations/crud', cleanPayload(payload)); notes.value = []; deletes.value = []; }; + +function cleanPayload(payload) { + ['creates', 'deletes', 'updates'].forEach((prop) => { + if (prop === 'creates' || prop === 'updates') { + payload[prop] = payload[prop].filter( + (item) => item.description !== '' && item.observationTypeFk !== '', + ); + } else { + payload[prop] = payload[prop].filter( + (item) => item !== null && item !== undefined, + ); + } + }); + return payload; +} + async function updateAll({ data, payload }) { await updateObservations(payload); await updateAddress(data); diff --git a/src/pages/Customer/components/CustomerNewPayment.vue b/src/pages/Customer/components/CustomerNewPayment.vue index ac80fdaa4..fb3804d55 100644 --- a/src/pages/Customer/components/CustomerNewPayment.vue +++ b/src/pages/Customer/components/CustomerNewPayment.vue @@ -3,18 +3,20 @@ import { onBeforeMount, reactive, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import axios from 'axios'; -import { getClientRisk } from '../composables/getClientRisk'; import { useDialogPluginComponent } from 'quasar'; -import FormModelPopup from 'components/FormModelPopup.vue'; + +import { getClientRisk } from '../composables/getClientRisk'; import { usePrintService } from 'composables/usePrintService'; import useNotify from 'src/composables/useNotify.js'; + +import FormModelPopup from 'components/FormModelPopup.vue'; import FetchData from 'components/FetchData.vue'; -import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputNumber from 'components/common/VnInputNumber.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import VnInput from 'src/components/common/VnInput.vue'; +import VnAccountNumber from 'src/components/common/VnAccountNumber.vue'; const { t } = useI18n(); const route = useRoute(); @@ -48,7 +50,7 @@ const maxAmount = ref(); const accountingType = ref({}); const isCash = ref(false); const formModelRef = ref(false); - +const amountToReturn = ref(); const filterBanks = { fields: ['id', 'bank', 'accountingTypeFk'], include: { relation: 'accountingType' }, @@ -90,7 +92,7 @@ function setPaymentType(data, accounting) { let descriptions = []; if (accountingType.value.receiptDescription) descriptions.push(accountingType.value.receiptDescription); - if (data.description) descriptions.push(data.description); + if (data.description > 0) descriptions.push(data.description); data.description = descriptions.join(', '); } @@ -100,7 +102,7 @@ const calculateFromAmount = (event) => { }; const calculateFromDeliveredAmount = (event) => { - initialData.amountToReturn = parseFloat(event) - initialData.amountPaid; + amountToReturn.value = event - initialData.amountPaid; }; function onBeforeSave(data) { @@ -121,17 +123,16 @@ async function onDataSaved(formData, { id }) { recipient: formData.email, }); - if (viewReceipt.value) openReport(`Receipts/${id}/receipt-pdf`); + if (viewReceipt.value) openReport(`Receipts/${id}/receipt-pdf`, {}, '_blank'); } finally { if ($props.promise) $props.promise(); if (closeButton.value) closeButton.value.click(); } } -async function accountShortToStandard({ target: { value } }) { +async function getSupplierClientReferences(value) { if (!value) return (initialData.description = ''); - initialData.compensationAccount = value.replace('.', '0'.repeat(11 - value.length)); - const params = { bankAccount: initialData.compensationAccount }; + const params = { bankAccount: value }; const { data } = await axios(`Clients/getClientOrSupplierReference`, { params }); if (!data.clientId) { initialData.description = t('Supplier Compensation Reference', { @@ -241,17 +242,16 @@ async function getAmountPaid() { @update:model-value="getAmountPaid()" /> </VnRow> - - <div v-if="data.bankFk?.accountingType?.code == 'compensation'"> + <div v-if="accountingType.code == 'compensation'"> <div class="text-h6"> {{ t('Compensation') }} </div> <VnRow> - <VnInputNumber + <VnAccountNumber :label="t('Compensation account')" clearable v-model="data.compensationAccount" - @blur="accountShortToStandard" + @blur="getSupplierClientReferences(data.compensationAccount)" /> </VnRow> </div> @@ -261,8 +261,7 @@ async function getAmountPaid() { clearable v-model="data.description" /> - - <div v-if="data.bankFk?.accountingType?.code == 'cash'"> + <div v-if="accountingType.code == 'cash'"> <div class="text-h6">{{ t('Cash') }}</div> <VnRow> <VnInputNumber @@ -274,7 +273,7 @@ async function getAmountPaid() { <VnInputNumber :label="t('Amount to return')" disable - v-model="data.amountToReturn" + v-model="amountToReturn" /> </VnRow> <VnRow> diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue index 09c7e714c..feb137065 100644 --- a/src/pages/Customer/components/CustomerSummaryTable.vue +++ b/src/pages/Customer/components/CustomerSummaryTable.vue @@ -191,7 +191,7 @@ const getItemPackagingType = (ticketSales) => { :without-header="true" auto-load :row-click="rowClick" - order="shipped DESC, id" + order="shipped DESC, id DESC" :disable-option="{ card: true, table: true }" class="full-width" :disable-infinite-scroll="true" diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue index a93b0801b..baa4d96b7 100644 --- a/src/pages/Entry/Card/EntryBuys.vue +++ b/src/pages/Entry/Card/EntryBuys.vue @@ -648,7 +648,7 @@ onMounted(() => { :url="`Entries/${entityId}/getBuyList`" search-url="EntryBuys" save-url="Buys/crud" - :filter="filter" + :filter="editableMode ? filter : {}" :disable-option="{ card: true }" v-model:selected="selectedRows" @on-fetch="() => footerFetchDataRef.fetch()" @@ -787,7 +787,7 @@ onMounted(() => { <span data-cy="footer-amount">{{ footer?.amount }} / </span> <span style="color: var(--q-positive)">{{ footer?.checkedAmount }}</span> </template> - <template #column-create-itemFk="{ data }"> + <template #column-create-itemFk="{ data, validations }"> <VnSelect url="Items/search" v-model="data.itemFk" @@ -801,7 +801,8 @@ onMounted(() => { await setBuyUltimate(value, data); } " - :required="true" + required + :rules="[(val) => validations.required(true, val)]" data-cy="itemFk-create-popup" sort-by="nickname DESC" > diff --git a/src/pages/Entry/Card/EntryCard.vue b/src/pages/Entry/Card/EntryCard.vue index 50f8b8e55..e9d07889f 100644 --- a/src/pages/Entry/Card/EntryCard.vue +++ b/src/pages/Entry/Card/EntryCard.vue @@ -8,6 +8,6 @@ import filter from './EntryFilter.js'; data-key="Entry" url="Entries" :descriptor="EntryDescriptor" - :filter="filter" + :filter="{ ...filter, where: { id: $route.params.id } }" /> </template> diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue index 202f94997..2f9cfe0ff 100644 --- a/src/pages/Entry/Card/EntryDescriptor.vue +++ b/src/pages/Entry/Card/EntryDescriptor.vue @@ -147,7 +147,7 @@ async function deleteEntry() { <template> <EntityDescriptor :url="`Entries/${entityId}`" - :user-filter="entryFilter" + :filter="entryFilter" title="supplier.nickname" data-key="Entry" width="lg-width" diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue index 37a28968c..d5ebcde18 100644 --- a/src/pages/Entry/Card/EntrySummary.vue +++ b/src/pages/Entry/Card/EntrySummary.vue @@ -70,8 +70,8 @@ onMounted(async () => { :url="`#/entry/${entityId}/basic-data`" :text="t('globals.summary.basicData')" /> - <div class="card-group"> - <div class="card-content"> + <div class="vn-card-group"> + <div class="vn-card-content"> <VnLv :label="t('entry.summary.commission')" :value="entry?.commission" @@ -93,7 +93,7 @@ onMounted(async () => { :value="entry?.invoiceNumber" /> </div> - <div class="card-content"> + <div class="vn-card-content"> <VnCheckbox :label="t('entry.list.tableVisibleColumns.isOrdered')" v-model="entry.isOrdered" @@ -130,8 +130,8 @@ onMounted(async () => { :url="`#/travel/${entry.travel.id}/summary`" :text="t('Travel')" /> - <div class="card-group"> - <div class="card-content"> + <div class="vn-card-group"> + <div class="vn-card-content"> <VnLv :label="t('entry.summary.travelReference')"> <template #value> <span class="link"> @@ -161,7 +161,7 @@ onMounted(async () => { :value="entry.travel.warehouseIn?.name" /> </div> - <div class="card-content"> + <div class="vn-card-content"> <VnLv :label="t('travel.awbFk')" :value="entry.travel.awbFk" /> <VnCheckbox :label="t('entry.summary.travelDelivered')" @@ -193,31 +193,6 @@ onMounted(async () => { </template> </CardSummary> </template> -<style lang="scss" scoped> -.card-group { - display: flex; - flex-direction: column; -} - -.card-content { - display: flex; - flex-direction: column; - text-overflow: ellipsis; - > div { - max-height: 24px; - } -} - -@media (min-width: 1010px) { - .card-group { - flex-direction: row; - } - .card-content { - flex: 1; - margin-right: 16px; - } -} -</style> <i18n> es: Travel: EnvĂo diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index 5ebad3144..e42380fa3 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -248,7 +248,6 @@ function getBadgeAttrs(row) { let timeDiff = today - timeTicket; - if (timeDiff > 0) return { color: 'info', 'text-color': 'black' }; if (timeDiff < 0) return { color: 'warning', 'text-color': 'black' }; switch (row.entryTypeCode) { case 'regularization': @@ -274,6 +273,7 @@ function getBadgeAttrs(row) { default: break; } + if (timeDiff > 0) return { color: 'info', 'text-color': 'black' }; return { color: 'transparent' }; } diff --git a/src/pages/Entry/EntryStockBought.vue b/src/pages/Entry/EntryStockBought.vue index 6168f0737..9e97e2ad5 100644 --- a/src/pages/Entry/EntryStockBought.vue +++ b/src/pages/Entry/EntryStockBought.vue @@ -116,6 +116,7 @@ const filter = computed(() => ({ hour: 0, minute: 0, second: 0, + milliseconds: 0, }), m3: { neq: null }, }, diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue index e8df27511..c5d79b045 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue @@ -22,7 +22,7 @@ const routes = reactive({ getSupplier: (id) => { return { name: 'SupplierCard', params: { id } }; }, - getTickets: (id) => { + getInvoices: (id) => { return { name: 'InvoiceInList', query: { @@ -131,11 +131,11 @@ async function setInvoiceCorrection(id) { </QBtn> <QBtn size="md" - icon="vn:ticket" + icon="vn:invoice-in" color="primary" - :to="routes.getTickets(entity.supplierFk)" + :to="routes.getInvoices(entity.supplierFk)" > - <QTooltip>{{ t('globals.ticketList') }}</QTooltip> + <QTooltip>{{ t('invoiceIn.descriptor.invoices') }}</QTooltip> </QBtn> <QBtn v-if=" diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue index 20cc1cc71..59bebcae2 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue @@ -25,7 +25,8 @@ const invoiceInFormRef = ref(); const invoiceId = +route.params.id; const filter = { where: { invoiceInFk: invoiceId } }; const areRows = ref(false); -const totals = ref(); +const totalTaxableBase = ref(); +const noMatch = computed(() => totalAmount.value != totalTaxableBase.value); const columns = computed(() => [ { name: 'duedate', @@ -74,9 +75,12 @@ async function insert() { notify(t('globals.dataSaved'), 'positive'); } -onBeforeMount(async () => { - totals.value = (await axios.get(`InvoiceIns/${invoiceId}/getTotals`)).data; -}); +async function setTaxableBase() { + const { data } = await axios.get(`InvoiceIns/${invoiceId}/getTotals`); + totalTaxableBase.value = data.totalTaxableBase; +} + +onBeforeMount(async () => await setTaxableBase()); </script> <template> <CrudModel @@ -89,13 +93,14 @@ onBeforeMount(async () => { :data-required="{ invoiceInFk: invoiceId }" v-model:selected="rowsSelected" @on-fetch="(data) => (areRows = !!data.length)" + @save-changes="setTaxableBase" > <template #body="{ rows }"> <QTable v-model:selected="rowsSelected" selection="multiple" - :columns="columns" - :rows="rows" + :columns + :rows row-key="$index" :grid="$q.screen.lt.sm" > @@ -151,7 +156,18 @@ onBeforeMount(async () => { <QTd /> <QTd /> <QTd> - {{ toCurrency(totalAmount) }} + <QChip + dense + :color="noMatch ? 'negative' : 'transparent'" + class="q-pa-xs" + :title=" + noMatch + ? t('invoiceIn.noMatch', { totalTaxableBase }) + : '' + " + > + {{ toCurrency(totalAmount) }} + </QChip> </QTd> <QTd> <template v-if="isNotEuro(invoiceIn.currency.code)"> @@ -237,7 +253,7 @@ onBeforeMount(async () => { if (!areRows) insert(); else invoiceInFormRef.insert({ - amount: (totals.totalTaxableBase - totalAmount).toFixed(2), + amount: (totalTaxableBase - totalAmount).toFixed(2), invoiceInFk: invoiceId, }); } @@ -249,6 +265,10 @@ onBeforeMount(async () => { .bg { background-color: var(--vn-light-gray); } + +.q-chip { + color: var(--vn-text-color); +} </style> <i18n> es: diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue index dad1da8d6..74936f00a 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue @@ -304,7 +304,10 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; :color="amountsNotMatch ? 'negative' : 'transparent'" :title=" amountsNotMatch - ? t('invoiceIn.summary.noMatch') + ? t('invoiceIn.noMatch', { + totalTaxableBase: + entity.totals.totalTaxableBase, + }) : t('invoiceIn.summary.dueTotal') " > diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue index 9b62fdf6a..10ddcbf05 100644 --- a/src/pages/InvoiceIn/InvoiceInList.vue +++ b/src/pages/InvoiceIn/InvoiceInList.vue @@ -156,7 +156,7 @@ const cols = computed(() => [ :create="{ urlCreate: 'InvoiceIns', title: t('globals.createInvoiceIn'), - onDataSaved: ({ id }) => tableRef.redirect(id), + onDataSaved: ({ id }) => tableRef.redirect(`${id}/basic-data`), formInitialData: { companyFk: user.companyFk, issued: Date.vnNew() }, }" redirect="invoice-in" diff --git a/src/pages/InvoiceIn/InvoiceInToBook.vue b/src/pages/InvoiceIn/InvoiceInToBook.vue index 23175f2e7..28f54f040 100644 --- a/src/pages/InvoiceIn/InvoiceInToBook.vue +++ b/src/pages/InvoiceIn/InvoiceInToBook.vue @@ -56,8 +56,9 @@ async function checkToBook(id) { componentProps: { title: t('Are you sure you want to book this invoice?'), message: messages.reduce((acc, msg) => `${acc}<p>${msg}</p>`, ''), + promise: () => toBook(id), }, - }).onOk(() => toBook(id)); + }); } async function toBook(id) { diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml index 7e3603f0f..a7a8d2469 100644 --- a/src/pages/InvoiceIn/locale/en.yml +++ b/src/pages/InvoiceIn/locale/en.yml @@ -15,6 +15,7 @@ invoiceIn: amount: Amount descriptor: ticketList: Ticket list + invoices: Supplier invoices descriptorMenu: book: Book unbook: Unbook @@ -58,7 +59,6 @@ invoiceIn: bank: Bank foreignValue: Foreign value dueTotal: Due day - noMatch: Do not match code: Code net: Net stems: Stems @@ -69,3 +69,4 @@ invoiceIn: isBooked: Is booked account: Ledger account correctingFk: Rectificative + noMatch: No match with the vat({totalTaxableBase}) diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml index e6ac9273c..c593f5a08 100644 --- a/src/pages/InvoiceIn/locale/es.yml +++ b/src/pages/InvoiceIn/locale/es.yml @@ -14,7 +14,7 @@ invoiceIn: awb: AWB amount: Importe descriptor: - ticketList: Listado de tickets + invoices: Facturas de proveedor descriptorMenu: book: Contabilizar unbook: Descontabilizar @@ -67,3 +67,4 @@ invoiceIn: isBooked: Contabilizada account: Cuenta contable correctingFk: Rectificativa + noMatch: No cuadra con el iva({totalTaxableBase}) diff --git a/src/pages/Item/Card/ItemDescriptorProxy.vue b/src/pages/Item/Card/ItemDescriptorProxy.vue index f686e8221..6e1f6d71f 100644 --- a/src/pages/Item/Card/ItemDescriptorProxy.vue +++ b/src/pages/Item/Card/ItemDescriptorProxy.vue @@ -22,7 +22,7 @@ const $props = defineProps({ }); </script> <template> - <QPopupProxy style="max-width: 10px"> + <QPopupProxy style="max-width: 10px" data-cy="ItemDescriptor"> <ItemDescriptor v-if="$props.id" :id="$props.id" diff --git a/src/pages/Item/ItemListFilter.vue b/src/pages/Item/ItemListFilter.vue index f4500d5fa..ab9b91d06 100644 --- a/src/pages/Item/ItemListFilter.vue +++ b/src/pages/Item/ItemListFilter.vue @@ -7,7 +7,7 @@ import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import VnInput from 'src/components/common/VnInput.vue'; -import { QCheckbox } from 'quasar'; +import VnCheckbox from 'src/components/common/VnCheckbox.vue'; import { useArrayData } from 'composables/useArrayData'; import { useValidator } from 'src/composables/useValidator'; @@ -250,10 +250,9 @@ onMounted(async () => { </QItemSection> </QItem> <!-- Tags filter --> - <QItem class="row items-center"> - <QItemLabel> - {{ t('params.tags') }} - </QItemLabel> + <QItemLabel header> + {{ t('params.tags') }} + <QIcon name="add_circle" class="fill-icon-on-hover q-ml-md" @@ -261,7 +260,7 @@ onMounted(async () => { color="primary" @click="tagValues.push({})" /> - </QItem> + </QItemLabel> <QItem v-for="(tag, index) in tagValues" :key="index" @@ -269,6 +268,7 @@ onMounted(async () => { > <QItemSection class="col"> <VnSelect + class="full-width" :label="t('params.tag')" v-model="tag.selectedTag" :options="tagOptions" @@ -316,25 +316,19 @@ onMounted(async () => { /> </QItem> <!-- Filter fields --> - <QItem class="row items-center"> - <QItemLabel> - {{ t('More fields') }} - </QItemLabel> + <QItemLabel header + >{{ t('More fields') }} <QIcon name="add_circle" class="fill-icon-on-hover q-ml-md" size="sm" color="primary" @click="fieldFiltersValues.push({})" - /> - </QItem> - <QItem - v-for="(fieldFilter, index) in fieldFiltersValues" - :key="index" - class="row items-center" - > + /></QItemLabel> + <QItem v-for="(fieldFilter, index) in fieldFiltersValues" :key="index"> <QItemSection class="col"> <VnSelect + class="full-width" :label="t('params.tag')" :model-value="fieldFilter.selectedField" :options="moreFields" @@ -355,7 +349,7 @@ onMounted(async () => { /> </QItemSection> <QItemSection class="col"> - <QCheckbox + <VnCheckbox v-if="fieldFilter.selectedField?.type === 'boolean'" v-model="fieldFilter.value" :label="t('params.value')" @@ -370,13 +364,14 @@ onMounted(async () => { @keydown.enter="applyFieldFilters(params, searchFn)" /> </QItemSection> - <QIcon - name="delete" - class="fill-icon-on-hover q-ml-xs" - size="sm" - color="primary" - @click="removeFieldFilter(index, params, searchFn)" - /> + <QItemSection side + ><QIcon + name="delete" + class="fill-icon-on-hover q-ml-xs" + size="sm" + color="primary" + @click="removeFieldFilter(index, params, searchFn)" + /></QItemSection> </QItem> <QItem> <QItemSection> diff --git a/src/pages/Login/__tests__/Login.spec.js b/src/pages/Login/__tests__/Login.spec.js index e90a8ee53..b25246f52 100644 --- a/src/pages/Login/__tests__/Login.spec.js +++ b/src/pages/Login/__tests__/Login.spec.js @@ -1,6 +1,7 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import { createWrapper } from 'app/test/vitest/helper'; import Login from 'pages/Login/LoginMain.vue'; +import axios from 'axios'; describe('Login', () => { let vm; diff --git a/src/pages/Monitor/MonitorClients.vue b/src/pages/Monitor/MonitorClients.vue index 278b0b26f..2ba5f4c0b 100644 --- a/src/pages/Monitor/MonitorClients.vue +++ b/src/pages/Monitor/MonitorClients.vue @@ -1,19 +1,22 @@ <script setup> import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; +import DepartmentDescriptorProxy from '../Worker/Department/Card/DepartmentDescriptorProxy.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; import { toDateFormat } from 'src/filters/date.js'; import VnTable from 'src/components/VnTable/VnTable.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnRow from 'src/components/ui/VnRow.vue'; import { dateRange } from 'src/filters'; +import useOpenURL from 'src/composables/useOpenURL'; +import { useState } from 'src/composables/useState'; const { t } = useI18n(); const dates = dateRange(Date.vnNew()); const from = ref(dates[0]); const to = ref(dates[1]); +const state = useState(); const filter = computed(() => { const obj = {}; const formatFrom = setHours(from.value, 'from'); @@ -23,16 +26,18 @@ const filter = computed(() => { if (!formatFrom && formatTo) stamp = { lte: formatTo }; else if (formatFrom && !formatTo) stamp = { gte: formatFrom }; else if (formatFrom && formatTo) stamp = { between: [formatFrom, formatTo] }; - - return Object.assign(obj, { where: { 'v.stamp': stamp } }); + return Object.assign(obj, { + where: { + 'v.stamp': stamp, + 'c.departmentFk': state.getUser().value.departmentFk, + }, + }); }); function exprBuilder(param, value) { switch (param) { case 'clientFk': return { [`c.id`]: value }; - case 'departmentFk': - return { [`c.${param}`]: value }; } } @@ -65,9 +70,13 @@ const columns = computed(() => [ align: 'left', name: 'departmentFk', label: t('customer.summary.team'), - component: 'select', - attrs: { - url: 'Departments', + columnFilter: { + component: 'select', + attrs: { + url: 'Departments', + }, + alias: 'c', + inWhere: true, }, columnField: { component: null, @@ -94,6 +103,7 @@ const columns = computed(() => [ columnClass: 'no-padding', }, ]); +const openTab = (id) => useOpenURL(`#/customer/${id}/summary`); </script> <template> @@ -113,6 +123,8 @@ const columns = computed(() => [ :disable-option="{ card: true }" dense class="q-px-none" + :row-click="({ id }) => openTab(id)" + :row-ctrl-click="(_, { id }) => openTab(id)" > <template #top-left> <VnRow> @@ -121,12 +133,16 @@ const columns = computed(() => [ </VnRow> </template> <template #column-departmentFk="{ row }"> - <span class="link" :title="row.department" v-text="row.department" /> - <WorkerDescriptorProxy :id="row.departmentFk" dense /> + <span @click.stop.prevent class="link" :title="row.department"> + {{ row.department }} + <DepartmentDescriptorProxy :id="row.departmentFk" dense + /></span> </template> <template #column-clientFk="{ row }"> - <span class="link" :title="row.clientName" v-text="row.clientName" /> - <CustomerDescriptorProxy :id="row.clientFk" /> + <span @click.stop.prevent class="link" :title="row.clientName"> + {{ row.clientName }} + <CustomerDescriptorProxy :id="row.clientFk" dense + /></span> </template> </VnTable> </template> diff --git a/src/pages/Monitor/MonitorOrders.vue b/src/pages/Monitor/MonitorOrders.vue index 2679f7224..bdfcf3837 100644 --- a/src/pages/Monitor/MonitorOrders.vue +++ b/src/pages/Monitor/MonitorOrders.vue @@ -9,6 +9,7 @@ import { toDateFormat, toDateTimeFormat } from 'src/filters/date.js'; import { toCurrency } from 'src/filters'; import { useVnConfirm } from 'composables/useVnConfirm'; import axios from 'axios'; +import useOpenURL from 'src/composables/useOpenURL'; const { t } = useI18n(); const { openConfirmationModal } = useVnConfirm(); @@ -108,8 +109,7 @@ const removeOrders = async () => { await table.value.reload(); }; -const openTab = (id) => - window.open(`#/order/${id}/summary`, '_blank', 'noopener, noreferrer'); +const openTab = (id) => useOpenURL(`#/order/${id}/summary`); </script> <template> <VnTable @@ -129,6 +129,7 @@ const openTab = (id) => }" default-mode="table" :row-click="({ id }) => openTab(id)" + :row-ctrl-click="(_, { id }) => openTab(id)" v-model:selected="selectedRows" :disable-option="{ card: true }" > @@ -177,16 +178,16 @@ const openTab = (id) => </template> <template #column-clientFk="{ row }"> - <QTd @click.stop> - <span class="link" v-text="row.clientName" :title="row.clientName" /> - <CustomerDescriptorProxy :id="row.clientFk" /> - </QTd> + <span class="link" @click.stop :title="row.clientName"> + {{ row.clientName }} + <CustomerDescriptorProxy :id="row.clientFk" dense + /></span> </template> <template #column-departmentFk="{ row }"> - <QTd @click.stop> - <span class="link" v-text="row.departmentName" /> - <DepartmentDescriptorProxy :id="row.departmentFk" dense /> - </QTd> + <span class="link" @click.stop :title="row.departmentName"> + {{ row.departmentName }} + <DepartmentDescriptorProxy :id="row.departmentFk" dense + /></span> </template> </VnTable> </template> diff --git a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue index 535906e17..1cadd4cb4 100644 --- a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue +++ b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue @@ -194,19 +194,6 @@ const getLocale = (label) => { /> </QItemSection> </QItem> - <QItem> - <QItemSection> - <VnSelect - dense - filled - :label="t('globals.params.departmentFk')" - v-model="params.department" - option-label="name" - option-value="name" - url="Departments" - /> - </QItemSection> - </QItem> <QItem> <QItemSection> <VnSelect diff --git a/src/pages/Monitor/Ticket/MonitorTickets.vue b/src/pages/Monitor/Ticket/MonitorTickets.vue index 03d751595..b46eb5bfa 100644 --- a/src/pages/Monitor/Ticket/MonitorTickets.vue +++ b/src/pages/Monitor/Ticket/MonitorTickets.vue @@ -449,21 +449,19 @@ const openTab = (id) => useOpenURL(`#/ticket/${id}/sale`); <span :title="row.province" v-text="row.province" /> </template> <template #column-state="{ row }"> - <div @click.stop.prevent> - <div v-if="row.refFk"> - <span class="link">{{ row.refFk }}</span> - <InvoiceOutDescriptorProxy :id="row.invoiceOutId" /> - </div> - <QBadge - v-else - :color="stateColors[row.classColor] || 'transparent'" - :text-color="stateColors[row.classColor] ? 'black' : 'white'" - class="q-pa-sm" - style="font-size: 14px" - > - {{ row.state }} - </QBadge> + <div v-if="row.refFk" @click.stop.prevent> + <span class="link">{{ row.refFk }}</span> + <InvoiceOutDescriptorProxy :id="row.invoiceOutId" /> </div> + <QBadge + v-else + :color="stateColors[row.classColor] || 'transparent'" + :text-color="stateColors[row.classColor] ? 'black' : 'white'" + class="q-pa-sm" + style="font-size: 14px" + > + {{ row.state }} + </QBadge> </template> <template #column-isFragile="{ row }"> <QIcon v-if="row.isFragile" name="local_bar" color="primary" size="sm"> diff --git a/src/pages/Order/Card/OrderFilter.vue b/src/pages/Order/Card/OrderFilter.vue index 609a1215a..5f91153ac 100644 --- a/src/pages/Order/Card/OrderFilter.vue +++ b/src/pages/Order/Card/OrderFilter.vue @@ -130,8 +130,10 @@ en: myTeam: My Team isConfirmed: Order Confirmed showEmpty: Show Empty + departmentFk: Department es: params: + departmentFk: Departamento search: BĂşsqueda clientFk: Cliente agencyModeFk: Agencia diff --git a/src/pages/Route/Agency/Card/AgencyCard.vue b/src/pages/Route/Agency/Card/AgencyCard.vue index c21298470..9fd3fe5e5 100644 --- a/src/pages/Route/Agency/Card/AgencyCard.vue +++ b/src/pages/Route/Agency/Card/AgencyCard.vue @@ -3,5 +3,5 @@ import AgencyDescriptor from 'pages/Route/Agency/Card/AgencyDescriptor.vue'; import VnCard from 'src/components/common/VnCard.vue'; </script> <template> - <VnCard data-key="Agency" url="Agencies" :descriptor="AgencyDescriptor" /> + <VnCard data-key="Agency" url="Agencies" :descriptor="AgencyDescriptor" :filter="{ where: { id: $route.params.id } }" /> </template> diff --git a/src/pages/Route/Roadmap/RoadmapSummary.vue b/src/pages/Route/Roadmap/RoadmapSummary.vue index 0c1c2b903..dcd02d98e 100644 --- a/src/pages/Route/Roadmap/RoadmapSummary.vue +++ b/src/pages/Route/Roadmap/RoadmapSummary.vue @@ -112,12 +112,9 @@ const filter = { :label="t('Trailer Plate')" :value="dashIfEmpty(entity?.trailerPlate)" /> - <VnLv :label="t('Phone')" :value="dashIfEmpty(entity?.phone)"> + <VnLv :label="t('Phone')"> <template #value> - <span> - {{ dashIfEmpty(entity?.phone) }} - <VnLinkPhone :phone-number="entity?.phone" /> - </span> + <VnLinkPhone :phone-number="entity?.phone" /> </template> </VnLv> <VnLv diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue index b905cfde8..c69492836 100644 --- a/src/pages/Route/RouteExtendedList.vue +++ b/src/pages/Route/RouteExtendedList.vue @@ -46,7 +46,6 @@ const columns = computed(() => [ }, isId: true, columnFilter: false, - width: '25px', }, { name: 'workerFk', @@ -142,7 +141,6 @@ const columns = computed(() => [ label: 'm3', cardVisible: true, columnClass: 'shrink', - width: '50px', }, { name: 'started', @@ -150,7 +148,6 @@ const columns = computed(() => [ component: 'time', columnFilter: false, format: ({ started }) => toHour(started), - width: '50px', }, { name: 'finished', @@ -158,7 +155,6 @@ const columns = computed(() => [ component: 'time', columnFilter: false, format: ({ finished }) => toHour(finished), - width: '50px', }, { align: 'right', diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue index f3b9c438c..810157683 100644 --- a/src/pages/Route/RouteList.vue +++ b/src/pages/Route/RouteList.vue @@ -46,7 +46,6 @@ const columns = computed(() => [ condition: () => true, }, columnFilter: false, - width: '25px', }, { align: 'left', @@ -57,7 +56,6 @@ const columns = computed(() => [ cardVisible: true, format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef), columnFilter: false, - width: '100px', }, { label: t('globals.agency'), @@ -100,7 +98,6 @@ const columns = computed(() => [ cardVisible: true, columnFilter: false, format: ({ started }) => toHour(started), - width: '50px', }, { align: 'center', @@ -109,7 +106,6 @@ const columns = computed(() => [ cardVisible: true, columnFilter: false, format: ({ finished }) => toHour(finished), - width: '50px', }, { align: 'left', diff --git a/src/pages/Route/RouteRoadmap.vue b/src/pages/Route/RouteRoadmap.vue index c981b86a5..bdb3d12c4 100644 --- a/src/pages/Route/RouteRoadmap.vue +++ b/src/pages/Route/RouteRoadmap.vue @@ -213,7 +213,7 @@ function exprBuilder(param, value) { }" > <template #advanced-menu> - <RoadmapFilter :dataKey /> + <RoadmapFilter :data-key /> </template> <template #body> <VnTable diff --git a/src/pages/Route/Vehicle/Card/VehicleNotes.vue b/src/pages/Route/Vehicle/Card/VehicleNotes.vue new file mode 100644 index 000000000..0afc3c3ed --- /dev/null +++ b/src/pages/Route/Vehicle/Card/VehicleNotes.vue @@ -0,0 +1,35 @@ +<script setup> +import { computed } from 'vue'; +import { useRoute } from 'vue-router'; +import { useState } from 'src/composables/useState'; +import VnNotes from 'src/components/ui/VnNotes.vue'; + +const route = useRoute(); +const state = useState(); +const user = state.getUser(); +const vehicleId = computed(() => route.params.id); + +const noteFilter = computed(() => { + return { + order: 'created DESC', + where: { vehicleFk: vehicleId.value }, + }; +}); + +const body = { + vehicleFk: vehicleId.value, + workerFk: user.value.id, +}; +</script> + +<template> + <VnNotes + url="vehicleObservations" + :add-note="true" + :filter="noteFilter" + :body="body" + style="overflow-y: auto" + required + deletable + /> +</template> diff --git a/src/pages/Route/locale/en.yml b/src/pages/Route/locale/en.yml index 283b61855..e7e2d691e 100644 --- a/src/pages/Route/locale/en.yml +++ b/src/pages/Route/locale/en.yml @@ -50,7 +50,7 @@ route: agencyAgreement: Agency agreement agencyModeName: Agency route isOwn: Own - isAnyVolumeallowed: Any volume allowed + isAnyVolumeAllowed: Any volume allowed Worker: Worker Agency: Agency Vehicle: Vehicle diff --git a/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue b/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue new file mode 100644 index 000000000..e78a2b238 --- /dev/null +++ b/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue @@ -0,0 +1,14 @@ +<script setup> +import ParkingDescriptor from './ParkingDescriptor.vue'; +import ParkingSummary from './ParkingSummary.vue'; +</script> +<template> + <QPopupProxy style="max-width: 10px"> + <ParkingDescriptor + v-if="$attrs.id" + v-bind="$attrs.id" + :summary="ParkingSummary" + :proxy-render="true" + /> + </QPopupProxy> +</template> diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue index 2863784ab..2511edf11 100644 --- a/src/pages/Supplier/Card/SupplierDescriptor.vue +++ b/src/pages/Supplier/Card/SupplierDescriptor.vue @@ -106,7 +106,7 @@ const getEntryQueryParams = (supplier) => { <QBtn :to="{ name: 'EntryList', - query: { params: JSON.stringify(getEntryQueryParams(entity)) }, + query: { table: JSON.stringify(getEntryQueryParams(entity)) }, }" size="md" icon="vn:entry" diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue index 055c9a0ff..83c621b20 100644 --- a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue +++ b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue @@ -91,7 +91,7 @@ const totalPrice = computed(() => { const totalNewPrice = computed(() => { return rows.value.reduce( (acc, item) => acc + item.component.newPrice * item.quantity, - 0 + 0, ); }); @@ -210,18 +210,18 @@ onMounted(async () => { flat > <template #body-cell-item="{ row }"> - <QTd @click.stop class="link"> - <QBtn flat> + <QTd align="center"> + <span @click.stop class="link"> {{ row.itemFk }} <ItemDescriptorProxy :id="row.itemFk" /> - </QBtn> + </span> </QTd> </template> <template #body-cell-description="{ row }"> <QTd style="min-width: 120px; max-width: 120px"> <div class="column q-pb-xs" style="min-width: 120px"> <span>{{ row.item.name }}</span> - <FetchedTags :item="row.item" class="full-width" /> + <FetchedTags :item="row.item" class="full-width" :columns="6" /> </div> </QTd> </template> diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue index 9d70fea38..61932468c 100644 --- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue +++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue @@ -25,9 +25,7 @@ const { validate } = useValidator(); const { notify } = useNotify(); const router = useRouter(); const { t } = useI18n(); -const canEditZone = useAcl().hasAny([ - { model: 'Ticket', props: 'editZone', accessType: 'WRITE' }, -]); +const canEditZone = useAcl().hasAcl('Ticket', 'editZone', 'WRITE'); const agencyFetchRef = ref(); const warehousesOptions = ref([]); diff --git a/src/pages/Ticket/Card/TicketCreateTracking.vue b/src/pages/Ticket/Card/TicketCreateTracking.vue deleted file mode 100644 index 5c1e916f2..000000000 --- a/src/pages/Ticket/Card/TicketCreateTracking.vue +++ /dev/null @@ -1,59 +0,0 @@ -<script setup> -import { ref } from 'vue'; -import { useRoute } from 'vue-router'; -import { useI18n } from 'vue-i18n'; - -import FormModelPopup from 'components/FormModelPopup.vue'; -import VnRow from 'components/ui/VnRow.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -import FetchData from 'components/FetchData.vue'; - -import { useState } from 'src/composables/useState'; -import VnSelectWorker from 'src/components/common/VnSelectWorker.vue'; - -const emit = defineEmits(['onRequestCreated']); - -const route = useRoute(); -const { t } = useI18n(); -const state = useState(); -const user = state.getUser(); -const stateFetchDataRef = ref(null); -const statesOptions = ref([]); - -const onStateFkChange = (formData) => (formData.userFk = user.value.id); -</script> -<template> - <FetchData - ref="stateFetchDataRef" - url="States" - auto-load - @on-fetch="(data) => (statesOptions = data)" - /> - <FormModelPopup - :title="t('Create tracking')" - url-create="Tickets/state" - model="CreateTicketTracking" - :form-initial-data="{ ticketFk: route.params.id }" - @on-data-saved="() => emit('onRequestCreated')" - > - <template #form-inputs="{ data }"> - <VnRow> - <VnSelect - v-model="data.stateFk" - :label="t('ticketList.state')" - :options="statesOptions" - @update:model-value="onStateFkChange(data)" - hide-selected - option-label="name" - option-value="id" - /> - <VnSelectWorker v-model="data.userFk" :fields="['id', 'name']" /> - </VnRow> - </template> - </FormModelPopup> -</template> - -<i18n> - es: - Create tracking: Crear estado -</i18n> diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue index 2fb305cc3..e721e2d1c 100644 --- a/src/pages/Ticket/Card/TicketSale.vue +++ b/src/pages/Ticket/Card/TicketSale.vue @@ -1,5 +1,5 @@ <script setup> -import { onMounted, ref, computed, watch } from 'vue'; +import { onMounted, ref, computed, watch, inject } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRouter, useRoute } from 'vue-router'; import { useQuasar } from 'quasar'; @@ -25,7 +25,7 @@ import VnTable from 'src/components/VnTable/VnTable.vue'; import VnConfirm from 'src/components/ui/VnConfirm.vue'; import TicketProblems from 'src/components/TicketProblems.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; - +const app = inject('app'); const route = useRoute(); const router = useRouter(); const { t } = useI18n(); @@ -99,6 +99,7 @@ const columns = computed(() => [ align: 'left', label: t('globals.quantity'), name: 'quantity', + class: 'shrink', format: (row) => toCurrency(row.quantity), }, { @@ -187,20 +188,26 @@ const getRowUpdateInputEvents = (sale) => { const resetChanges = async () => { arrayData.fetch({ append: false }); - tableRef.value.reload(); + tableRef.value.CrudModelRef.hasChanges = false; + await tableRef.value.reload(); + selectedRows.value = []; }; const changeQuantity = async (sale) => { if (!sale.itemFk || sale.quantity == null || sale?.originalQuantity === sale.quantity) return; else sale.originalQuantity = sale.quantity; - if (!sale.id) return addSale(sale); + try { + if (!sale.id) await addSale(sale); + } catch (e) { + app.config.errorHandler(e); + return; + } if (await isSalePrepared(sale)) { await confirmUpdate(() => updateQuantity(sale)); } else await updateQuantity(sale); }; - const updateQuantity = async (sale) => { try { let { quantity, id } = sale; @@ -213,7 +220,7 @@ const updateQuantity = async (sale) => { (s) => s.id === sale.id, ); sale.quantity = quantity; - throw e; + app.config.errorHandler(e); } }; @@ -222,24 +229,27 @@ const addSale = async (sale) => { barcode: sale.itemFk, quantity: sale.quantity, }; + try { + const { data } = await axios.post(`tickets/${route.params.id}/addSale`, params); - const { data } = await axios.post(`tickets/${route.params.id}/addSale`, params); + if (!data) return; - if (!data) return; + const newSale = data; + sale.id = newSale.id; + sale.image = newSale.item.image; + sale.subName = newSale.item.subName; + sale.concept = newSale.concept; + sale.quantity = newSale.quantity; + sale.discount = newSale.discount; + sale.price = newSale.price; + sale.item = newSale.item; - const newSale = data; - sale.id = newSale.id; - sale.image = newSale.item.image; - sale.subName = newSale.item.subName; - sale.concept = newSale.concept; - sale.quantity = newSale.quantity; - sale.discount = newSale.discount; - sale.price = newSale.price; - sale.item = newSale.item; - - notify('globals.dataSaved', 'positive'); - sale.isNew = false; - resetChanges(); + notify('globals.dataSaved', 'positive'); + sale.isNew = false; + resetChanges(); + } catch (e) { + app.config.errorHandler(e); + } }; const changeConcept = async (sale) => { if (await isSalePrepared(sale)) { @@ -248,10 +258,14 @@ const changeConcept = async (sale) => { }; const updateConcept = async (sale) => { - const data = { newConcept: sale.concept }; - await axios.post(`Sales/${sale.id}/updateConcept`, data); - notify('globals.dataSaved', 'positive'); - resetChanges(); + try { + const data = { newConcept: sale.concept }; + await axios.post(`Sales/${sale.id}/updateConcept`, data); + notify('globals.dataSaved', 'positive'); + resetChanges(); + } catch (e) { + app.config.errorHandler(e); + } }; const DEFAULT_EDIT = { @@ -262,18 +276,6 @@ const DEFAULT_EDIT = { oldQuantity: null, }; const edit = ref({ ...DEFAULT_EDIT }); -const usesMana = ref(null); - -const getUsesMana = async () => { - const { data } = await axios.get('Sales/usesMana'); - usesMana.value = data; -}; - -const getMana = async () => { - const { data } = await axios.get(`Tickets/${route.params.id}/getDepartmentMana`); - mana.value = data; - await getUsesMana(); -}; const selectedValidSales = computed(() => { if (!sales.value) return; @@ -310,11 +312,15 @@ const changePrice = async (sale) => { } }; const updatePrice = async (sale, newPrice) => { - await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice }); - sale.price = newPrice; - edit.value = { ...DEFAULT_EDIT }; - notify('globals.dataSaved', 'positive'); - resetChanges(); + try { + await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice }); + sale.price = newPrice; + edit.value = { ...DEFAULT_EDIT }; + notify('globals.dataSaved', 'positive'); + resetChanges(); + } catch (e) { + app.config.errorHandler(e); + } }; const changeDiscount = async (sale) => { @@ -337,15 +343,20 @@ const updateDiscounts = async (sales, newDiscount) => { }; const updateDiscount = async (sales, newDiscount = 0) => { - const salesIds = sales.map(({ id }) => id); - const params = { - salesIds, - newDiscount, - manaCode: manaCode.value, - }; - await axios.post(`Tickets/${route.params.id}/updateDiscount`, params); - notify('globals.dataSaved', 'positive'); - resetChanges(); + try { + const salesIds = sales.map(({ id }) => id); + const params = { + salesIds, + newDiscount, + manaCode: manaCode.value, + }; + await axios.post(`Tickets/${route.params.id}/updateDiscount`, params); + notify('globals.dataSaved', 'positive'); + resetChanges(); + } catch (e) { + app.config.errorHandler(e); + return; + } }; const getNewPrice = computed(() => { @@ -367,30 +378,40 @@ const getNewPrice = computed(() => { }); const newOrderFromTicket = async () => { - const { data } = await axios.post(`Orders/newFromTicket`, { - ticketFk: Number(route.params.id), - }); - const routeData = router.resolve({ name: 'OrderCatalog', params: { id: data } }); - window.open(routeData.href, '_blank'); + try { + const { data } = await axios.post(`Orders/newFromTicket`, { + ticketFk: Number(route.params.id), + }); + const routeData = router.resolve({ name: 'OrderCatalog', params: { id: data } }); + window.open(routeData.href, '_blank'); + } catch (e) { + app.config.errorHandler(e); + } }; const goToLog = (saleId) => { router.push({ name: 'TicketLog', - params: { - originId: route.params.id, - changedModel: 'Sale', - changedModelId: saleId, + query: { + logs: JSON.stringify({ + originFk: route.params.id, + changedModel: 'Sale', + changedModelId: saleId, + }), }, }); }; const changeTicketState = async (val) => { - stateBtnDropdownRef.value.hide(); - const params = { ticketFk: route.params.id, code: val }; - await axios.post('Tickets/state', params); - notify('globals.dataSaved', 'positive'); - await resetChanges(); + try { + stateBtnDropdownRef.value.hide(); + const params = { ticketFk: route.params.id, code: val }; + await axios.post('Tickets/state', params); + notify('globals.dataSaved', 'positive'); + resetChanges(); + } catch (e) { + app.config.errorHandler(e); + } }; const removeSelectedSales = () => { @@ -410,10 +431,14 @@ const removeSales = async () => { .forEach((sale) => tableRef.value.CrudModelRef.formData.splice(sale.$index, 1)); if (params.sales.length == 0) return; - await axios.post('Sales/deleteSales', params); - removeSelectedSales(); - notify('globals.dataSaved', 'positive'); - resetChanges(); + try { + await axios.post('Sales/deleteSales', params); + removeSelectedSales(); + notify('globals.dataSaved', 'positive'); + resetChanges(); + } catch (e) { + app.config.errorHandler(e); + } }; const setTransferParams = async () => { @@ -767,7 +792,7 @@ watch( {{ row?.item?.subName.toUpperCase() }} </div> </div> - <FetchedTags v-if="row.item" :item="row.item" :max-length="6" /> + <FetchedTags v-if="row.item" :item="row.item" :columns="6" :max-length="6" /> <QPopupProxy v-if="row.id && isTicketEditable"> <VnInput v-model="row.concept" diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue index 773b0807f..37441b44f 100644 --- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue +++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue @@ -55,13 +55,12 @@ const isClaimable = computed(() => { if (ticket.value) { const landedPlusWeek = new Date(ticket.value.landed); landedPlusWeek.setDate(landedPlusWeek.getDate() + 7); - const createAfterDeadline = acl.hasAny([ - { model: 'Claim', props: 'createAfterDeadline', accessType: 'WRITE' }, - ]); + const createAfterDeadline = acl.hasAcl('Claim', 'createAfterDeadline', 'WRITE'); return landedPlusWeek >= Date.vnNew() || createAfterDeadline; } return false; }); + const sendSms = async (params) => { await axios.post(`Tickets/${ticket.value.id}/sendSms`, params); notify(t('SMS sent'), 'positive'); @@ -230,18 +229,6 @@ const createRefund = async (withWarehouse) => { <QItemLabel>{{ t('Add claim') }}</QItemLabel> </QItemSection> </QItem> - <QItem - v-if="isTicketEditable" - clickable - v-close-popup - v-ripple - @click="setReserved(true)" - data-cy="markAsReservedItem" - > - <QItemSection> - <QItemLabel>{{ t('Mark as reserved') }}</QItemLabel> - </QItemSection> - </QItem> <QItem clickable v-ripple data-cy="ticketSaleRefundItem"> <QItemSection> <QItemLabel>{{ t('Refund') }}</QItemLabel> @@ -287,8 +274,6 @@ es: Recalculate price: Recalcular precio Update discount: Actualizar descuento Add claim: Crear reclamaciĂłn - Mark as reserved: Marcar como reservado - Unmark as reserved: Desmarcar como reservado Refund: Abono with warehouse: con almacĂ©n without warehouse: sin almacĂ©n diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue index 3412b0106..119b867ed 100644 --- a/src/pages/Ticket/Card/TicketSummary.vue +++ b/src/pages/Ticket/Card/TicketSummary.vue @@ -21,6 +21,7 @@ import VnSelect from 'src/components/common/VnSelect.vue'; import VnToSummary from 'src/components/ui/VnToSummary.vue'; import TicketDescriptorMenu from './TicketDescriptorMenu.vue'; import TicketProblems from 'src/components/TicketProblems.vue'; +import VnDropdown from 'src/components/common/VnDropdown.vue'; const route = useRoute(); const { notify } = useNotify(); @@ -40,7 +41,7 @@ const ticket = computed(() => summary.value?.entity); const editableStates = ref([]); const ticketUrl = ref(); const grafanaUrl = 'https://grafana.verdnatura.es'; -const stateBtnDropdownRef = ref(); + const descriptorData = useArrayData('Ticket'); onMounted(async () => { @@ -67,7 +68,6 @@ function isEditable() { } async function changeState(value) { - stateBtnDropdownRef.value?.hide(); const formData = { ticketFk: entityId.value, code: value, @@ -113,25 +113,12 @@ onMounted(async () => { </div> </template> <template #header-right> - <div> - <QBtnDropdown - ref="stateBtnDropdownRef" - color="black" - text-color="white" - :label="t('globals.changeState')" - :disable="!isEditable()" - > - <VnSelect - :options="editableStates" - hide-selected - option-label="name" - option-value="code" - hide-dropdown-icon - focus-on-mount - @update:model-value="changeState" - /> - </QBtnDropdown> - </div> + <VnDropdown + :disable="!isEditable()" + :options="editableStates" + option-value="code" + @change-state="changeState" + /> </template> <template #menu="{ entity }"> <TicketDescriptorMenu :ticket="entity" /> @@ -229,27 +216,23 @@ onMounted(async () => { :value="toDate(entity.landed)" /> <VnLv :label="t('globals.packages')" :value="entity.packages" /> - <VnLv :value="entity.address.phone"> - <template #label> - {{ t('ticket.summary.consigneePhone') }} + <VnLv :label="t('ticket.summary.consigneePhone')"> + <template #value> <VnLinkPhone :phone-number="entity.address.phone" /> </template> </VnLv> - <VnLv :value="entity.address.mobile"> - <template #label> - {{ t('ticket.summary.consigneeMobile') }} + <VnLv :label="t('ticket.summary.consigneeMobile')"> + <template #value> <VnLinkPhone :phone-number="entity.address.mobile" /> </template> </VnLv> - <VnLv :value="entity.client.phone"> - <template #label> - {{ t('ticket.summary.clientPhone') }} + <VnLv :label="t('ticket.summary.clientPhone')"> + <template #value> <VnLinkPhone :phone-number="entity.client.phone" /> </template> </VnLv> - <VnLv :value="entity.client.mobile"> - <template #label> - {{ t('ticket.summary.clientMobile') }} + <VnLv :label="t('ticket.summary.clientMobile')"> + <template #value> <VnLinkPhone :phone-number="entity.client.mobile" /> </template> </VnLv> diff --git a/src/pages/Ticket/Card/TicketTracking.vue b/src/pages/Ticket/Card/TicketTracking.vue index 00610de44..06171366d 100644 --- a/src/pages/Ticket/Card/TicketTracking.vue +++ b/src/pages/Ticket/Card/TicketTracking.vue @@ -1,27 +1,23 @@ <script setup> -import { ref, computed, watch, reactive } from 'vue'; +import { ref, reactive, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; -import TicketCreateTracking from './TicketCreateTracking.vue'; -import VnPaginate from 'components/ui/VnPaginate.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import VnSelectWorker from 'src/components/common/VnSelectWorker.vue'; +import { useState } from 'src/composables/useState'; import { toDateTimeFormat } from 'src/filters/date.js'; +import VnTable from 'src/components/VnTable/VnTable.vue'; +const state = useState(); + +const user = state.getUser(); const route = useRoute(); const { t } = useI18n(); -const createTrackingDialogRef = ref(null); -const paginateRef = ref(null); - -watch( - () => route.params.id, - async (val) => { - paginateFilter.where.ticketFk = val; - paginateRef.value.fetch(); - }, -); - +const tableRef = ref(null); +const onStateFkChange = (formData) => (formData.userFk = user.value.id); const paginateFilter = reactive({ include: [ { @@ -56,75 +52,68 @@ const columns = computed(() => [ name: 'state', field: 'state', align: 'left', - format: (val) => val.name, + format: (row) => row.state?.name, }, { label: t('expedition.worker'), name: 'worker', align: 'left', + field: 'user', }, { label: t('expedition.created'), name: 'created', field: 'created', align: 'left', - format: (val) => toDateTimeFormat(val), + format: ({ created }) => toDateTimeFormat(created), }, ]); - -const openCreateModal = () => createTrackingDialogRef.value.show(); </script> <template> - <QPage class="column items-center q-pa-md"> - <VnPaginate - ref="paginateRef" - data-key="TicketTracking" - :user-filter="paginateFilter" - search-url="table" - url="TicketTrackings" - auto-load - order="created DESC" - :limit="0" - > - <template #body="{ rows }"> - <QTable - :rows="rows" - :columns="columns" - row-key="id" - :pagination="{ rowsPerPage: 0 }" - class="full-width q-mt-md" - :no-data-label="t('globals.noResults')" - > - <template #body-cell-worker="{ row }"> - <QTd> - <QBtn flat class="link" @click.stop> - {{ row.user?.name }} - <WorkerDescriptorProxy :id="row.user?.worker?.id" /> - </QBtn> - </QTd> - </template> - </QTable> - </template> - </VnPaginate> - <QDialog - ref="createTrackingDialogRef" - transition-show="scale" - transition-hide="scale" - > - <TicketCreateTracking @on-request-created="paginateRef.fetch()" /> - </QDialog> - <QPageSticky :offset="[20, 20]"> - <QBtn - @click="openCreateModal()" - color="primary" - fab - icon="add" - v-shortcut="'+'" + <VnTable + ref="tableRef" + :right-search="false" + :column-search="false" + :disable-option="{ card: true, table: true }" + :search-url="false" + :columns="columns" + data-key="TicketTracking" + :user-filter="paginateFilter" + url="TicketTrackings" + auto-load + order="created DESC" + :limit="0" + :without-header="true" + :create="{ + urlCreate: 'Tickets/state', + title: t('Create tracking'), + onDataSaved: () => tableRef.reload(), + formInitialData: { + ticketFk: route.params.id, + }, + }" + > + <template #more-create-dialog="{ data }"> + <VnSelect + url="States" + v-model="data.stateFk" + :label="t('ticketList.state')" + auto-load + @update:model-value="onStateFkChange(data)" + hide-selected /> - <QTooltip class="text-no-wrap"> - {{ t('tracking.addState') }} - </QTooltip> - </QPageSticky> - </QPage> + <VnSelectWorker v-model="data.userFk" :fields="['id', 'name']" /> + </template> + <template #column-worker="{ row }"> + <span class="link" @click.stop> + {{ row.user.name }} + <WorkerDescriptorProxy :id="row.user?.worker?.id" /> + </span> + </template> + </VnTable> </template> +<i18n> + es: + Create tracking: Crear estado +</i18n> diff --git a/src/pages/Ticket/Card/TicketVolume.vue b/src/pages/Ticket/Card/TicketVolume.vue index db78094cf..690ae9063 100644 --- a/src/pages/Ticket/Card/TicketVolume.vue +++ b/src/pages/Ticket/Card/TicketVolume.vue @@ -134,7 +134,7 @@ onMounted(() => (stateStore.rightDrawer = true)); auto-load > <template #column-itemFk="{ row }"> - <span class="link"> + <span class="link" @click.stop> {{ row.itemFk }} <ItemDescriptorProxy :id="row.itemFk" /> </span> diff --git a/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js b/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js index 8fd62d8c2..a1dd7775d 100644 --- a/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js +++ b/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import TicketBoxing from 'pages/Ticket/Card/TicketBoxing.vue'; // #4836 - Investigate how to test q-drawer outside @@ -21,7 +22,11 @@ describe('TicketBoxing', () => { min: 1, max: 2, }; - const videoList = ['2022-01-01T01-01-00.mp4', '2022-02-02T02-02-00.mp4', '2022-03-03T03-03-00.mp4']; + const videoList = [ + '2022-01-01T01-01-00.mp4', + '2022-02-02T02-02-00.mp4', + '2022-03-03T03-03-00.mp4', + ]; vi.spyOn(axios, 'get').mockResolvedValue({ data: videoList }); vi.spyOn(vm.quasar, 'notify'); @@ -44,7 +49,9 @@ describe('TicketBoxing', () => { await vm.getVideoList(expeditionId, timed); - expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'negative' })); + expect(vm.quasar.notify).toHaveBeenCalledWith( + expect.objectContaining({ type: 'negative' }) + ); }); }); }); diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue index b763ef970..d84d1c082 100644 --- a/src/pages/Ticket/TicketFilter.vue +++ b/src/pages/Ticket/TicketFilter.vue @@ -22,16 +22,6 @@ const states = ref([]); const agencies = ref([]); const warehouses = ref([]); const groupedStates = ref([]); - -const getGroupedStates = (data) => { - for (const state of data) { - groupedStates.value.push({ - id: state.id, - name: t(`${state.code}`), - code: state.code, - }); - } -}; </script> <template> @@ -39,12 +29,11 @@ const getGroupedStates = (data) => { <FetchData url="States" @on-fetch="(data) => (states = data)" auto-load /> <FetchData url="AlertLevels" - @on-fetch=" - (data) => { - getGroupedStates(data); - } - " auto-load + @on-fetch=" + (data) => + (groupedStates = data.map((x) => Object.assign(x, { code: t(x.code) }))) + " /> <FetchData url="AgencyModes" @@ -126,12 +115,11 @@ const getGroupedStates = (data) => { </QItemSection> <QItemSection v-if="groupedStates"> <VnSelect - :label="t('Grouped state')" + :label="t('params.groupedStates')" v-model="params.groupedStates" @update:model-value="searchFn()" :options="groupedStates" - option-value="id" - option-label="name" + option-label="code" emit-value map-options use-input @@ -304,7 +292,7 @@ en: ON_PREPARATION: On preparation PACKED: Packed DELIVERED: Delivered - ON_PREVIOUS: ON_PREVIOUS + ON_PREVIOUS: On previous es: params: search: Contiene @@ -349,7 +337,7 @@ es: ON_PREPARATION: En preparaciĂłn PACKED: Encajado DELIVERED: Servido - ON_PREVIOUS: ON_PREVIOUS + ON_PREVIOUS: En previa Collection: ColecciĂłn Nickname: Nombre mostrado </i18n> diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue index 039d3ca9e..634b8e50a 100644 --- a/src/pages/Ticket/TicketList.vue +++ b/src/pages/Ticket/TicketList.vue @@ -113,7 +113,7 @@ const columns = computed(() => [ }, { align: 'left', - name: 'shipped', + name: 'shippedDate', cardVisible: true, label: t('ticketList.shipped'), columnFilter: { @@ -123,7 +123,7 @@ const columns = computed(() => [ }, { align: 'left', - name: 'shipped', + name: 'shippedHour', component: 'time', columnFilter: false, label: t('ticketList.hour'), diff --git a/src/pages/Ticket/__tests__/TicketAdvance.spec.js b/src/pages/Ticket/__tests__/TicketAdvance.spec.js index ab1a47544..cfe5f86c5 100644 --- a/src/pages/Ticket/__tests__/TicketAdvance.spec.js +++ b/src/pages/Ticket/__tests__/TicketAdvance.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import TicketAdvance from 'pages/Ticket/TicketAdvance.vue'; import { Notify } from 'quasar'; import { nextTick } from 'vue'; diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml index 9eb8ce8cb..2e44df7aa 100644 --- a/src/pages/Ticket/locale/en.yml +++ b/src/pages/Ticket/locale/en.yml @@ -205,6 +205,7 @@ ticketList: toLines: Go to lines addressNickname: Address nickname ref: Reference + hour: Hour rounding: Rounding noVerifiedData: No verified data purchaseRequest: Purchase request diff --git a/src/pages/Travel/Card/TravelCard.vue b/src/pages/Travel/Card/TravelCard.vue index 479b47fb9..d452f5287 100644 --- a/src/pages/Travel/Card/TravelCard.vue +++ b/src/pages/Travel/Card/TravelCard.vue @@ -8,6 +8,6 @@ import filter from './TravelFilter.js'; data-key="Travel" url="Travels" :descriptor="TravelDescriptor" - :filter="filter" + :filter="{ ...filter, where: { id: $route.params.id } }" /> </template> diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue index d4903f794..d57046bae 100644 --- a/src/pages/Travel/Card/TravelDescriptor.vue +++ b/src/pages/Travel/Card/TravelDescriptor.vue @@ -66,7 +66,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. :to="{ name: 'TravelList', query: { - params: JSON.stringify({ + table: JSON.stringify({ agencyModeFk: entity.agencyModeFk, }), }, diff --git a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue index 14d824b86..f8828bffe 100644 --- a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue +++ b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue @@ -37,7 +37,7 @@ const cloneTravelWithEntries = async () => { router.push({ name: 'TravelBasicData', params: { id: data.id } }); }; -const canDelete = computed(() => useAcl().hasAny('Travel', '*', 'WRITE')); +const canDelete = computed(() => useAcl().hasAcl('Travel', '*', 'WRITE')); const openDeleteEntryDialog = (id) => { quasar diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue index af6db6304..22e2cff86 100644 --- a/src/pages/Travel/Card/TravelSummary.vue +++ b/src/pages/Travel/Card/TravelSummary.vue @@ -89,6 +89,13 @@ const entriesTableColumns = computed(() => { showValue: true, }, { label: 'CC', field: 'cc', name: 'cc', align: 'left', showValue: true }, + { + label: t('travel.summary.roundedCc'), + field: 'cc', + name: 'roundedCc', + align: 'left', + showValue: true, + }, { label: 'Pallet', field: 'pallet', @@ -191,13 +198,18 @@ const entriesTotals = computed(() => { freightValue: 0, packageValue: 0, cc: 0, + roundedCc: 0, pallet: 0, m3: 0, }; entriesTableRows.value.forEach((row) => { for (const key in totals) { - totals[key] += row[key] || 0; + if (key === 'roundedCc') { + totals['roundedCc'] += Math.ceil(row['cc'] || 0); + } else { + totals[key] += row[key] || 0; + } } }); @@ -206,6 +218,7 @@ const entriesTotals = computed(() => { freight: toCurrency(totals.freightValue), packageValue: toCurrency(totals.packageValue), cc: totals.cc.toFixed(2), + roundedCc: totals.roundedCc, pallet: totals.pallet.toFixed(2), m3: totals.m3.toFixed(2), }; @@ -370,6 +383,11 @@ onMounted(async () => { </QBtn> </QTd> </template> + <template #body-cell-roundedCc="{ col, value }"> + <QTd> + {{ Math.ceil(value) || 0 }} + </QTd> + </template> <template #body-cell-observation="{ value }"> <QTd> <QIcon name="insert_drive_file" color="primary" size="24px"> @@ -386,23 +404,24 @@ onMounted(async () => { <QTd class="text-bold">{{ entriesTotals.freight }}</QTd> <QTd class="text-bold">{{ entriesTotals.packageValue }}</QTd> <QTd class="text-bold">{{ entriesTotals.cc }}</QTd> + <QTd class="text-bold">{{ entriesTotals.roundedCc }}</QTd> <QTd class="text-bold">{{ entriesTotals.pallet }}</QTd> <QTd class="text-bold">{{ entriesTotals.m3 }}</QTd> </template> </QTable> </QCard> - <QCard class="full-width" v-if="thermographs.length > 0"> - <RouterLink - class="header header-link" - :to="{ - name: 'TravelThermographsIndex', - params: { id: travel.id }, - }" - > - {{ t('travel.summary.thermographs') }} - <QIcon name="open_in_new" /> - </RouterLink> + <FetchData + url="Warehouses" + :filter="{ fields: ['id', 'name'] }" + order="name" + @on-fetch="(data) => (warehouses = data)" + auto-load + /> + <VnTitle + :url="getLink('thermographs')" + :text="t('travel.summary.thermographs')" + /> <QTable :rows="thermographs" :columns="thermographsTableColumns" diff --git a/src/pages/Travel/ExtraCommunity.vue b/src/pages/Travel/ExtraCommunity.vue index ac46caa44..849eeee5b 100644 --- a/src/pages/Travel/ExtraCommunity.vue +++ b/src/pages/Travel/ExtraCommunity.vue @@ -18,7 +18,6 @@ import { usePrintService } from 'composables/usePrintService'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import axios from 'axios'; import RightMenu from 'src/components/common/RightMenu.vue'; -import VnPopup from 'src/components/common/VnPopup.vue'; const stateStore = useStateStore(); const { t } = useI18n(); @@ -141,7 +140,6 @@ const columns = computed(() => [ label: 'id', field: 'id', name: 'id', - align: 'center', showValue: true, sortable: true, }, @@ -165,7 +163,7 @@ const columns = computed(() => [ label: t('globals.amount'), name: 'invoiceAmount', field: 'entries', - align: 'left', + align: 'right', showValue: true, sortable: true, format: (value) => @@ -184,13 +182,12 @@ const columns = computed(() => [ align: 'left', showValue: false, sortable: true, - style: 'min-width: 170px;', }, { label: t('globals.packages'), field: 'stickers', name: 'stickers', - align: 'left', + align: 'right', showValue: true, sortable: true, }, @@ -198,7 +195,7 @@ const columns = computed(() => [ label: '%', field: '', name: 'percentage', - align: 'center', + align: 'right', showValue: false, sortable: true, }, @@ -214,7 +211,7 @@ const columns = computed(() => [ label: t('extraCommunity.physicKg'), field: 'loadedKg', name: 'loadedKg', - align: 'left', + align: 'right', showValue: true, sortable: true, }, @@ -222,7 +219,7 @@ const columns = computed(() => [ label: 'KG Vol.', field: 'volumeKg', name: 'volumeKg', - align: 'left', + align: 'right', showValue: true, sortable: true, }, @@ -277,7 +274,6 @@ async function getData() { const onStoreDataChange = () => { const newData = JSON.parse(JSON.stringify(arrayData.store.data)) || []; rows.value = newData; - // el objetivo de esto es guardar una copia de los valores iniciales de todas las rows para corroborar si la data cambio antes de guardar los cambios originalRowDataCopy.value = JSON.parse(JSON.stringify(newData)); }; @@ -300,20 +296,17 @@ const openReportPdf = () => { }; const saveFieldValue = async (val, field, index) => { - // Evitar la solicitud de guardado si el valor no ha cambiado if (originalRowDataCopy.value[index][field] == val) return; const id = rows.value[index].id; const params = { [field]: val }; await axios.patch(`Travels/${id}`, params); - // Actualizar la copia de los datos originales con el nuevo valor originalRowDataCopy.value[index][field] = val; await arrayData.fetch({ append: false }); }; const stopEventPropagation = (event, col) => { - // Detener la propagaciĂłn del evento de los siguientes elementos para evitar el click sobre la row que dispararĂa la funciĂłn navigateToTravelId if (!['ref', 'id', 'cargoSupplierNickname', 'kg'].includes(col.name)) return; event.preventDefault(); event.stopPropagation(); @@ -335,14 +328,12 @@ onMounted(async () => { await getData(); }); -// Handler del evento @dragstart (inicio del drag) y guarda informaciĂłn inicial const handleDragStart = (event, rowIndex, entryIndex) => { draggedRowIndex.value = rowIndex; entryRowIndex.value = entryIndex; event.dataTransfer.effectAllowed = 'move'; }; -// Handler del evento @dragenter (cuando haces drag sobre une elemento y lo arrastras sobre un posible target de drop) y actualiza el targetIndex const handleDragEnter = (_, targetIndex) => { targetRowIndex.value = targetIndex; }; @@ -356,11 +347,8 @@ const saveRowDrop = async (targetRowIndex) => { const moveRow = async (draggedRowIndex, targetRowIndex, entryIndex) => { try { if (draggedRowIndex === targetRowIndex) return; - // Remover entry de la row original draggedEntry.value = rows.value[draggedRowIndex].entries.splice(entryIndex, 1)[0]; - //Si la row de destino por alguna razĂłn no tiene la propiedad entry la creamos if (!rows.value[targetRowIndex].entries) rows.value[targetRowIndex].entries = []; - // Añadir entry a la row de destino rows.value[targetRowIndex].entries.push(draggedEntry.value); await saveRowDrop(targetRowIndex); @@ -370,13 +358,11 @@ const moveRow = async (draggedRowIndex, targetRowIndex, entryIndex) => { } }; -// Handler de cuando haces un drop tanto dentro como fuera de la tabla para limpiar acciones y data const handleDragEnd = () => { stopScroll(); cleanDragAndDropData(); }; -// Handler del evento @drop (cuando soltas el elemento draggeado sobre un target) const handleDrop = () => { if ( !draggedRowIndex.value && @@ -399,7 +385,6 @@ const cleanDragAndDropData = () => { const scrollInterval = ref(null); const startScroll = (direction) => { - // Iniciar el scroll en la direcciĂłn especificada if (!scrollInterval.value) { scrollInterval.value = requestAnimationFrame(() => scroll(direction)); } @@ -413,14 +398,12 @@ const stopScroll = () => { }; const scroll = (direction) => { - // Controlar el desplazamiento en la direcciĂłn especificada const yOffset = direction === 'up' ? -2 : 2; window.scrollBy(0, yOffset); const windowHeight = window.innerHeight; const documentHeight = document.body.offsetHeight; - // Verificar si se alcanzaron los lĂmites de la ventana para detener el desplazamiento if ( (direction === 'up' && window.scrollY > 0) || (direction === 'down' && windowHeight + window.scrollY < documentHeight) @@ -431,13 +414,10 @@ const scroll = (direction) => { } }; -// Handler del scroll mientras se hace el drag de una row const handleDragScroll = (event) => { - // Obtener la posiciĂłn y dimensiones del cursor const y = event.clientY; const windowHeight = window.innerHeight; - // Verificar si el cursor está cerca del borde superior o inferior de la ventana const nearTop = y < 150; const nearBottom = y > windowHeight - 100; @@ -547,7 +527,7 @@ watch(route, () => { ? `${props.row.percentageKg}%` : '-' " - class="text-left q-py-xs q-px-sm" + class="text-right q-py-xs q-px-sm" :color="getColor(props.row.percentageKg)" /> <span @@ -566,7 +546,6 @@ watch(route, () => { ]" v-text="col.value" /> - <!-- Main Row Descriptors --> <TravelDescriptorProxy v-if="col.name === 'id'" :id="props.row.id" @@ -597,58 +576,46 @@ watch(route, () => { index === props.row.entries.length - 1, }" > - <QTd> + <QTd class="text-right"> <QBtn dense flat class="link">{{ entry.id }} </QBtn> <EntryDescriptorProxy :id="entry.id" /> </QTd> - <QTd> - <QBtn flat class="link" dense>{{ entry.supplierName }}</QBtn> - <SupplierDescriptorProxy :id="entry.supplierFk" /> + <QTd :colspan="2"> + <div style="display: flex"> + <span class="link"> + {{ entry.supplierName }} + <SupplierDescriptorProxy :id="entry.supplierFk" /> + </span> + <QIcon + v-if="entry.isCustomInspectionRequired" + name="warning" + color="negative" + size="md" + :title="t('extraCommunity.requiresInspection')" + /> + </div> </QTd> - <QTd> - <QIcon - v-if="entry.isCustomInspectionRequired" - name="warning" - color="negative" - size="md" - :title="t('extraCommunity.requiresInspection')" - > - </QIcon> - </QTd> - <QTd> + <QTd class="text-right"> <span>{{ toCurrency(entry.invoiceAmount) }}</span> </QTd> <QTd> <span>{{ entry.reference }}</span> </QTd> - <QTd> + <QTd class="text-right"> <span>{{ entry.stickers }}</span> </QTd> <QTd /> <QTd></QTd> - <QTd> + <QTd class="text-right"> <span>{{ entry.loadedkg }}</span> </QTd> - <QTd> + <QTd class="text-right"> <span>{{ entry.volumeKg }}</span> </QTd> - <QTd /> - <QTd /> - <QTd /> - <QTd /> - <QTd> - <QBtn - v-if="entry.evaNotes" - icon="comment" - size="md" - flat - color="primary" - > - <VnPopup - :title="t('globals.observations')" - :content="entry.evaNotes" - /> - </QBtn> + <QTd :colspan="5" class="text-right"> + <span> + {{ entry.evaNotes }} + </span> </QTd> </QTr> </template> @@ -662,18 +629,21 @@ watch(route, () => { } :deep(.q-table) { + table-layout: auto; + width: 100%; border-collapse: collapse; + overflow: hidden; + text-overflow: ellipsis; - th { - padding: 0; - } tbody tr td { &:nth-child(1) { max-width: 65px; } - &:nth-child(4) { - padding: 0; - } + padding: 0 5px 0; + } + thead > tr > th { + padding: 3px; + color: var(--vn-label-color); } } diff --git a/src/pages/Travel/TravelFilter.vue b/src/pages/Travel/TravelFilter.vue index a26cc0ec0..5498fd269 100644 --- a/src/pages/Travel/TravelFilter.vue +++ b/src/pages/Travel/TravelFilter.vue @@ -80,7 +80,7 @@ defineExpose({ states }); /> <VnSelect :label="t('travel.warehouseOut')" - v-model="params.warehouseOut" + v-model="params.warehouseOutFk" @update:model-value="searchFn()" url="warehouses" :use-like="false" @@ -128,6 +128,7 @@ en: ref: Reference agency: Agency warehouseInFk: Warehouse In + warehouseOutFk: Warehouse Out shipped: Shipped shipmentHour: Shipment Hour warehouseOut: Warehouse Out @@ -141,6 +142,7 @@ es: ref: Referencia agency: Agencia warehouseInFk: Alm.Entrada + warehouseOutFk: Alm.Salida shipped: F.EnvĂo shipmentHour: Hora de envĂo warehouseOut: Alm.Salida diff --git a/src/pages/Wagon/__tests__/WagonCreate.spec.js b/src/pages/Wagon/__tests__/WagonCreate.spec.js index f195c183f..9be19e027 100644 --- a/src/pages/Wagon/__tests__/WagonCreate.spec.js +++ b/src/pages/Wagon/__tests__/WagonCreate.spec.js @@ -1,5 +1,6 @@ import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest'; -import { createWrapper, axios } from 'app/test/vitest/helper'; +import axios from 'axios'; +import { createWrapper } from 'app/test/vitest/helper'; import WagonCreate from 'pages/Wagon/WagonCreate.vue'; describe('WagonCreate', () => { diff --git a/src/pages/Worker/Card/WorkerCalendar.vue b/src/pages/Worker/Card/WorkerCalendar.vue index df4616011..05ebb4687 100644 --- a/src/pages/Worker/Card/WorkerCalendar.vue +++ b/src/pages/Worker/Card/WorkerCalendar.vue @@ -18,9 +18,7 @@ const router = useRouter(); const route = useRoute(); const { t } = useI18n(); const acl = useAcl(); -const canSeeNotes = computed(() => - acl.hasAny([{ model: 'Worker', props: '__get__business', accessType: 'READ' }]), -); +const canSeeNotes = computed(() => acl.hasAcl('Worker', '__get__business', 'READ')); const workerIsFreelance = ref(); const WorkerFreelanceRef = ref(); const workerCalendarFilterRef = ref(null); diff --git a/src/pages/Worker/Card/WorkerCalendarFilter.vue b/src/pages/Worker/Card/WorkerCalendarFilter.vue index f0e2d758a..32edaa6e9 100644 --- a/src/pages/Worker/Card/WorkerCalendarFilter.vue +++ b/src/pages/Worker/Card/WorkerCalendarFilter.vue @@ -166,50 +166,44 @@ const yearList = ref(generateYears()); }} </QCardSection> </div> - <QList dense class="list q-gutter-y-sm q-my-lg"> - <QItem> - <QItemSection> - <VnSelect - :label="t('Year')" - v-model="selectedYear" - :options="yearList" - dense - filled - use-input - :is-clearable="false" - /> - </QItemSection> - <QItemSection> - <VnSelect - :label="t('Contract')" - v-model="selectedBusinessFk" - :options="contractList" - option-value="businessFk" - option-label="businessFk" - dense - filled - use-input - :is-clearable="false" - > - <template #option="scope"> - <QItem v-bind="scope.itemProps"> - <QItemSection> - <QItemLabel># {{ scope.opt?.businessFk }}</QItemLabel> - <QItemLabel caption> - {{ toDateFormat(scope.opt?.started) }} - - {{ - scope.opt?.ended - ? toDateFormat(scope.opt?.ended) - : 'Indef.' - }} - </QItemLabel> - </QItemSection> - </QItem> - </template> - </VnSelect> - </QItemSection> - </QItem> - </QList> + <div dense class="column q-gutter-y-sm q-px-md"> + <VnSelect + :label="t('Year')" + v-model="selectedYear" + :options="yearList" + dense + filled + use-input + :is-clearable="false" + /> + <VnSelect + :label="t('Contract')" + v-model="selectedBusinessFk" + :options="contractList" + option-value="businessFk" + option-label="businessFk" + dense + filled + use-input + :is-clearable="false" + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel># {{ scope.opt?.businessFk }}</QItemLabel> + <QItemLabel caption> + {{ toDateFormat(scope.opt?.started) }} - + {{ + scope.opt?.ended + ? toDateFormat(scope.opt?.ended) + : 'Indef.' + }} + </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> + </div> <QList dense class="list q-gutter-y-xs q-my-md"> <QItem v-for="type in absenceTypeList" :key="type.id"> <WorkerEventLabel diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue index 060520e84..9576e7e84 100644 --- a/src/pages/Worker/Card/WorkerDescriptor.vue +++ b/src/pages/Worker/Card/WorkerDescriptor.vue @@ -116,7 +116,7 @@ const handlePhotoUpdated = (evt = false) => { <template #body="{ entity }"> <VnLv :label="t('globals.user')" :value="entity.user?.name" /> <VnLv - class="ellipsis-text" + class="ellipsis" :label="t('globals.params.email')" :value="entity.user?.emailUser?.email" copy @@ -128,15 +128,13 @@ const handlePhotoUpdated = (evt = false) => { </template> </VnLv> - <VnLv :value="entity.phone"> - <template #label> - {{ t('globals.phone') }} + <VnLv :label="t('globals.phone')"> + <template #value> <VnLinkPhone :phone-number="entity.phone" /> </template> </VnLv> - <VnLv :value="entity?.sip?.extension"> - <template #label> - {{ t('worker.summary.sipExtension') }} + <VnLv :label="t('worker.summary.sipExtension')"> + <template #value> <VnLinkPhone :phone-number="entity?.sip?.extension" /> </template> </VnLv> diff --git a/src/pages/Worker/Card/WorkerDescriptorProxy.vue b/src/pages/Worker/Card/WorkerDescriptorProxy.vue index 5f71abbea..baa9aa571 100644 --- a/src/pages/Worker/Card/WorkerDescriptorProxy.vue +++ b/src/pages/Worker/Card/WorkerDescriptorProxy.vue @@ -11,7 +11,7 @@ const $props = defineProps({ </script> <template> - <QPopupProxy> + <QPopupProxy data-cy="WorkerDescriptor"> <WorkerDescriptor v-if="$props.id" :id="$props.id" diff --git a/src/pages/Worker/Card/WorkerLocker.vue b/src/pages/Worker/Card/WorkerLocker.vue index 015bced35..62891070d 100644 --- a/src/pages/Worker/Card/WorkerLocker.vue +++ b/src/pages/Worker/Card/WorkerLocker.vue @@ -9,7 +9,7 @@ import VnSelect from 'src/components/common/VnSelect.vue'; import { useArrayData } from 'src/composables/useArrayData'; import FetchData from 'components/FetchData.vue'; -const { hasAny } = useAcl(); +const { hasAcl } = useAcl(); const { t } = useI18n(); const fetchData = ref(); const originaLockerId = ref(); @@ -58,11 +58,7 @@ const init = async (data) => { option-label="code" option-value="id" hide-selected - :readonly=" - !hasAny([ - { model: 'Worker', props: '__get__locker', accessType: 'READ' }, - ]) - " + :readonly="!hasAcl('Worker', '__get__locker', 'READ')" /> </template> </FormModel> diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue index 001eb368a..590cbc2b2 100644 --- a/src/pages/Worker/Card/WorkerPda.vue +++ b/src/pages/Worker/Card/WorkerPda.vue @@ -102,8 +102,8 @@ async function fetchDocuware() { Value: ['PDA'], }, { - DBName: 'FILENAME', - Value: [`${row.deviceProductionFk}-pda`], + DBName: 'OBSERVACIONES', + Value: [row.deviceProductionFk], }, ], }); @@ -234,7 +234,7 @@ function isSigned(row) { data-cy="workerPda-download" > <QTooltip> - {{ t('worker.pda.download') }} + {{ t('globals.downloadPdf') }} </QTooltip> </QBtn> </template> @@ -307,4 +307,5 @@ es: This PDA is already assigned to another user: Este PDA ya está asignado a otro usuario Are you sure you want to send it?: ÂżSeguro que quieres enviarlo? Sign PDA: Firmar PDA + PDF sended to signed: PDF enviado para firmar </i18n> diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index 40787613c..96d5220f5 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -73,28 +73,25 @@ onBeforeMount(async () => { /> </template> </VnLv> - <VnLv :value="worker.mobileExtension"> - <template #label> - {{ t('worker.summary.phoneExtension') }} + <VnLv :label="t('worker.summary.phoneExtension')"> + <template #value> <VnLinkPhone :phone-number="worker.mobileExtension" /> </template> </VnLv> - <VnLv :value="worker.phone"> - <template #label> - {{ t('worker.summary.entPhone') }} + <VnLv :label="t('worker.summary.entPhone')"> + <template #value> <VnLinkPhone :phone-number="worker.phone" /> </template> </VnLv> - <VnLv :value="advancedSummary?.client?.phone"> - <template #label> - {{ t('worker.summary.personalPhone') }} + <VnLv :label="t('worker.summary.personalPhone')"> + <template #value> <VnLinkPhone :phone-number="advancedSummary?.client?.phone" /> </template> </VnLv> </div> - <div class="vn-card-content"> + <div class="vn-card-content" v-if="advancedSummary"> <VnLv :label="t('worker.summary.fiDueDate')" :value="toDate(advancedSummary.fiDueDate)" @@ -135,6 +132,7 @@ onBeforeMount(async () => { <VnTitle :text="t('worker.summary.userData')" /> <VnLv :label="t('globals.name')" :value="worker?.user?.nickname" /> <VnLv + class="ellipsis" :label="t('globals.params.email')" :value="worker.user?.emailUser?.email" copy @@ -147,9 +145,8 @@ onBeforeMount(async () => { </span> </template> </VnLv> - <VnLv :value="worker?.sip?.extension"> - <template #label> - {{ t('worker.summary.sipExtension') }} + <VnLv :label="t('worker.summary.sipExtension')"> + <template #value> <VnLinkPhone :phone-number="worker?.sip?.extension" /> </template> </VnLv> diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index 9c0fa6758..b64166c7d 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -68,13 +68,9 @@ const arrayData = useArrayData('Worker'); const acl = useAcl(); const selectedDateYear = computed(() => moment(selectedDate.value).isoWeekYear()); const worker = computed(() => arrayData.store?.data); -const canSend = computed(() => - acl.hasAny([{ model: 'WorkerTimeControl', props: 'sendMail', accessType: 'WRITE' }]), -); +const canSend = computed(() => acl.hasAcl('WorkerTimeControl', 'sendMail', 'WRITE')); const canUpdate = computed(() => - acl.hasAny([ - { model: 'WorkerTimeControl', props: 'updateMailState', accessType: 'WRITE' }, - ]), + acl.hasAcl('WorkerTimeControl', 'updateMailState', 'WRITE'), ); const isHimself = computed(() => user.value.id === Number(route.params.id)); diff --git a/src/pages/Worker/WorkerFilter.vue b/src/pages/Worker/WorkerFilter.vue index 44dfd32b4..c40afe57e 100644 --- a/src/pages/Worker/WorkerFilter.vue +++ b/src/pages/Worker/WorkerFilter.vue @@ -102,8 +102,11 @@ en: lastName: Last name userName: User extension: Extension + departmentFk: Department es: + params: + departmentFk: Departamento search: Contiene firstName: Nombre lastName: Apellidos diff --git a/src/pages/Zone/Card/ZoneDescriptorProxy.vue b/src/pages/Zone/Card/ZoneDescriptorProxy.vue index 27102ac07..a16d231e6 100644 --- a/src/pages/Zone/Card/ZoneDescriptorProxy.vue +++ b/src/pages/Zone/Card/ZoneDescriptorProxy.vue @@ -11,7 +11,7 @@ const $props = defineProps({ </script> <template> - <QPopupProxy> + <QPopupProxy data-cy="ZoneDescriptor"> <ZoneDescriptor v-if="$props.id" :id="$props.id" :summary="ZoneSummary" /> </QPopupProxy> </template> diff --git a/src/pages/Zone/Card/ZoneSummary.vue b/src/pages/Zone/Card/ZoneSummary.vue index 61475b1f6..5958fe27a 100644 --- a/src/pages/Zone/Card/ZoneSummary.vue +++ b/src/pages/Zone/Card/ZoneSummary.vue @@ -75,13 +75,13 @@ onMounted(async () => { <template #body="{ entity: zone }"> <QCard class="vn-one"> <VnTitle :url="zoneUrl + `basic-data`" :text="t('summary.basicData')" /> - <div class="card-group"> - <div class="card-content"> + <div class="vn-card-group"> + <div class="vn-card-content"> <VnLv :label="t('list.agency')" :value="zone.agencyMode?.name" /> <VnLv :label="t('list.price')" :value="toCurrency(zone.price)" /> <VnLv :label="t('zone.bonus')" :value="toCurrency(zone.bonus)" /> </div> - <div class="card-content"> + <div class="vn-card-content"> <VnLv :label="t('summary.closeHour')" :value="toTimeFormat(zone.hour)" @@ -98,7 +98,7 @@ onMounted(async () => { </div> </div> </QCard> - <QCard class="vn-one"> + <QCard class="vn-max"> <VnTitle :url="zoneUrl + `warehouses`" :text="t('list.warehouse')" /> <QTable :columns="columns" @@ -109,15 +109,3 @@ onMounted(async () => { </template> </CardSummary> </template> - -<style lang="scss" scoped> -.card-group { - display: flex; - flex-direction: column; -} - -.card-content { - display: flex; - flex-direction: column; -} -</style> diff --git a/src/router/__tests__/hooks.spec.js b/src/router/__tests__/hooks.spec.js new file mode 100644 index 000000000..97f5eacdc --- /dev/null +++ b/src/router/__tests__/hooks.spec.js @@ -0,0 +1,36 @@ +import { describe, it, expect, vi } from 'vitest'; +import { ref, nextTick } from 'vue'; +import { stateQueryGuard } from 'src/router/hooks'; +import { useStateQueryStore } from 'src/stores/useStateQueryStore'; + +vi.mock('src/stores/useStateQueryStore', () => { + const isLoading = ref(true); + return { + useStateQueryStore: () => ({ + isLoading: () => isLoading, + setLoading: isLoading, + }), + }; +}); + +describe('hooks', () => { + describe('stateQueryGuard', () => { + const foo = { name: 'foo' }; + it('should wait until the state query is not loading and then call next()', async () => { + const next = vi.fn(); + + stateQueryGuard(foo, { name: 'bar' }, next); + expect(next).not.toHaveBeenCalled(); + + useStateQueryStore().setLoading.value = false; + await nextTick(); + expect(next).toHaveBeenCalled(); + }); + + it('should ignore if both routes are the same', () => { + const next = vi.fn(); + stateQueryGuard(foo, foo, next); + expect(next).toHaveBeenCalled(); + }); + }); +}); diff --git a/src/router/hooks.js b/src/router/hooks.js new file mode 100644 index 000000000..bd9e5334f --- /dev/null +++ b/src/router/hooks.js @@ -0,0 +1,95 @@ +import { useRole } from 'src/composables/useRole'; +import { useUserConfig } from 'src/composables/useUserConfig'; +import { useTokenConfig } from 'src/composables/useTokenConfig'; +import { useAcl } from 'src/composables/useAcl'; +import { isLoggedIn } from 'src/utils/session'; +import { useSession } from 'src/composables/useSession'; +import { useStateQueryStore } from 'src/stores/useStateQueryStore'; +import { watch } from 'vue'; +import { i18n } from 'src/boot/i18n'; + +let session = null; +const { t, te } = i18n.global; + +export async function navigationGuard(to, from, next, Router, state) { + if (!session) session = useSession(); + const outLayout = Router.options.routes[0].children.map((r) => r.name); + if (!session.isLoggedIn() && !outLayout.includes(to.name)) { + return next({ name: 'Login', query: { redirect: to.fullPath } }); + } + + if (isLoggedIn()) { + const stateRoles = state.getRoles().value; + if (stateRoles.length === 0) { + await useRole().fetch(); + await useAcl().fetch(); + await useUserConfig().fetch(); + await useTokenConfig().fetch(); + } + const matches = to.matched; + const hasRequiredAcls = matches.every((route) => { + const meta = route.meta; + if (!meta?.acls) return true; + return useAcl().hasAny(meta.acls); + }); + if (!hasRequiredAcls) return next({ path: '/' }); + } + + next(); +} + +export async function stateQueryGuard(to, from, next) { + if (to.name !== from.name) { + const stateQuery = useStateQueryStore(); + await waitUntilFalse(stateQuery.isLoading()); + } + + next(); +} + +export function setPageTitle(to) { + let title = t(`login.title`); + + const matches = to.matched; + if (matches && matches.length > 1) { + const module = matches[1]; + const moduleTitle = module.meta?.title; + if (moduleTitle) { + title = t(`globals.pageTitles.${moduleTitle}`); + } + } + + const childPage = to.meta; + const childPageTitle = childPage?.title; + if (childPageTitle && matches.length > 2) { + if (title != '') title += ': '; + + const moduleLocale = `globals.pageTitles.${childPageTitle}`; + const pageTitle = te(moduleLocale) + ? t(moduleLocale) + : t(`globals.pageTitles.${childPageTitle}`); + const idParam = to.params?.id; + const idPageTitle = `${idParam} - ${pageTitle}`; + const builtTitle = idParam ? idPageTitle : pageTitle; + + title += builtTitle; + } + + document.title = title; +} + +function waitUntilFalse(ref) { + return new Promise((resolve) => { + if (!ref.value) return resolve(); + const stop = watch( + ref, + (val) => { + if (!val) { + stop(); + resolve(); + } + }, + { immediate: true }, + ); + }); +} diff --git a/src/router/index.js b/src/router/index.js index 4403901cb..628a53c8e 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -6,101 +6,25 @@ import { createWebHashHistory, } from 'vue-router'; import routes from './routes'; -import { i18n } from 'src/boot/i18n'; import { useState } from 'src/composables/useState'; -import { useRole } from 'src/composables/useRole'; -import { useUserConfig } from 'src/composables/useUserConfig'; -import { useTokenConfig } from 'src/composables/useTokenConfig'; -import { useAcl } from 'src/composables/useAcl'; -import { isLoggedIn } from 'src/utils/session'; -import { useSession } from 'src/composables/useSession'; +import { navigationGuard, setPageTitle, stateQueryGuard } from './hooks'; -let session = null; -const { t, te } = i18n.global; - -const createHistory = process.env.SERVER - ? createMemoryHistory - : process.env.VUE_ROUTER_MODE === 'history' - ? createWebHistory - : createWebHashHistory; +const webHistory = + process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory; +const createHistory = process.env.SERVER ? createMemoryHistory : webHistory; const Router = createRouter({ scrollBehavior: () => ({ left: 0, top: 0 }), routes, - - // Leave this as is and make changes in quasar.conf.js instead! - // quasar.conf.js -> build -> vueRouterMode - // quasar.conf.js -> build -> publicPath history: createHistory(process.env.VUE_ROUTER_BASE), }); -/* - * If not building with SSR mode, you can - * directly export the Router instantiation; - * - * The function below can be async too; either use - * async/await or return a Promise which resolves - * with the Router instance. - */ export { Router }; -export default defineRouter(function (/* { store, ssrContext } */) { +export default defineRouter(() => { const state = useState(); - Router.beforeEach(async (to, from, next) => { - if (!session) session = useSession(); - const outLayout = Router.options.routes[0].children.map((r) => r.name); - if (!session.isLoggedIn() && !outLayout.includes(to.name)) { - return next({ name: 'Login', query: { redirect: to.fullPath } }); - } - - if (isLoggedIn()) { - const stateRoles = state.getRoles().value; - if (stateRoles.length === 0) { - await useRole().fetch(); - await useAcl().fetch(); - await useUserConfig().fetch(); - await useTokenConfig().fetch(); - } - const matches = to.matched; - const hasRequiredAcls = matches.every((route) => { - const meta = route.meta; - if (!meta?.acls) return true; - return useAcl().hasAny(meta.acls); - }); - if (!hasRequiredAcls) return next({ path: '/' }); - } - - next(); - }); - - Router.afterEach((to) => { - let title = t(`login.title`); - - const matches = to.matched; - if (matches && matches.length > 1) { - const module = matches[1]; - const moduleTitle = module.meta && module.meta.title; - if (moduleTitle) { - title = t(`globals.pageTitles.${moduleTitle}`); - } - } - - const childPage = to.meta; - const childPageTitle = childPage && childPage.title; - if (childPageTitle && matches.length > 2) { - if (title != '') title += ': '; - - const moduleLocale = `globals.pageTitles.${childPageTitle}`; - const pageTitle = te(moduleLocale) - ? t(moduleLocale) - : t(`globals.pageTitles.${childPageTitle}`); - const idParam = to.params && to.params.id; - const idPageTitle = `${idParam} - ${pageTitle}`; - const builtTitle = idParam ? idPageTitle : pageTitle; - - title += builtTitle; - } - document.title = title; - }); + Router.beforeEach((to, from, next) => navigationGuard(to, from, next, Router, state)); + Router.beforeEach(stateQueryGuard); + Router.afterEach(setPageTitle); Router.onError(({ message }) => { const errorMessages = [ diff --git a/src/router/modules/route.js b/src/router/modules/route.js index 62765a49c..0dd41c86e 100644 --- a/src/router/modules/route.js +++ b/src/router/modules/route.js @@ -166,7 +166,7 @@ const vehicleCard = { component: () => import('src/pages/Route/Vehicle/Card/VehicleCard.vue'), redirect: { name: 'VehicleSummary' }, meta: { - menu: ['VehicleBasicData'], + menu: ['VehicleBasicData', 'VehicleNotes'], }, children: [ { @@ -187,6 +187,15 @@ const vehicleCard = { }, component: () => import('src/pages/Route/Vehicle/Card/VehicleBasicData.vue'), }, + { + name: 'VehicleNotes', + path: 'notes', + meta: { + title: 'notes', + icon: 'vn:notes', + }, + component: () => import('src/pages/Route/Vehicle/Card/VehicleNotes.vue'), + } ], }; @@ -229,6 +238,7 @@ export default { title: 'list', icon: 'view_list', }, + component: () => import('src/pages/Route/RouteList.vue'), }, routeCard, ], @@ -277,6 +287,7 @@ export default { title: 'list', icon: 'view_list', }, + component: () => import('src/pages/Route/RouteRoadmap.vue'), }, roadmapCard, ], @@ -307,6 +318,8 @@ export default { title: 'list', icon: 'view_list', }, + component: () => + import('src/pages/Route/Agency/AgencyList.vue'), }, agencyCard, ], @@ -328,6 +341,8 @@ export default { title: 'vehicleList', icon: 'directions_car', }, + component: () => + import('src/pages/Route/Vehicle/VehicleList.vue'), }, vehicleCard, ], diff --git a/src/stores/__tests__/useArrayDataStore.spec.js b/src/stores/__tests__/useArrayDataStore.spec.js new file mode 100644 index 000000000..79f17cf69 --- /dev/null +++ b/src/stores/__tests__/useArrayDataStore.spec.js @@ -0,0 +1,95 @@ +import { describe, expect, it, beforeEach } from 'vitest'; +import { setActivePinia, createPinia } from 'pinia'; +import { useArrayDataStore } from '../useArrayDataStore'; + +describe('useArrayDataStore', () => { + beforeEach(() => { + setActivePinia(createPinia()); + }); + + it('should get undefined for non-existent key', () => { + const store = useArrayDataStore(); + expect(store.get('nonExistent')).toBeUndefined(); + }); + + it('should set default state for new key', () => { + const store = useArrayDataStore(); + store.set('test'); + const state = store.get('test'); + + expect(state).toMatchObject({ + filter: {}, + userFilter: {}, + userParams: {}, + url: '', + limit: 20, + skip: 0, + order: '', + isLoading: false, + userParamsChanged: false, + exprBuilder: null, + searchUrl: 'params', + navigate: null, + page: 1, + mapKey: 'id', + oneRecord: false, + }); + }); + + it('should clear state for specific key', () => { + const store = useArrayDataStore(); + store.set('test'); + store.clear('test'); + expect(store.get('test')).toBeUndefined(); + }); + + it('should reset all properties when no options provided', () => { + const store = useArrayDataStore(); + store.set('test'); + const state = store.get('test'); + state.limit = 50; + state.page = 3; + + store.reset('test'); + expect(store.get('test').limit).toBe(20); + expect(store.get('test').page).toBe(1); + }); + + it('should reset only specified properties', () => { + const store = useArrayDataStore(); + store.set('test'); + const state = store.get('test'); + state.limit = 50; + state.page = 3; + state.url = 'test-url'; + + store.reset('test', ['limit', 'page']); + expect(state.limit).toBe(20); + expect(state.page).toBe(1); + expect(state.url).toBe('test-url'); + }); + + it('should reset nested properties', () => { + const store = useArrayDataStore(); + store.set('test'); + const state = store.get('test'); + state.filter.skip = 10; + + store.reset('test', ['filter.skip']); + expect(state.filter.skip).toBe(0); + }); + + it('should reset pagination properties', () => { + const store = useArrayDataStore(); + store.set('test'); + const state = store.get('test'); + state.skip = 20; + state.filter.skip = 20; + state.page = 3; + + store.resetPagination('test'); + expect(state.skip).toBe(0); + expect(state.filter.skip).toBe(0); + expect(state.page).toBe(1); + }); +}); diff --git a/src/stores/__tests__/useNavigationStore.spec.js b/src/stores/__tests__/useNavigationStore.spec.js index c5df6157e..120fa64cb 100644 --- a/src/stores/__tests__/useNavigationStore.spec.js +++ b/src/stores/__tests__/useNavigationStore.spec.js @@ -1,15 +1,17 @@ import { setActivePinia, createPinia } from 'pinia'; -import { describe, beforeEach, afterEach, it, expect, vi, beforeAll } from 'vitest'; +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import { useNavigationStore } from '../useNavigationStore'; -import axios from 'axios'; +import { default as axios } from 'axios'; let store; -vi.mock('src/router/modules', () => [ - { name: 'Item', meta: {} }, - { name: 'Shelving', meta: {} }, - { name: 'Order', meta: {} }, -]); +vi.mock('src/router/modules', () => ({ + default: [ + { name: 'Item', meta: {} }, + { name: 'Shelving', meta: {} }, + { name: 'Order', meta: {} }, + ], +})); vi.mock('src/filters', () => ({ toLowerCamel: vi.fn((name) => name.toLowerCase()), diff --git a/src/stores/useArrayDataStore.js b/src/stores/useArrayDataStore.js index b3996d1e3..569ff1c7e 100644 --- a/src/stores/useArrayDataStore.js +++ b/src/stores/useArrayDataStore.js @@ -18,7 +18,6 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => { navigate: null, page: 1, mapKey: 'id', - keepData: false, oneRecord: false, }; diff --git a/src/stores/useDescriptorStore.js b/src/stores/useDescriptorStore.js index a5b83a42e..be342b016 100644 --- a/src/stores/useDescriptorStore.js +++ b/src/stores/useDescriptorStore.js @@ -11,7 +11,7 @@ export const useDescriptorStore = defineStore('descriptorStore', () => { const files = import.meta.glob(`/src/**/*DescriptorProxy.vue`); const moduleParser = { account: 'user', - client: 'customer', + customer: 'client', }; for (const file in files) { const name = file.split('/').at(-1).slice(0, -19).toLowerCase(); diff --git a/test/cypress/cypressParallel.sh b/test/cypress/cypressParallel.sh deleted file mode 100644 index 8ef26bcde..000000000 --- a/test/cypress/cypressParallel.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -find 'test/cypress/integration' \ - -mindepth 1 \ - -maxdepth 1 \ - -type d | \ -xargs -P "$1" -I {} sh -c ' - echo "đź”· {}" && - xvfb-run -a cypress run \ - --headless \ - --spec "{}" \ - --quiet \ - > /dev/null -' -wait diff --git a/test/cypress/docker/cypressParallel.sh b/test/cypress/docker/cypressParallel.sh new file mode 100644 index 000000000..8e253f1e3 --- /dev/null +++ b/test/cypress/docker/cypressParallel.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +echo $2 +if [ -z "$2" ]; then + TEST_DIRS=$(find 'test/cypress/integration' -mindepth 1 -maxdepth 1 -type d) +else + TEST_DIRS=$2 +fi + +echo $TEST_DIRS x$1 + +echo "$TEST_DIRS" | xargs -P "$1" -I {} sh -c ' + echo "đź”· {}" && + xvfb-run -a cypress run \ + --headless \ + --spec "{}" \ + --quiet \ + > /dev/null +' +wait diff --git a/test/cypress/docker/find/find-imports.js b/test/cypress/docker/find/find-imports.js new file mode 100644 index 000000000..39c3ac3eb --- /dev/null +++ b/test/cypress/docker/find/find-imports.js @@ -0,0 +1,52 @@ +import fs from 'fs'; +import { parse } from 'es-module-lexer'; +import { parse as vueParse } from '@vue/compiler-sfc'; +import glob from 'fast-glob'; +import { resolveImportPath, toRelative } from './resolve-import-path.js'; + +const ROUTER_MODULES = 'src/router/modules/'; +const files = await glob(['src/**/*.{vue,js,ts}'], { absolute: true }); +const vueFiles = new Map(); + +export async function findImports(targetFile, visited = new Set(), identation = '') { + if (visited.has(targetFile)) return []; // Avoid infinite loops + visited.add(targetFile); + + const usageFiles = files + .filter((file) => { + let content = fs.readFileSync(file, 'utf8'); + if (file.endsWith('.vue')) { + if (vueFiles.has(file)) { + content = vueFiles.get(file); + } else { + const { descriptor } = vueParse(content); + content = descriptor?.scriptSetup?.content ?? ''; + vueFiles.set(file, content); + } + } + if (!content.trim()) return false; + + return parse(content)[0].some((imp) => { + if (!imp?.n) return false; + return resolveImportPath(imp.n, targetFile) === targetFile; + }); + }) + .map((file) => toRelative(file)); + + let fullTree = [...usageFiles]; + for (const file of usageFiles) { + if (file.startsWith(ROUTER_MODULES)) { + continue; + } + fullTree = [ + ...fullTree, + ...(await findImports(file, visited, identation + ' ')), + ]; + } + + return getUniques(fullTree); // Remove duplicates +} + +function getUniques(array) { + return Array.from(new Set(array)); +} diff --git a/test/cypress/docker/find/find.js b/test/cypress/docker/find/find.js new file mode 100644 index 000000000..b89aab230 --- /dev/null +++ b/test/cypress/docker/find/find.js @@ -0,0 +1,36 @@ +import { execSync } from 'child_process'; +import { findImports } from './find-imports.js'; +import { getModules } from './get-modules.js'; +const E2E_PATH = 'test/cypress/integration'; +const FINDED_PATHS = ['src', E2E_PATH]; + +function getGitDiff(options) { + const TARGET_BRANCH = options[2] || 'dev'; + const diff = execSync(`git diff --name-only origin/${TARGET_BRANCH}`, { + encoding: 'utf-8', + }); + return diff.split('\n'); +} + +async function getChangedModules() { + let changedModules = new Set(); + const changes = getGitDiff(process.argv); + for (const change of changes) { + if (!change) continue; + if (!FINDED_PATHS.some((prefix) => change.startsWith(prefix))) return ''; + const changedArray = [ + ...changedModules, + ...new Set(getModules(await findImports(change))), + ]; + if (change.startsWith(E2E_PATH)) changedArray.push(change); + changedModules = new Set(changedArray); + } + return [...changedModules].join('\n'); +} + +getChangedModules() + .then((modules) => console.log(modules)) // is return + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/test/cypress/docker/find/get-modules.js b/test/cypress/docker/find/get-modules.js new file mode 100644 index 000000000..4ac9ec8c4 --- /dev/null +++ b/test/cypress/docker/find/get-modules.js @@ -0,0 +1,13 @@ +export function getModules(files) { + const CYPRESS_PREFIX = 'test/cypress/integration/'; + const CYPRESS_SUFIX = '/**/*.spec.js'; + const modules = []; + for (const file of files) { + if (file.startsWith('src/page')) { + modules.push( + CYPRESS_PREFIX + file.split('/')[2].toLowerCase() + CYPRESS_SUFIX, + ); + } + } + return modules; +} diff --git a/test/cypress/docker/find/resolve-import-path.js b/test/cypress/docker/find/resolve-import-path.js new file mode 100644 index 000000000..38c225fd2 --- /dev/null +++ b/test/cypress/docker/find/resolve-import-path.js @@ -0,0 +1,34 @@ +import fs from 'fs'; +import path from 'path'; +const rootDir = process.cwd(); +const config = JSON.parse(fs.readFileSync('jsconfig.json', 'utf-8')); +const { paths, baseUrl } = config.compilerOptions; + +function resolveImportPath(importPath, fileBase) { + if (!importPath) return null; + importPath = jsConfigPaths(importPath); + const fileDir = path.dirname(fileBase); + if (importPath.startsWith('.') || importPath.startsWith('/')) { + return path.relative(rootDir, path.resolve(fileDir, importPath)); + } + + return importPath; +} +function toRelative(file) { + return path.relative(rootDir, file); +} + +function jsConfigPaths(importPath) { + for (const [aliasPattern, [target]] of Object.entries(paths)) { + const alias = aliasPattern.replace('/*', ''); + const targetBase = target.replace('/*', ''); + + if (importPath.startsWith(alias)) { + const rest = importPath.slice(alias.length); + return path.resolve(baseUrl, targetBase + rest); + } + } + return importPath; +} + +export { resolveImportPath, toRelative }; diff --git a/test/cypress/run.sh b/test/cypress/docker/run.sh similarity index 89% rename from test/cypress/run.sh rename to test/cypress/docker/run.sh index 0f8c59902..f62f57960 100755 --- a/test/cypress/run.sh +++ b/test/cypress/docker/run.sh @@ -35,6 +35,8 @@ docker build -f ./docs/Dockerfile.dev -t lilium-dev . # END IMAGES docker-compose -p e2e --project-directory . -f test/cypress/docker-compose.yml up -d +files=$(node test/cypress/docker/find/find.js) +echo $files docker run -it --rm \ -v "$(pwd)":/app \ @@ -42,6 +44,6 @@ docker run -it --rm \ -e CI \ -e TZ \ lilium-dev \ - bash -c 'sh test/cypress/cypressParallel.sh 2' + bash -c "sh test/cypress/docker/cypressParallel.sh 2 '$files'" cleanup diff --git a/test/cypress/summary.sh b/test/cypress/docker/summary.sh similarity index 100% rename from test/cypress/summary.sh rename to test/cypress/docker/summary.sh diff --git a/test/cypress/integration/account/accountDescriptorMenu.spec.js b/test/cypress/integration/account/accountDescriptorMenu.spec.js index 67a7d8ef6..04fc57040 100644 --- a/test/cypress/integration/account/accountDescriptorMenu.spec.js +++ b/test/cypress/integration/account/accountDescriptorMenu.spec.js @@ -1,4 +1,4 @@ -describe('ClaimNotes', () => { +describe('Account descriptor', () => { const descriptorOptions = '[data-cy="descriptor-more-opts-menu"] > .q-list'; const url = '/#/account/1/summary'; @@ -7,6 +7,9 @@ describe('ClaimNotes', () => { cy.visit(url); cy.dataCy('descriptor-more-opts').click(); cy.get(descriptorOptions) + .should('exist') + .should('be.visible') + .find('.q-item') .its('length') .then((count) => { diff --git a/test/cypress/integration/client/clientAddress.spec.js b/test/cypress/integration/customer/clientAddress.spec.js similarity index 100% rename from test/cypress/integration/client/clientAddress.spec.js rename to test/cypress/integration/customer/clientAddress.spec.js diff --git a/test/cypress/integration/client/clientBalance.spec.js b/test/cypress/integration/customer/clientBalance.spec.js similarity index 100% rename from test/cypress/integration/client/clientBalance.spec.js rename to test/cypress/integration/customer/clientBalance.spec.js diff --git a/test/cypress/integration/client/clientBasicData.spec.js b/test/cypress/integration/customer/clientBasicData.spec.js similarity index 100% rename from test/cypress/integration/client/clientBasicData.spec.js rename to test/cypress/integration/customer/clientBasicData.spec.js diff --git a/test/cypress/integration/client/clientBillingData.spec.js b/test/cypress/integration/customer/clientBillingData.spec.js similarity index 100% rename from test/cypress/integration/client/clientBillingData.spec.js rename to test/cypress/integration/customer/clientBillingData.spec.js diff --git a/test/cypress/integration/client/clientCredits.spec.js b/test/cypress/integration/customer/clientCredits.spec.js similarity index 100% rename from test/cypress/integration/client/clientCredits.spec.js rename to test/cypress/integration/customer/clientCredits.spec.js diff --git a/test/cypress/integration/client/clientFiscalData.spec.js b/test/cypress/integration/customer/clientFiscalData.spec.js similarity index 100% rename from test/cypress/integration/client/clientFiscalData.spec.js rename to test/cypress/integration/customer/clientFiscalData.spec.js diff --git a/test/cypress/integration/client/clientGreuges.spec.js b/test/cypress/integration/customer/clientGreuges.spec.js similarity index 100% rename from test/cypress/integration/client/clientGreuges.spec.js rename to test/cypress/integration/customer/clientGreuges.spec.js diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/customer/clientList.spec.js similarity index 100% rename from test/cypress/integration/client/clientList.spec.js rename to test/cypress/integration/customer/clientList.spec.js diff --git a/test/cypress/integration/client/clientNotes.spec.js b/test/cypress/integration/customer/clientNotes.spec.js similarity index 100% rename from test/cypress/integration/client/clientNotes.spec.js rename to test/cypress/integration/customer/clientNotes.spec.js diff --git a/test/cypress/integration/client/clientRecoveries.spec.js b/test/cypress/integration/customer/clientRecoveries.spec.js similarity index 100% rename from test/cypress/integration/client/clientRecoveries.spec.js rename to test/cypress/integration/customer/clientRecoveries.spec.js diff --git a/test/cypress/integration/client/clientSms.spec.js b/test/cypress/integration/customer/clientSms.spec.js similarity index 100% rename from test/cypress/integration/client/clientSms.spec.js rename to test/cypress/integration/customer/clientSms.spec.js diff --git a/test/cypress/integration/client/clientWebAccess.spec.js b/test/cypress/integration/customer/clientWebAccess.spec.js similarity index 100% rename from test/cypress/integration/client/clientWebAccess.spec.js rename to test/cypress/integration/customer/clientWebAccess.spec.js diff --git a/test/cypress/integration/client/credit-management/clientCreditContracts.spec.js b/test/cypress/integration/customer/credit-management/clientCreditContracts.spec.js similarity index 100% rename from test/cypress/integration/client/credit-management/clientCreditContracts.spec.js rename to test/cypress/integration/customer/credit-management/clientCreditContracts.spec.js diff --git a/test/cypress/integration/client/credit-management/clientCreditOpinion.spec.js b/test/cypress/integration/customer/credit-management/clientCreditOpinion.spec.js similarity index 100% rename from test/cypress/integration/client/credit-management/clientCreditOpinion.spec.js rename to test/cypress/integration/customer/credit-management/clientCreditOpinion.spec.js diff --git a/test/cypress/integration/client/others/clientConsumption.spec.js b/test/cypress/integration/customer/others/clientConsumption.spec.js similarity index 100% rename from test/cypress/integration/client/others/clientConsumption.spec.js rename to test/cypress/integration/customer/others/clientConsumption.spec.js diff --git a/test/cypress/integration/client/others/clientContacts.spec.js b/test/cypress/integration/customer/others/clientContacts.spec.js similarity index 100% rename from test/cypress/integration/client/others/clientContacts.spec.js rename to test/cypress/integration/customer/others/clientContacts.spec.js diff --git a/test/cypress/integration/client/others/clientMandates.spec.js b/test/cypress/integration/customer/others/clientMandates.spec.js similarity index 100% rename from test/cypress/integration/client/others/clientMandates.spec.js rename to test/cypress/integration/customer/others/clientMandates.spec.js diff --git a/test/cypress/integration/client/others/clientSamples.spec.js b/test/cypress/integration/customer/others/clientSamples.spec.js similarity index 100% rename from test/cypress/integration/client/others/clientSamples.spec.js rename to test/cypress/integration/customer/others/clientSamples.spec.js diff --git a/test/cypress/integration/client/others/clientUnpaid.spec.js b/test/cypress/integration/customer/others/clientUnpaid.spec.js similarity index 100% rename from test/cypress/integration/client/others/clientUnpaid.spec.js rename to test/cypress/integration/customer/others/clientUnpaid.spec.js diff --git a/test/cypress/integration/client/others/clientWebPayments.spec.js b/test/cypress/integration/customer/others/clientWebPayments.spec.js similarity index 100% rename from test/cypress/integration/client/others/clientWebPayments.spec.js rename to test/cypress/integration/customer/others/clientWebPayments.spec.js diff --git a/test/cypress/integration/entry/commands.js b/test/cypress/integration/entry/commands.js index 7c96a5440..4d4a8f980 100644 --- a/test/cypress/integration/entry/commands.js +++ b/test/cypress/integration/entry/commands.js @@ -1,6 +1,6 @@ Cypress.Commands.add('selectTravel', (warehouse = '1') => { cy.get('i[data-cy="Travel_icon"]').click(); - cy.get('input[data-cy="Warehouse Out_select"]').type(warehouse); + cy.selectOption('input[data-cy="Warehouse Out_select"]', warehouse); cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click(); cy.get('button[data-cy="save-filter-travel-form"]').click(); cy.get('tr').eq(1).click(); @@ -9,7 +9,6 @@ Cypress.Commands.add('selectTravel', (warehouse = '1') => { Cypress.Commands.add('deleteEntry', () => { cy.get('[data-cy="descriptor-more-opts"]').should('be.visible').click(); cy.waitForElement('div[data-cy="delete-entry"]').click(); - cy.url().should('include', 'list'); }); Cypress.Commands.add('createEntry', () => { diff --git a/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js b/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js index 554471008..8185866db 100644 --- a/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js +++ b/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js @@ -28,12 +28,8 @@ describe('EntryDescriptor', () => { cy.get('.q-notification__message') .eq(2) .should('have.text', 'Entry prices recalculated'); - - cy.get('[data-cy="descriptor-more-opts"]').click(); cy.deleteEntry(); - cy.log(previousUrl); - cy.visit(previousUrl); cy.waitForElement('[data-cy="entry-buys"]'); diff --git a/test/cypress/integration/entry/entryList.spec.js b/test/cypress/integration/entry/entryList.spec.js index 990f74261..bad47615f 100644 --- a/test/cypress/integration/entry/entryList.spec.js +++ b/test/cypress/integration/entry/entryList.spec.js @@ -44,11 +44,12 @@ describe('EntryList', () => { }, ); - checkBadgeDate( + // fix on task https://redmine.verdnatura.es/issues/8638 + /* checkBadgeDate( 'td[data-col-field="landed"] > div .bg-info', (badgeDate, compareDate) => { expect(badgeDate.getTime()).to.be.lessThan(compareDate.getTime()); }, - ); + ); */ }); }); diff --git a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js index 7058e154c..9744486e0 100644 --- a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js @@ -40,7 +40,7 @@ describe('InvoiceInDescriptor', () => { cy.visit('/#/invoice-in/6/summary'); cy.selectDescriptorOption(5); - cy.dataCy('SendEmailNotifiactionDialogInput_input').type( + cy.dataCy('SendEmailNotificationDialogInput_input').type( '{selectall}jorgito@gmail.mx', ); cy.clickConfirm(); diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js index 6b5d28c70..7254e8909 100644 --- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js @@ -41,12 +41,12 @@ describe('InvoiceInList', () => { cy.fillInForm({ ...mock }, { attr: 'data-cy' }); cy.dataCy('FormModelPopup_save').click(); cy.intercept('GET', /\/api\/InvoiceIns\/\d+\/getTotals$/).as('invoice'); - cy.wait('@invoice').then(() => + cy.wait('@invoice').then(() => { cy.validateDescriptor({ title: mockInvoiceRef, listBox: { 0: '11/16/2001', 3: 'The farmer' }, - }), - ); - cy.get('[data-cy="vnLvCompany"]').should('contain.text', 'ORN'); + }); + cy.dataCy('invoiceInBasicDataCompanyFk').should('have.value', 'ORN'); + }); }); }); diff --git a/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js b/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js index 63e828f55..49eed32c7 100644 --- a/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js +++ b/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js @@ -37,7 +37,7 @@ describe('InvoiceOut summary', () => { }); }); - it('should transfer the invoice ', () => { + it.skip('should transfer the invoice ', () => { cy.typeSearchbar('T1111111{enter}'); cy.dataCy('descriptor-more-opts').click(); cy.get(selectMenuOption(1)).click(); @@ -50,7 +50,7 @@ describe('InvoiceOut summary', () => { cy.dataCy('descriptor-more-opts').click(); cy.get(selectMenuOption(3)).click(); cy.dataCy('InvoiceOutDescriptorMenuSendPdfOption').click(); - cy.dataCy('SendEmailNotifiactionDialogInput').should('be.visible'); + cy.dataCy('SendEmailNotificationDialogInput').should('be.visible'); cy.get(confirmSend).click(); cy.checkNotification('Notification sent'); }); @@ -59,7 +59,7 @@ describe('InvoiceOut summary', () => { cy.dataCy('descriptor-more-opts').click(); cy.get(selectMenuOption(3)).click(); cy.dataCy('InvoiceOutDescriptorMenuSendCsvOption').click(); - cy.dataCy('SendEmailNotifiactionDialogInput').should('be.visible'); + cy.dataCy('SendEmailNotificationDialogInput').should('be.visible'); cy.get(confirmSend).click(); cy.checkNotification('Notification sent'); }); diff --git a/test/cypress/integration/item/itemSummary.spec.js b/test/cypress/integration/item/itemSummary.spec.js index ad8267ecf..8d67c8e3c 100644 --- a/test/cypress/integration/item/itemSummary.spec.js +++ b/test/cypress/integration/item/itemSummary.spec.js @@ -19,6 +19,7 @@ describe('Item summary', () => { cy.get('.q-menu > .q-list > :nth-child(1) > .q-item__section').click(); cy.dataCy('regularizeStockInput').type('10'); cy.dataCy('Warehouse_select').type('Warehouse One{enter}'); + cy.dataCy('FormModelPopup_save').click(); cy.checkNotification('Data created'); }); }); diff --git a/test/cypress/integration/outLogin/login.spec.js b/test/cypress/integration/login/login.spec.js similarity index 100% rename from test/cypress/integration/outLogin/login.spec.js rename to test/cypress/integration/login/login.spec.js diff --git a/test/cypress/integration/outLogin/logout.spec.js b/test/cypress/integration/login/logout.spec.js similarity index 100% rename from test/cypress/integration/outLogin/logout.spec.js rename to test/cypress/integration/login/logout.spec.js diff --git a/test/cypress/integration/outLogin/recoverPassword.spec.js b/test/cypress/integration/login/recoverPassword.spec.js similarity index 100% rename from test/cypress/integration/outLogin/recoverPassword.spec.js rename to test/cypress/integration/login/recoverPassword.spec.js diff --git a/test/cypress/integration/outLogin/twoFactor.spec.js b/test/cypress/integration/login/twoFactor.spec.js similarity index 100% rename from test/cypress/integration/outLogin/twoFactor.spec.js rename to test/cypress/integration/login/twoFactor.spec.js diff --git a/test/cypress/integration/Order/orderCatalog.spec.js b/test/cypress/integration/order/orderCatalog.spec.js similarity index 100% rename from test/cypress/integration/Order/orderCatalog.spec.js rename to test/cypress/integration/order/orderCatalog.spec.js diff --git a/test/cypress/integration/order/orderList.spec.js b/test/cypress/integration/order/orderList.spec.js index 34cd2bffc..ee011ea05 100644 --- a/test/cypress/integration/order/orderList.spec.js +++ b/test/cypress/integration/order/orderList.spec.js @@ -30,9 +30,11 @@ describe('OrderList', () => { cy.url().should('include', `/order`); }); - it.skip('filter list and create order', () => { + it('filter list and create order', () => { cy.dataCy('Customer ID_input').type('1101{enter}'); + cy.intercept('GET', /\/api\/Clients/).as('clientFilter'); cy.dataCy('vnTableCreateBtn').click(); + cy.wait('@clientFilter'); cy.dataCy('landedDate').find('input').type('06/01/2001'); cy.selectOption(agencyCreateSelect, 1); diff --git a/test/cypress/integration/route/agency/agencyModes.spec.js b/test/cypress/integration/route/agency/agencyModes.spec.js new file mode 100644 index 000000000..3f5784997 --- /dev/null +++ b/test/cypress/integration/route/agency/agencyModes.spec.js @@ -0,0 +1,15 @@ +describe('Agency modes', () => { + const name = 'inhouse pickup'; + + beforeEach(() => { + cy.viewport(1920, 1080); + cy.login('developer'); + cy.visit(`/#/route/agency/1/modes`); + }); + + it('should display the agency modes page', () => { + cy.get('.flex > .title').should('have.text', name); + cy.get('.flex > .q-chip > .q-chip__content').should('have.text', 'ID: 1'); + cy.get('.list-items > :nth-child(1) > .value').should('have.text', name); + }); +}); diff --git a/test/cypress/integration/route/routeAutonomous.spec.js b/test/cypress/integration/route/routeAutonomous.spec.js index acf82bd95..d77584c04 100644 --- a/test/cypress/integration/route/routeAutonomous.spec.js +++ b/test/cypress/integration/route/routeAutonomous.spec.js @@ -1,4 +1,4 @@ -describe('RouteAutonomous', () => { +describe.skip('RouteAutonomous', () => { const getLinkSelector = (colField) => `tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`; @@ -49,12 +49,12 @@ describe('RouteAutonomous', () => { cy.get(selectors.firstRowCheckbox).click(); cy.get(selectors.createInvoiceBtn).click(); cy.dataCy(selectors.reference).type(data.reference); + cy.dataCy('attachFile').click(); cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', { force: true, }); - cy.dataCy(selectors.saveFormBtn).click(); + cy.dataCy(selectors.saveFormBtn).should('be.visible').click(); cy.checkNotification(dataSaved); - cy.typeSearchbar('{enter}'); }); it('Should display the total price of the selected rows', () => { diff --git a/test/cypress/integration/route/routeExtendedList.spec.js b/test/cypress/integration/route/routeExtendedList.spec.js index a183c08cb..e6c873d5e 100644 --- a/test/cypress/integration/route/routeExtendedList.spec.js +++ b/test/cypress/integration/route/routeExtendedList.spec.js @@ -53,17 +53,20 @@ describe('Route extended list', () => { function fillField(selector, type, value) { switch (type) { case 'select': - cy.get(selector).should('be.visible').click(); - cy.dataCy('null_select').clear().type(value); + cy.get(selector).should('be.visible').click().clear().type(value); cy.get('.q-item').contains(value).click(); break; case 'input': - cy.get(selector).should('be.visible').click(); - cy.dataCy('null_input').clear().type(`${value}`); + cy.get(selector) + .should('be.visible') + .click() + .type(`{selectall}{backspace}${value}`); break; case 'date': - cy.get(selector).should('be.visible').click(); - cy.dataCy('null_inputDate').clear().type(`${value}`); + cy.get(selector) + .should('be.visible') + .click() + .type(`{selectall}{backspace}${value}`); break; case 'checkbox': cy.get(selector).should('be.visible').click().click(); @@ -103,8 +106,8 @@ describe('Route extended list', () => { cy.fillInForm(data); cy.dataCy(selectors.saveFormBtn).click(); - cy.checkNotification(dataCreated); cy.url().should('include', '/summary'); + cy.checkNotification(dataCreated); }); it('Should reset changed values when click reset button', () => { @@ -140,7 +143,7 @@ describe('Route extended list', () => { const downloadsFolder = Cypress.config('downloadsFolder'); cy.get(selectors.lastRowSelectCheckBox).click(); cy.get(selectors.downloadBtn).click(); - cy.wait(5000); + cy.wait(3000); const fileName = 'download.zip'; cy.readFile(`${downloadsFolder}/${fileName}`).should('exist'); @@ -177,7 +180,7 @@ describe('Route extended list', () => { const [month, day, year] = value.split('/'); value = `${day}/${month}/${year}`; } - cy.validateContent(selector, value); + cy.get(selector).should('contain', value); }); }); diff --git a/test/cypress/integration/route/vehicle/vehicleNotes.spec.js b/test/cypress/integration/route/vehicle/vehicleNotes.spec.js new file mode 100644 index 000000000..cd92cc4af --- /dev/null +++ b/test/cypress/integration/route/vehicle/vehicleNotes.spec.js @@ -0,0 +1,28 @@ +describe('Vehicle Notes', () => { + const selectors = { + addNoteInput: 'Add note here..._input', + saveNoteBtn: 'saveNote', + deleteNoteBtn: 'notesRemoveNoteBtn', + noteCard: '.column.full-width > :nth-child(1) > .q-card__section--vert', + }; + + const noteText = 'Golpe parachoques trasero'; + const newNoteText = 'probando'; + + beforeEach(() => { + cy.viewport(1920, 1080); + cy.login('developer'); + cy.visit(`/#/route/vehicle/1/notes`); + }); + + it('Should add new note', () => { + cy.dataCy(selectors.addNoteInput).should('be.visible').type(newNoteText); + cy.dataCy(selectors.saveNoteBtn).click(); + cy.validateContent(selectors.noteCard, newNoteText); + }); + + it('Should delete note', () => { + cy.dataCy(selectors.deleteNoteBtn).first().should('be.visible').click(); + cy.get(selectors.noteCard).first().should('have.text', noteText); + }); +}); diff --git a/test/cypress/integration/Supplier/SupplierBalance.spec.js b/test/cypress/integration/supplier/SupplierBalance.spec.js similarity index 100% rename from test/cypress/integration/Supplier/SupplierBalance.spec.js rename to test/cypress/integration/supplier/SupplierBalance.spec.js diff --git a/test/cypress/integration/ticket/ticketBasicData.spec.js b/test/cypress/integration/ticket/ticketBasicData.spec.js new file mode 100644 index 000000000..443e9569b --- /dev/null +++ b/test/cypress/integration/ticket/ticketBasicData.spec.js @@ -0,0 +1,46 @@ +/// <reference types="cypress" /> +describe('TicketBasicData', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/31/basic-data'); + }); + + it('Should redirect to customer basic data', () => { + cy.get('.q-page').should('be.visible'); + cy.get(':nth-child(2) > div > .text-primary').click(); + cy.dataCy('Address_select').click(); + cy.get('.q-btn-group ').find('.q-btn__content > .q-icon').click(); + cy.get( + '[data-cy="CustomerBasicData-menu-item"] > .q-item__section--main', + ).click(); + cy.url().should('include', '/customer/1104/basic-data'); + }); + it.only('stepper', () => { + cy.get('.q-stepper__tab--active').should('have.class', 'q-stepper__tab--active'); + + cy.get('.q-stepper__nav > .q-btn--standard').click(); + cy.get('.q-stepper__tab--done').should('have.class', 'q-stepper__tab--done'); + cy.get('.q-stepper__tab--active').should('have.class', 'q-stepper__tab--active'); + cy.get('tr:nth-child(1)>:nth-child(1)>span').should('have.class', 'link').click(); + cy.dataCy('ItemDescriptor').should('exist'); + + cy.get('.q-drawer__content > :nth-child(1)').each(() => { + cy.get('span').should('contain.text', 'Price: €'); + cy.get('span').should('contain.text', 'New price: €'); + cy.get('span').should('contain.text', 'Difference: €'); + }); + cy.get( + ':nth-child(3) > .q-radio > .q-radio__inner > .q-radio__bg > .q-radio__check', + ).should('have.class', 'q-radio__check'); + cy.get( + '.q-stepper__step-inner > .q-drawer-container > .q-drawer > .q-drawer__content', + ).click(); + cy.get(':nth-child(2) > :nth-child(1) > .text-weight-bold').click(); + cy.get(':nth-child(3) > .q-radio > .q-radio__inner').should( + 'have.class', + 'q-radio__inner--truthy', + ); + cy.get('.q-drawer__content > :nth-child(2)').click(); + }); +}); diff --git a/test/cypress/integration/ticket/ticketComponents.spec.js b/test/cypress/integration/ticket/ticketComponents.spec.js new file mode 100644 index 000000000..23dbf8bcd --- /dev/null +++ b/test/cypress/integration/ticket/ticketComponents.spec.js @@ -0,0 +1,30 @@ +/// <reference types="cypress" /> + +describe('TicketComponents', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/1/components'); + }); + it('Should load layout', () => { + cy.get('.q-page').should('be.visible'); + cy.validateScrollContent([ + { row: 2, col: 2, text: 'Base to commission: €799.20' }, + { row: 2, col: 3, text: 'Total without VAT: €807.20' }, + { row: 3, col: 2, text: 'valor de compra: €425.000' }, + { row: 3, col: 4, text: 'maná auto: €7.998' }, + { row: 4, col: 2, text: 'Price: €5.00' }, + { row: 4, col: 3, text: 'Bonus: €1.00' }, + { row: 4, col: 5, text: 'Packages: 6' }, + { row: 4, col: 4, text: 'Zone: Zone pickup A ' }, + { row: 5, col: 2, text: 'Total price: €16.00' }, + ]); + cy.get(':nth-child(4) > .link').click(); + + cy.dataCy('ZoneDescriptor').should('exist'); + cy.getRowCol('total').should('have.text', '€250.000€247.000€4.970'); + cy.getRowCol('import').should('have.text', '€50.000€49.400€0.994'); + cy.getRowCol('components').should('have.text', 'valor de compramargenmaná auto'); + cy.getRowCol('serie').should('have.text', 'costeempresacartera_comercial'); + }); +}); diff --git a/test/cypress/integration/ticket/ticketList.spec.js b/test/cypress/integration/ticket/ticketList.spec.js index 5613a5854..e18025319 100644 --- a/test/cypress/integration/ticket/ticketList.spec.js +++ b/test/cypress/integration/ticket/ticketList.spec.js @@ -1,7 +1,5 @@ /// <reference types="cypress" /> describe('TicketList', () => { - const firstRow = 'tbody.q-virtual-scroll__content tr:nth-child(1)'; - beforeEach(() => { cy.login('developer'); cy.viewport(1920, 1080); @@ -11,7 +9,7 @@ describe('TicketList', () => { const searchResults = (search) => { if (search) cy.typeSearchbar().type(search); cy.dataCy('vn-searchbar').find('input').type('{enter}'); - cy.get(firstRow).should('exist'); + cy.getRow().should('exist'); }; it('should search results', () => { @@ -24,13 +22,13 @@ describe('TicketList', () => { cy.window().then((win) => { cy.stub(win, 'open').as('windowOpen'); }); - cy.get(firstRow).should('be.visible').find('.q-btn:first').click(); + cy.getRow().should('be.visible').find('.q-btn:first').click(); cy.get('@windowOpen').should('be.calledWithMatch', /\/ticket\/\d+\/sale/); }); it('should open ticket summary', () => { searchResults(); - cy.get(firstRow).find('.q-btn:last').click(); + cy.getRow().find('.q-btn:last').click(); cy.get('.summaryHeader').should('exist'); cy.get('.summaryBody').should('exist'); }); @@ -43,8 +41,9 @@ describe('TicketList', () => { cy.dataCy('Customer ID_input').clear('1'); cy.dataCy('Customer ID_input').type('1101{enter}'); - cy.get('[data-cy="vnTableCreateBtn"] > .q-btn__content > .q-icon').click(); - cy.waitSpinner(); + cy.intercept('GET', /\/api\/Clients\?filter/).as('clientFilter'); + cy.vnTableCreateBtn(); + cy.wait('@clientFilter'); cy.dataCy('Customer_select').should('have.value', 'Bruce Wayne'); cy.dataCy('Address_select').click(); @@ -52,8 +51,7 @@ describe('TicketList', () => { cy.dataCy('Address_select').should('have.value', 'Bruce Wayne'); }); it('Client list create new ticket', () => { - cy.dataCy('vnTableCreateBtn').should('exist'); - cy.dataCy('vnTableCreateBtn').click(); + cy.vnTableCreateBtn(); const data = { Customer: { val: 1, type: 'select' }, Warehouse: { val: 'Warehouse One', type: 'select' }, diff --git a/test/cypress/integration/ticket/ticketNotes.spec.js b/test/cypress/integration/ticket/ticketNotes.spec.js index 5b44f9e1f..df1ff9137 100644 --- a/test/cypress/integration/ticket/ticketNotes.spec.js +++ b/test/cypress/integration/ticket/ticketNotes.spec.js @@ -19,7 +19,7 @@ describe('TicketNotes', () => { cy.checkNotification('Data saved'); cy.dataCy('ticketNotesRemoveNoteBtn').should('exist'); cy.dataCy('ticketNotesRemoveNoteBtn').click(); - cy.dataCy('VnConfirm_confirm').click(); + cy.confirmVnConfirm(); cy.checkNotification('Data saved'); }); }); diff --git a/test/cypress/integration/ticket/ticketPackage.spec.js b/test/cypress/integration/ticket/ticketPackage.spec.js new file mode 100644 index 000000000..992efd53b --- /dev/null +++ b/test/cypress/integration/ticket/ticketPackage.spec.js @@ -0,0 +1,21 @@ +/// <reference types="cypress" /> +describe('TicketPackages', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/31/package'); + }); + + it('Should load layout', () => { + cy.get('.q-page').should('be.visible'); + cy.get('.vn-row > .q-btn > .q-btn__content > .q-icon').click(); + cy.dataCy('Package_select').click(); + cy.get('.q-menu :nth-child(1) >.q-item__section').click(); + cy.dataCy('Quantity_input').clear().type('5'); + cy.saveCrudModel(); + cy.checkNotification('Data saved'); + cy.get('.q-mb-md > .text-primary').click(); + cy.confirmVnConfirm(); + cy.checkNotification('Data saved'); + }); +}); diff --git a/test/cypress/integration/ticket/ticketPictures.spec.js b/test/cypress/integration/ticket/ticketPictures.spec.js new file mode 100644 index 000000000..1165b54bf --- /dev/null +++ b/test/cypress/integration/ticket/ticketPictures.spec.js @@ -0,0 +1,18 @@ +/// <reference types="cypress" /> +describe('TicketPictures', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/31/picture'); + }); + it('Should load layout', () => { + cy.get(':nth-child(1) > .q-card > .content').should('be.visible'); + cy.get('.content > .link').should('be.visible').click(); + cy.dataCy('ItemDescriptor').should('exist'); + cy.dataCy('vnLvColor:'); + cy.dataCy('vnLvColor:'); + cy.dataCy('vnLvTallos:'); + cy.get('.q-mt-md').should('be.visible'); + cy.get(':nth-child(1) > .q-card > .img-wrapper').should('be.visible'); + }); +}); diff --git a/test/cypress/integration/ticket/ticketRequest.spec.js b/test/cypress/integration/ticket/ticketRequest.spec.js index b9dc509ef..3b237826e 100644 --- a/test/cypress/integration/ticket/ticketRequest.spec.js +++ b/test/cypress/integration/ticket/ticketRequest.spec.js @@ -7,8 +7,7 @@ describe('TicketRequest', () => { }); it('Creates a new request', () => { - cy.dataCy('vnTableCreateBtn').should('exist'); - cy.dataCy('vnTableCreateBtn').click(); + cy.vnTableCreateBtn(); const data = { Description: { val: 'Purchase description' }, Atender: { val: 'buyerNick', type: 'select' }, diff --git a/test/cypress/integration/ticket/ticketSale.spec.js b/test/cypress/integration/ticket/ticketSale.spec.js index 6d84f214c..f433f0d11 100644 --- a/test/cypress/integration/ticket/ticketSale.spec.js +++ b/test/cypress/integration/ticket/ticketSale.spec.js @@ -2,9 +2,9 @@ const firstRow = 'tbody > :nth-child(1)'; describe('TicketSale', () => { - describe('Ticket #23', () => { + describe('#23', () => { beforeEach(() => { - cy.login('developer'); + cy.login('salesBoss'); cy.viewport(1920, 1080); cy.visit('/#/ticket/23/sale'); }); @@ -16,10 +16,12 @@ describe('TicketSale', () => { cy.waitForElement('[data-cy="ticketEditManaProxy"]'); cy.dataCy('ticketEditManaProxy').should('exist'); cy.waitForElement('[data-cy="Price_input"]'); - cy.dataCy('Price_input').clear(); - cy.dataCy('Price_input').type(price); + cy.dataCy('Price_input').clear().type(price); + cy.intercept('POST', /\/api\/Sales\/\d+\/updatePrice/).as('updatePrice'); + cy.dataCy('saveManaBtn').click(); handleVnConfirm(); + cy.wait('@updatePrice').its('response.statusCode').should('eq', 200); cy.get('[data-col-field="price"]') .find('.q-btn > .q-btn__content') @@ -32,10 +34,14 @@ describe('TicketSale', () => { cy.waitForElement('[data-cy="ticketEditManaProxy"]'); cy.dataCy('ticketEditManaProxy').should('exist'); cy.waitForElement('[data-cy="Disc_input"]'); - cy.dataCy('Disc_input').clear(); - cy.dataCy('Disc_input').type(discount); + cy.dataCy('Disc_input').clear().type(discount); + cy.intercept('POST', /\/api\/Tickets\/\d+\/updateDiscount/).as( + 'updateDiscount', + ); + cy.dataCy('saveManaBtn').click(); handleVnConfirm(); + cy.wait('@updateDiscount').its('response.statusCode').should('eq', 204); cy.get('[data-col-field="discount"]') .find('.q-btn > .q-btn__content') @@ -46,6 +52,8 @@ describe('TicketSale', () => { const concept = Math.floor(Math.random() * 100) + 1; cy.waitForElement(firstRow); cy.get('[data-col-field="item"]').click(); + cy.intercept('POST', '**/api').as('postRequest'); + cy.get('.q-menu') .find('[data-cy="undefined_input"]') .type(concept) @@ -58,6 +66,8 @@ describe('TicketSale', () => { const quantity = Math.floor(Math.random() * 100) + 1; cy.waitForElement(firstRow); cy.dataCy('ticketSaleQuantityInput').find('input').clear(); + cy.intercept('POST', '**/api').as('postRequest'); + cy.dataCy('ticketSaleQuantityInput') .find('input') .type(quantity) @@ -71,7 +81,7 @@ describe('TicketSale', () => { .should('have.value', `${quantity}`); }); }); - describe('Ticket to add claim #24', () => { + describe('#24 add claim', () => { beforeEach(() => { cy.login('developer'); cy.viewport(1920, 1080); @@ -82,15 +92,15 @@ describe('TicketSale', () => { selectFirstRow(); cy.dataCy('ticketSaleMoreActionsDropdown').click(); cy.dataCy('createClaimItem').click(); - cy.dataCy('VnConfirm_confirm').click(); + cy.confirmVnConfirm(); cy.url().should('contain', 'claim/'); // Delete created claim to avoid cluttering the database cy.dataCy('descriptor-more-opts').click(); cy.dataCy('deleteClaim').click(); - cy.dataCy('VnConfirm_confirm').click(); + cy.confirmVnConfirm(); }); }); - describe('Free ticket #31', () => { + describe('#31 free ticket', () => { beforeEach(() => { cy.login('developer'); cy.viewport(1920, 1080); @@ -129,7 +139,9 @@ describe('TicketSale', () => { cy.dataCy('ticketSaleMoreActionsDropdown').should('be.disabled'); }); - it('should update discount when "Update discount" is clicked', () => { + it.only('should update discount when "Update discount" is clicked', () => { + const discount = Number((Math.random() * 99 + 1).toFixed(2)); + selectFirstRow(); cy.dataCy('ticketSaleMoreActionsDropdown').click(); cy.waitForElement('[data-cy="updateDiscountItem"]'); @@ -137,9 +149,13 @@ describe('TicketSale', () => { cy.dataCy('updateDiscountItem').click(); cy.waitForElement('[data-cy="ticketSaleDiscountInput"]'); cy.dataCy('ticketSaleDiscountInput').find('input').focus(); - cy.dataCy('ticketSaleDiscountInput').find('input').type('10'); + cy.intercept('POST', /\/api\/Tickets\/\d+\/updateDiscount/).as( + 'updateDiscount', + ); + cy.dataCy('ticketSaleDiscountInput').find('input').type(discount); + cy.dataCy('saveManaBtn').click(); - cy.waitForElement('.q-notification__message'); + cy.wait('@updateDiscount').its('response.statusCode').should('eq', 204); cy.checkNotification('Data saved'); cy.dataCy('ticketSaleMoreActionsDropdown').should('be.disabled'); }); @@ -148,7 +164,7 @@ describe('TicketSale', () => { selectFirstRow(); cy.dataCy('ticketSaleMoreActionsDropdown').click(); cy.dataCy('createClaimItem').click(); - cy.dataCy('VnConfirm_confirm').click(); + cy.confirmVnConfirm(); cy.checkNotification('Future ticket date not allowed'); }); @@ -173,7 +189,7 @@ describe('TicketSale', () => { cy.url().should('match', /\/ticket\/31\/log/); }); }); - describe('Ticket to transfer #32', () => { + describe('#32 transfer', () => { beforeEach(() => { cy.login('developer'); cy.viewport(1920, 1080); @@ -194,9 +210,7 @@ function selectFirstRow() { cy.get(firstRow).find('.q-checkbox__inner').click(); } function handleVnConfirm() { - cy.get('[data-cy="VnConfirm_confirm"]').click(); - cy.waitForElement('.q-notification__message'); + cy.confirmVnConfirm(); - cy.get('.q-notification__message').should('be.visible'); cy.checkNotification('Data saved'); } diff --git a/test/cypress/integration/ticket/ticketSaleTracking.spec.js b/test/cypress/integration/ticket/ticketSaleTracking.spec.js new file mode 100644 index 000000000..9ee9f8824 --- /dev/null +++ b/test/cypress/integration/ticket/ticketSaleTracking.spec.js @@ -0,0 +1,53 @@ +/// <reference types="cypress" /> +function uncheckedSVG(className, state) { + cy.get(`${className} .q-checkbox__svg`).should( + state === 'checked' ? 'not.have.attr' : 'have.attr', + 'fill', + 'none', + ); +} +function checkedSVG(className, state) { + cy.get(`${className} .q-checkbox__svg> .q-checkbox__truthy`).should( + state === 'checked' ? 'not.have.attr' : 'have.attr', + 'fill', + 'none', + ); +} + +function clickIconAndCloseDialog(n) { + cy.get( + `:nth-child(1) > :nth-child(6) > :nth-child(${n}) > .q-btn__content > .q-icon`, + ).click(); +} + +describe('TicketSaleTracking', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/1/sale-tracking'); + }); + + it('Should load layout', () => { + cy.get('.q-page').should('be.visible'); + // Check checkbox states + uncheckedSVG('.pink', 'checked'); + uncheckedSVG('.cyan', 'checked'); + uncheckedSVG('.warning', 'checked'); + uncheckedSVG('.info', 'checked'); + checkedSVG('.yellow', 'unchecked'); + + cy.get('.q-page').click(); + cy.get( + ':nth-child(1) > :nth-child(6) > :nth-child(2) > .q-btn__content > .q-icon', + ).click(); + cy.get('body').type('{esc}'); + cy.get( + ':nth-child(1) > :nth-child(6) > :nth-child(1) > .q-btn__content > .q-icon', + ).click(); + cy.get( + '.q-dialog__inner > .q-table__container :nth-child(1) > :nth-child(2) .link.q-btn', + ).click(); + + cy.dataCy('WorkerDescriptor').should('exist'); + }); +}); diff --git a/test/cypress/integration/ticket/ticketService.spec.js b/test/cypress/integration/ticket/ticketService.spec.js new file mode 100644 index 000000000..5bf8e2aab --- /dev/null +++ b/test/cypress/integration/ticket/ticketService.spec.js @@ -0,0 +1,23 @@ +/// <reference types="cypress" /> +describe('TicketService', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/31/service'); + }); + + it('Add and remove service', () => { + cy.get('.q-page').should('be.visible'); + cy.addBtnClick(); + cy.dataCy('Description_icon').click(); + cy.dataCy('Description_input').clear().type('test'); + cy.saveFormModel(); + cy.selectOption('[data-cy="Description_select"]', 'test'); + + cy.dataCy('Quantity_input').clear().type('1'); + cy.dataCy('Price_input').clear().type('2'); + cy.saveCrudModel(); + cy.checkNotification('Data saved'); + cy.get(':nth-child(5) > .q-icon').click(); + }); +}); diff --git a/test/cypress/integration/ticket/ticketSms.spec.js b/test/cypress/integration/ticket/ticketSms.spec.js new file mode 100644 index 000000000..feafb2157 --- /dev/null +++ b/test/cypress/integration/ticket/ticketSms.spec.js @@ -0,0 +1,22 @@ +/// <reference types="cypress" /> +describe('TicketSms', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/32/sms'); + }); + + it('Should load layout', () => { + cy.get('.q-page').should('be.visible'); + cy.get('.q-infinite-scroll > :nth-child(1)').should( + 'contain.text', + '0004 444444444Lorem ipsum dolor sit amet, consectetur adipiscing elit.2001-01-01 00:00:00OK', + ); + cy.get( + ':nth-child(1) > .q-item > .q-item__section--top > .column > .q-avatar', + ).should('be.visible'); + cy.get( + ':nth-child(1) > .q-item > .q-item__section--side.justify-center > .center > .q-chip > .q-chip__content', + ).should('have.class', 'q-chip__content'); + }); +}); diff --git a/test/cypress/integration/ticket/ticketTracking.spec.js b/test/cypress/integration/ticket/ticketTracking.spec.js new file mode 100644 index 000000000..f351ee0a1 --- /dev/null +++ b/test/cypress/integration/ticket/ticketTracking.spec.js @@ -0,0 +1,25 @@ +/// <reference types="cypress" /> +describe('Ticket tracking', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/31/tracking'); + }); + + it('Add new tracking', () => { + cy.get('.q-page').should('be.visible'); + + cy.getRowCol('worker').find('span').should('have.class', 'link').click(); + cy.dataCy('WorkerDescriptor').should('exist'); + cy.vnTableCreateBtn(); + cy.selectOption('.q-field--float [data-cy="State_select"]', 'OK').click(); + cy.saveFormModel(); + cy.get( + ':last-child > [data-col-field="state"] > [data-cy="vnTableCell_state"]', + ).should('have.text', 'OK'); + cy.get(':last-child > [data-col-field="worker"]').should( + 'have.text', + 'developer ', + ); + }); +}); diff --git a/test/cypress/integration/ticket/ticketVolume.spec.js b/test/cypress/integration/ticket/ticketVolume.spec.js new file mode 100644 index 000000000..59ff6dcb2 --- /dev/null +++ b/test/cypress/integration/ticket/ticketVolume.spec.js @@ -0,0 +1,27 @@ +/// <reference types="cypress" /> +function checkRightLabel(index, value, tag = 'Volume: ') { + cy.get(`.q-scrollarea__content > :nth-child(${index}) > :nth-child(2) > span`) + .should('be.visible') + .should('have.text', `${tag}${value}`); +} +describe('TicketVolume', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit('/#/ticket/1/volume'); + }); + + it('Check right panel info', () => { + cy.get('.q-page').should('be.visible'); + checkRightLabel(2, '0.028'); + checkRightLabel(3, '0.014'); + checkRightLabel(4, '1.526'); + }); + it('Descriptors', () => { + cy.get(':nth-child(1) > [data-col-field="itemFk"]') + .find('span') + .should('have.class', 'link') + .click(); + cy.dataCy('ItemDescriptor').should('exist'); + }); +}); diff --git a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js b/test/cypress/integration/vnComponent/VnAccountNumber.spec.js deleted file mode 100644 index 053902f35..000000000 --- a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js +++ /dev/null @@ -1,37 +0,0 @@ -describe('VnAccountNumber', () => { - const accountInput = 'input[data-cy="supplierFiscalDataAccount_input"]'; - beforeEach(() => { - cy.login('developer'); - cy.viewport(1920, 1080); - cy.visit('/#/supplier/1/fiscal-data'); - }); - - describe('VnInput handleInsertMode()', () => { - it('should replace character at cursor position in insert mode', () => { - cy.get(accountInput).type('{selectall}4100000001'); - cy.get(accountInput).type('{movetostart}'); - cy.get(accountInput).type('999'); - cy.get(accountInput).should('have.value', '9990000001'); - }); - - it('should replace character at cursor position in insert mode', () => { - cy.get(accountInput).clear(); - cy.get(accountInput).type('4100000001'); - cy.get(accountInput).type('{movetostart}'); - cy.get(accountInput).type('999'); - cy.get(accountInput).should('have.value', '9990000001'); - }); - - it('should respect maxlength prop', () => { - cy.get(accountInput).clear(); - cy.get(accountInput).type('123456789012345'); - cy.get(accountInput).should('have.value', '1234567890'); - }); - }); - - it('should convert short account number to standard format', () => { - cy.get(accountInput).clear(); - cy.get(accountInput).type('123.'); - cy.get(accountInput).should('have.value', '1230000000'); - }); -}); diff --git a/test/cypress/integration/vnComponent/VnLog.spec.js b/test/cypress/integration/vnComponent/VnLog.spec.js index 8ca32b681..57faeac85 100644 --- a/test/cypress/integration/vnComponent/VnLog.spec.js +++ b/test/cypress/integration/vnComponent/VnLog.spec.js @@ -1,26 +1,23 @@ /// <reference types="cypress" /> describe('VnLog', () => { - const chips = [ - ':nth-child(1) > :nth-child(1) > .q-item__label > .q-chip > .q-chip__content', - ':nth-child(2) > :nth-child(1) > .q-item__label > .q-chip > .q-chip__content', - ]; beforeEach(() => { cy.login('developer'); cy.visit(`/#/claim/${1}/log`); - cy.openRightMenu(); }); it('should filter by insert actions', () => { - cy.checkOption(':nth-child(7) > .q-checkbox'); - cy.get('.q-page').click(); - cy.validateContent(chips[0], 'Document'); - cy.validateContent(chips[1], 'Beginning'); + cy.get('[data-cy="vnLog-checkbox"]').eq(0).click(); + cy.get('[data-cy="vnLog-action-icon"]').each(($el) => { + cy.wrap($el).should('have.attr', 'title', 'Creates'); + }); }); it('should filter by entity', () => { - cy.selectOption('.q-drawer--right .q-item > .q-select', 'Claim'); - cy.get('.q-page').click(); - cy.validateContent(chips[0], 'Beginning'); + const entity = 'Document'; + cy.selectOption('[data-cy="vnLog-entity"]', entity); + cy.get('[data-cy="vnLog-model-chip"]').each(($el) => { + cy.wrap($el).should('have.text', entity); + }); }); it('should show claimDescriptor', () => { diff --git a/test/cypress/integration/vnComponent/VnShortcut.spec.js b/test/cypress/integration/vnComponent/VnShortcut.spec.js index e08c44635..cc5cacbe4 100644 --- a/test/cypress/integration/vnComponent/VnShortcut.spec.js +++ b/test/cypress/integration/vnComponent/VnShortcut.spec.js @@ -1,6 +1,6 @@ /// <reference types="cypress" /> - -describe('VnShortcuts', () => { +// https://redmine.verdnatura.es/issues/8848 +describe.skip('VnShortcuts', () => { const modules = { item: 'a', customer: 'c', @@ -27,12 +27,15 @@ describe('VnShortcuts', () => { code: `Key${shortcut.toUpperCase()}`, }); + cy.waitSpinner(); cy.url().should('include', module); if (['monitor', 'claim'].includes(module)) { return; } cy.waitForElement('.q-page').should('exist'); cy.dataCy('vnTableCreateBtn').should('exist'); + cy.waitSpinner(); + cy.get('.q-page').trigger('keydown', { ctrlKey: true, altKey: true, diff --git a/test/cypress/integration/vnComponent/crudModel.commands.js b/test/cypress/integration/vnComponent/crudModel.commands.js new file mode 100644 index 000000000..9d08f064a --- /dev/null +++ b/test/cypress/integration/vnComponent/crudModel.commands.js @@ -0,0 +1,3 @@ +Cypress.Commands.add('saveCrudModel', () => + cy.dataCy('crudModelDefaultSaveBtn').should('exist').click(), +); diff --git a/test/cypress/integration/vnComponent/formModel.commands.js b/test/cypress/integration/vnComponent/formModel.commands.js new file mode 100644 index 000000000..2814b0091 --- /dev/null +++ b/test/cypress/integration/vnComponent/formModel.commands.js @@ -0,0 +1,3 @@ +Cypress.Commands.add('saveFormModel', () => + cy.dataCy('FormModelPopup_save').should('exist').click(), +); diff --git a/test/cypress/integration/vnComponent/vnConfirm.commands.js b/test/cypress/integration/vnComponent/vnConfirm.commands.js new file mode 100644 index 000000000..9f93967d6 --- /dev/null +++ b/test/cypress/integration/vnComponent/vnConfirm.commands.js @@ -0,0 +1,3 @@ +Cypress.Commands.add('confirmVnConfirm', () => + cy.dataCy('VnConfirm_confirm').should('exist').click(), +); diff --git a/test/cypress/integration/vnComponent/vnSelect.commands.js b/test/cypress/integration/vnComponent/vnSelect.commands.js new file mode 100644 index 000000000..017b6e7ea --- /dev/null +++ b/test/cypress/integration/vnComponent/vnSelect.commands.js @@ -0,0 +1,3 @@ +Cypress.Commands.add('clickOption', (index = 1) => + cy.get(`.q-menu :nth-child(${index}) >.q-item__section`).click(), +); diff --git a/test/cypress/integration/vnComponent/vnTable.commands.js b/test/cypress/integration/vnComponent/vnTable.commands.js new file mode 100644 index 000000000..6c7e71e13 --- /dev/null +++ b/test/cypress/integration/vnComponent/vnTable.commands.js @@ -0,0 +1,16 @@ +Cypress.Commands.add('getRow', (index = 1) => + cy.get(`.vnTable .q-virtual-scroll__content tr:nth-child(${index})`), +); +Cypress.Commands.add('getRowCol', (field, index = 1) => + cy.get( + `.vnTable .q-virtual-scroll__content > :nth-child(${index}) > [data-col-field="${field}"]`, + ), +); + +Cypress.Commands.add('vnTableCreateBtn', () => + cy.dataCy('vnTableCreateBtn').should('exist').click(), +); + +Cypress.Commands.add('waitTableScrollLoad', () => + cy.waitForElement('[data-q-vs-anchor]'), +); diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js index 0a45441c1..d964c3dc8 100644 --- a/test/cypress/integration/worker/workerList.spec.js +++ b/test/cypress/integration/worker/workerList.spec.js @@ -1,4 +1,5 @@ -describe('WorkerList', () => { +// https://redmine.verdnatura.es/issues/8848 +describe.skip('WorkerList', () => { const inputName = '.q-drawer .q-form input[aria-label="First Name"]'; const searchBtn = '.q-drawer button:nth-child(3)'; const descriptorTitle = '.descriptor .title span'; @@ -13,7 +14,7 @@ describe('WorkerList', () => { cy.intercept('GET', /\/api\/Workers\/summary+/).as('worker'); cy.get(searchBtn).click(); cy.wait('@worker').then(() => - cy.get(descriptorTitle).should('include.text', 'Jessica') + cy.get(descriptorTitle).should('include.text', 'Jessica'), ); }); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 7f5203547..41f91e855 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -29,7 +29,12 @@ // import { registerCommands } from '@quasar/quasar-app-extension-testing-e2e-cypress'; import moment from 'moment'; import waitUntil from './waitUntil'; +// Importar dinámicamente todos los archivos con el sufijo .commands.js dentro de la carpeta src/test/cypress/integration +const requireCommands = require.context('../integration', true, /\.commands\.js$/); +// Iterar sobre cada archivo y requerirlo +requireCommands.keys().forEach(requireCommands); +// Common comma Cypress.Commands.add('waitUntil', { prevSubject: 'optional' }, waitUntil); Cypress.Commands.add('resetDB', () => { @@ -606,6 +611,11 @@ Cypress.Commands.add('checkQueryParams', (expectedParams = {}) => { }); }); -Cypress.Commands.add('waitTableScrollLoad', () => - cy.waitForElement('[data-q-vs-anchor]'), -); +Cypress.Commands.add('validateScrollContent', (validations) => { + validations.forEach(({ row, col, text }) => { + cy.get(`.q-scrollarea__content > :nth-child(${row}) > :nth-child(${col})`).should( + 'have.text', + text, + ); + }); +}); diff --git a/test/vitest/helper.js b/test/vitest/helper.js index 1e693ab63..be0029ee8 100644 --- a/test/vitest/helper.js +++ b/test/vitest/helper.js @@ -4,7 +4,6 @@ import { createTestingPinia } from '@pinia/testing'; import { vi } from 'vitest'; import { i18n } from 'src/boot/i18n'; import { Notify, Dialog } from 'quasar'; -import axios from 'axios'; import * as useValidator from 'src/composables/useValidator'; installQuasarPlugin({ @@ -41,8 +40,6 @@ vi.mock('vue-router', () => ({ onBeforeRouteLeave: () => {}, })); -vi.mock('axios'); - vi.spyOn(useValidator, 'useValidator').mockImplementation(() => { return { validate: vi.fn(), @@ -112,5 +109,4 @@ export function createWrapper(component, options) { return { vm, wrapper }; } - -export { axios, flushPromises }; +export { flushPromises }; diff --git a/test/vitest/setup-file.js b/test/vitest/setup-file.js index 288f80beb..0ba9e53c2 100644 --- a/test/vitest/setup-file.js +++ b/test/vitest/setup-file.js @@ -1 +1,27 @@ // This file will be run before each test file, don't delete or vitest will not work. +import { vi } from 'vitest'; + +vi.mock('axios'); +vi.mock('vue-router', () => ({ + useRouter: () => ({ + push: vi.fn(), + replace: vi.fn(), + currentRoute: { + value: { + params: { + id: 1, + }, + meta: { moduleName: 'mockName' }, + matched: [{ path: 'mockName/list' }], + }, + }, + }), + useRoute: () => ({ + matched: [], + query: {}, + params: {}, + meta: { moduleName: 'mockName' }, + path: 'mockSection/list', + }), + onBeforeRouteLeave: () => {}, +})); diff --git a/vitest.config.js b/vitest.config.js index f856a1dc9..331d21ef9 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -5,12 +5,11 @@ import jsconfigPaths from 'vite-jsconfig-paths'; import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'; import path from 'path'; -let reporters, - outputFile; +let reporters, outputFile; if (process.env.CI) { reporters = ['junit', 'default']; - outputFile = {junit: './junit/vitest.xml'}; + outputFile = { junit: './junit/vitest.xml' }; } else { reporters = 'default'; } @@ -28,6 +27,9 @@ export default defineConfig({ 'src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', ], }, + server: { + hmr: { overlay: false }, + }, plugins: [ vue({ template: { @@ -39,8 +41,11 @@ export default defineConfig({ sassVariables: 'src/quasar-variables.scss', }), VueI18nPlugin({ + strictMessage: false, + + runtimeOnly: false, include: [ - path.resolve(__dirname, 'src/i18n/**'), + path.resolve(__dirname, 'src/i18n/locale/**'), path.resolve(__dirname, 'src/pages/**/locale/**'), ], }),