diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000000..51882da855 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [ + "Bash(grep -l \"$l\" build/assets/*.js)" + ] + } +} diff --git a/.env.production b/.env.production index 3552083afc..97e12cb9b1 100644 --- a/.env.production +++ b/.env.production @@ -1,4 +1,5 @@ VITE_PUBLIC_URL=/mlrun +VITE_FEDERATION=false VITE_MLRUN_API_URL=${MLRUN_API_PROXY_URL} VITE_MLRUN_V3IO_ACCESS_KEY=${MLRUN_V3IO_ACCESS_KEY} VITE_IGUAZIO_API_URL= diff --git a/.gitignore b/.gitignore index a12895fef4..48a178568b 100755 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ # production /build +.__mf__temp/ +*.tar # misc .DS_Store diff --git a/Dockerfile b/Dockerfile index 428b7a5b7d..e38ba4add5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,12 +13,7 @@ # limitations under the License. # # build stage -# node:20.18.2-alpine used as 20-alpine -FROM quay.io/mlrun/node:20-alpine as build-stage - -RUN apk update && \ - apk upgrade && \ - rm -rf /var/cache/apk/* +FROM quay.io/mlrun/node:20.19.2-slim AS build-stage WORKDIR /app @@ -30,32 +25,30 @@ RUN npm run build ARG COMMIT_HASH ARG DATE -RUN echo ${COMMIT_HASH} > ./build/COMMIT_HASH && \ - echo ${DATE} > ./build/BUILD_DATE +RUN echo "${COMMIT_HASH}" > ./build/COMMIT_HASH && \ + echo "${DATE}" > ./build/BUILD_DATE # production stage -FROM gcr.io/iguazio/nginx-unprivileged:1.21-alpine as production-stage +FROM gcr.io/iguazio/nginx-unprivileged:1.21-alpine AS production-stage -# align UID & GID with nginx-unprivileged image UID & GID ARG UID=101 ARG GID=101 USER root -# escalate permissions to update packages -RUN apk update --no-cache && apk upgrade --no-cache -# we are inheriting $UID and $GID from the base image, you can find more information here: -# https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/Dockerfile-alpine.template +RUN apk update --no-cache && apk upgrade --no-cache \ + && rm -f /etc/nginx/conf.d/default.conf + USER $UID COPY --from=build-stage /app/build /usr/share/nginx/html COPY config.json.tmpl /usr/share/nginx/html/ -RUN rm /etc/nginx/conf.d/default.conf + COPY nginx/nginx.conf.tmpl /etc/nginx/conf.d/ COPY nginx/run_nginx /etc/nginx/ USER root -# update build files permissions so they would be accessible to the running user RUN chown -R $UID:0 /usr/share/nginx/html && chmod -R g+w /usr/share/nginx/html && chmod 777 /etc/nginx/run_nginx + USER $UID EXPOSE 8090 diff --git a/Dockerfile.mf b/Dockerfile.mf new file mode 100644 index 0000000000..3ef084252e --- /dev/null +++ b/Dockerfile.mf @@ -0,0 +1,67 @@ +# Copyright 2019 Iguazio +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# build stage — Module Federation remote +FROM quay.io/mlrun/node:20.19.2-slim AS build-stage + +WORKDIR /app + +COPY package*.json ./ +RUN npm install + +COPY . . + +RUN echo ">>> Building Module Federation remote" && \ + sed -i "/^VITE_FEDERATION=/d" .env.production && \ + echo "VITE_FEDERATION=true" >> .env.production && \ + sed -i "s|^VITE_PUBLIC_URL=/mlrun|VITE_PUBLIC_URL=|" .env.production && \ + echo ">>> Final .env.production:" && grep '^VITE_' .env.production + +RUN npm run build + +ARG COMMIT_HASH +ARG DATE +RUN echo "${COMMIT_HASH}" > ./build/COMMIT_HASH && \ + echo "${DATE}" > ./build/BUILD_DATE + +# production stage +FROM gcr.io/iguazio/nginx-unprivileged:1.21-alpine AS production-stage + +ARG UID=101 +ARG GID=101 + +USER root +RUN apk update --no-cache && apk upgrade --no-cache \ + && rm -f /etc/nginx/conf.d/default.conf + +USER $UID + +COPY --from=build-stage /app/build /usr/share/nginx/html +COPY --from=build-stage /app/.env.production /usr/share/nginx/html/ + +COPY nginx/nginx.conf.mf.tmpl /etc/nginx/conf.d/nginx.conf.tmpl +COPY nginx/run_nginx.mf /etc/nginx/run_nginx + +USER root +RUN INDEX=/usr/share/nginx/html/index.html && \ + [ -f "$INDEX" ] && sed -i 's| +When set to `true`, the image is built in **Module Federation** mode. + ### `docker run` environment variables The Docker container runs a Nginx server, which listens on exposed port number 8090, serves the web-app, and proxies to the backend API. @@ -36,6 +45,7 @@ You can pass the following environment variables to the `docker run` command to | `MLRUN_V3IO_ACCESS_KEY` | Sets the V3IO access key to use for accessing V3IO containers
Example: `a7097c94-6e8f-436d-9717-a84abe2861d1` | | `MLRUN_FUNCTION_CATALOG_URL` | Sets the base URL of the function-template catalog
Default: `https://raw.githubusercontent.com` | | `MLRUN_FUNCTION_CATALOG_PATH` | Sets the base URI of the function-template catalog
Default: `/mlrun/functions/master` | +| `MLRUN_IGZ_UI_ALLOWED_ORIGIN` | Allowed origin for Module Federation and CORS
Example: `https://igz-ui.pini.vmdev90ig4.lab.iguazeng.com` | Example: @@ -71,6 +81,11 @@ This command is run by the Dockerfile that is used by the command [`npm run dock Note: `npm install` should be run first. +### `npm run preview:federation` + +Builds and serves the **mlrun-ui** application in **Module Federation** mode at `http://localhost:5179/`.
+Use this command when developing locally with **igz-ui**, allowing **mlrun-ui** to be consumed as a remote module. + ## Development ### Environment variables diff --git a/config.json.tmpl b/config.json.tmpl index 4784356dd6..3bde3bc9d7 100644 --- a/config.json.tmpl +++ b/config.json.tmpl @@ -1,5 +1,6 @@ { "betaMode": "${MLRUN_BETA_MODE}", "nuclioMode": "${MLRUN_NUCLIO_MODE}", - "nuclioUiUrl": "${MLRUN_NUCLIO_UI_URL}" + "nuclioUiUrl": "${MLRUN_NUCLIO_UI_URL}", + "nuclioRemoteEntryUrl": "${MLRUN_NUCLIO_REMOTE_ENTRY_URL}" } diff --git a/config/loadDevProxyConfig.js b/config/loadDevProxyConfig.js new file mode 100644 index 0000000000..4208bc3239 --- /dev/null +++ b/config/loadDevProxyConfig.js @@ -0,0 +1,57 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +/** + * Dynamically loads the Mlrun proxy configuration for development. + * + * Returns an empty proxy in production. + * In development, it imports the shared `mlrunProxyConfig` function + * from the `iguazio.dashboard-react-controls` package and validates its export. + * + * Node cannot use the aliased import + * (`import { mlrunProxyConfig } from 'igz-controls/utils/proxyServerConfig.util'`) + * since Vite path aliases are resolved only at build time, + * not during Node's module execution. + */ +import path from 'path' +import { pathToFileURL } from 'url' + +export const loadMlrunProxyConfig = async mode => { + const modulePath = path.resolve( + 'node_modules/iguazio.dashboard-react-controls/dist/utils/proxyServerConfig.util.mjs' + ) + + try { + const moduleUrl = pathToFileURL(modulePath).href + + const { mlrunProxyConfig } = await import(moduleUrl) + + if (typeof mlrunProxyConfig !== 'function') { + throw new Error('Invalid export: expected mlrunProxyConfig to be a function.') + } + + return mlrunProxyConfig + } catch (error) { + if (process.env.PREVIEW_MODE === 'true' || mode === 'development') { + throw new Error(`Failed to load mlrunProxyConfig: ${error.message}`) + } + + return () => ({}) + } +} diff --git a/eslint.config.mjs b/eslint.config.mjs index d476aa233d..e06e5699e2 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,24 +5,28 @@ import react from 'eslint-plugin-react' import reactHooks from 'eslint-plugin-react-hooks' import eslintPluginImport from 'eslint-plugin-import' +import { viteGlobals } from './eslint.mlrun-globals.mjs' + export default [ - { ignores: ['dist'] }, + { ignores: ['dist', '.__mf__temp'] }, js.configs.recommended, eslintConfigPrettier, { - files: ['**/*.{js,jsx,ts,tsx}'], + files: ['**/*.{js,mjs,jsx,ts,tsx}'], languageOptions: { ecmaVersion: 2021, globals: { ...globals.browser, ...globals.jest, - ...globals.node + ...globals.node, + ...viteGlobals }, parserOptions: { ecmaFeatures: { jsx: true } - } + }, + sourceType: 'module' }, plugins: { react: react, @@ -49,9 +53,9 @@ export default [ } }, { - files: ["**/*.test.jsx"], + files: ['**/*.test.jsx'], rules: { - "import/named": "off" + 'import/named': 'off' } } ] diff --git a/eslint.mlrun-globals.mjs b/eslint.mlrun-globals.mjs new file mode 100644 index 0000000000..ea00e909b4 --- /dev/null +++ b/eslint.mlrun-globals.mjs @@ -0,0 +1,9 @@ +export const viteGlobals = { + VITE_PUBLIC_URL: 'readonly', + VITE_MLRUN_API_URL: 'readonly', + VITE_NUCLIO_API_URL: 'readonly', + VITE_IGUAZIO_API_URL: 'readonly', + VITE_FUNCTION_CATALOG_URL: 'readonly', + VITE_MLRUN_V3IO_ACCESS_KEY: 'readonly', + VITE_FEDERATION: 'readonly' +} diff --git a/nginx/nginx.conf.mf.tmpl b/nginx/nginx.conf.mf.tmpl new file mode 100644 index 0000000000..7989d3eeba --- /dev/null +++ b/nginx/nginx.conf.mf.tmpl @@ -0,0 +1,30 @@ +server { + listen 8090; + server_name localhost; + + root /usr/share/nginx/html; + + # Basic Gzip as per standard defaults + gzip on; + + # CRITICAL: Allow the Global Host (IGZ) to fetch these assets + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, OPTIONS'; + add_header Access-Control-Allow-Headers 'Content-Type, Authorization'; + + location / { + # Show landing page when accessing the remote directly + index landing.html; + try_files $uri $uri/ /landing.html; + + # Ensure remote assets are always fresh + if ($request_filename ~* .*\.(?:js|json)$ ) { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + } + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/nginx/run_nginx.mf b/nginx/run_nginx.mf new file mode 100644 index 0000000000..f6e1ae65af --- /dev/null +++ b/nginx/run_nginx.mf @@ -0,0 +1,7 @@ +#!/bin/sh + +# Simply copy the template as the final config +cp /etc/nginx/conf.d/nginx.conf.tmpl /etc/nginx/conf.d/nginx.conf + +# Start Nginx in foreground +exec nginx -g 'daemon off;' diff --git a/package-lock.json b/package-lock.json index 807df01f5f..49a30d9ce3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,8 @@ "hasInstallScript": true, "dependencies": { "@dagrejs/dagre": "^1.1.5", + "@module-federation/runtime": "^0.23.0", + "@module-federation/vite": "^1.2.6", "@monaco-editor/react": "^4.7.0", "@reduxjs/toolkit": "^1.9.5", "axios": "1.13.5", @@ -21,6 +23,7 @@ "concurrently": "^6.4.2", "cronstrue": "^2.49.0", "dotenv": "^10.0.0", + "dotenv-cli": "^10.0.0", "dotenv-expand": "^5.1.0", "file-saver": "^2.0.5", "final-form": "^4.20.10", @@ -40,6 +43,7 @@ "qs": "^6.15.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-error-boundary": "^6.1.0", "react-final-form": "^6.5.9", "react-final-form-arrays": "^3.1.4", "react-modal-promise": "^1.0.2", @@ -167,23 +171,23 @@ } }, "node_modules/@asamuzakjp/css-color": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz", - "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", + "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^3.0.0", - "@csstools/css-color-parser": "^4.0.1", - "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0", - "lru-cache": "^11.2.5" + "@csstools/css-calc": "^2.1.4", + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "lru-cache": "^11.2.4" } }, "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", + "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -191,9 +195,9 @@ } }, "node_modules/@asamuzakjp/dom-selector": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", - "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.7.tgz", + "integrity": "sha512-8CO/UQ4tzDd7ula+/CVimJIVWez99UJlbMyIgk8xOnhAVPKLnBZmUFYVgugS441v2ZqUq5EnSh6B0Ua0liSFAA==", "dev": true, "license": "MIT", "dependencies": { @@ -201,13 +205,13 @@ "bidi-js": "^1.0.3", "css-tree": "^3.1.0", "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.2.6" + "lru-cache": "^11.2.5" } }, "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", + "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -317,9 +321,9 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.0.tgz", + "integrity": "sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2520,9 +2524,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.1.tgz", - "integrity": "sha512-NmXRccUJMk2AWA5A7e5a//3bCIMyOu2hAtdRYrhPPHjDxINuCwX1w6rnIZ4xjLcp0ayv6h8Pc3X0eJUGiAAXHQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", "dev": true, "funding": [ { @@ -2536,13 +2540,13 @@ ], "license": "MIT-0", "engines": { - "node": ">=20.19.0" + "node": ">=18" } }, "node_modules/@csstools/css-calc": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", - "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", "dev": true, "funding": [ { @@ -2556,17 +2560,17 @@ ], "license": "MIT", "engines": { - "node": ">=20.19.0" + "node": ">=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0" + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, "node_modules/@csstools/css-color-parser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.1.tgz", - "integrity": "sha512-vYwO15eRBEkeF6xjAno/KQ61HacNhfQuuU/eGwH67DplL0zD5ZixUa563phQvUelA07yDczIXdtmYojCphKJcw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", "dev": true, "funding": [ { @@ -2580,21 +2584,21 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^6.0.1", - "@csstools/css-calc": "^3.0.0" + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" }, "engines": { - "node": ">=20.19.0" + "node": ">=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0" + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", - "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "funding": [ { @@ -2608,16 +2612,16 @@ ], "license": "MIT", "engines": { - "node": ">=20.19.0" + "node": ">=18" }, "peerDependencies": { - "@csstools/css-tokenizer": "^4.0.0" + "@csstools/css-tokenizer": "^3.0.4" } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.0.27", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.27.tgz", - "integrity": "sha512-sxP33Jwg1bviSUXAV43cVYdmjt2TLnLXNqCWl9xmxHawWVjGz/kEbdkr7F9pxJNBN2Mh+dq0crgItbW6tQvyow==", + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.26.tgz", + "integrity": "sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==", "dev": true, "funding": [ { @@ -2632,9 +2636,9 @@ "license": "MIT-0" }, "node_modules/@csstools/css-tokenizer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", - "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, "funding": [ { @@ -2648,7 +2652,7 @@ ], "license": "MIT", "engines": { - "node": ">=20.19.0" + "node": ">=18" } }, "node_modules/@csstools/normalize.css": { @@ -4876,30 +4880,30 @@ } }, "node_modules/@cucumber/ci-environment": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-12.0.0.tgz", - "integrity": "sha512-SqCEnbCNl3zCXCFpqGUuoaSNhLC0jLw4tKeFcAxTw9MD/QRlJjeAC/fyvVLFuXuSq0OunJlFfxLu+Z3HE+oLPg==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-13.0.0.tgz", + "integrity": "sha512-cs+3NzfNkGbcmHPddjEv4TKFiBpZRQ6WJEEufB9mw+ExS22V/4R/zpDSEG+fsJ/iSNCd6A2sATdY8PFOyY3YnA==", "dev": true, "license": "MIT" }, "node_modules/@cucumber/cucumber": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber/-/cucumber-12.6.0.tgz", - "integrity": "sha512-z6XKBIcUnJebnR3W8+K7Q2jJKB+pKpoD1l3CygEa9ufq/aeGuS5LAlllNxrod8loepLJhNmp8J8aengGbkL4cg==", + "version": "12.7.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber/-/cucumber-12.7.0.tgz", + "integrity": "sha512-7A/9CJpJDxv1SQ7hAZU0zPn2yRxx6XMR+LO4T94Enm3cYNWsEEj+RGX38NLX4INT+H6w5raX3Csb/qs4vUBsOA==", "dev": true, "license": "MIT", "dependencies": { - "@cucumber/ci-environment": "12.0.0", - "@cucumber/cucumber-expressions": "18.1.0", - "@cucumber/gherkin": "37.0.1", + "@cucumber/ci-environment": "13.0.0", + "@cucumber/cucumber-expressions": "19.0.0", + "@cucumber/gherkin": "38.0.0", "@cucumber/gherkin-streams": "6.0.0", - "@cucumber/gherkin-utils": "10.0.0", - "@cucumber/html-formatter": "22.3.0", + "@cucumber/gherkin-utils": "11.0.0", + "@cucumber/html-formatter": "23.0.0", "@cucumber/junit-xml-formatter": "0.9.0", "@cucumber/message-streams": "4.0.1", - "@cucumber/messages": "31.2.0", + "@cucumber/messages": "32.0.1", "@cucumber/pretty-formatter": "1.0.1", - "@cucumber/tag-expressions": "8.1.0", + "@cucumber/tag-expressions": "9.1.0", "assertion-error-formatter": "^3.0.0", "capital-case": "^1.0.4", "chalk": "^4.1.2", @@ -4922,7 +4926,7 @@ "mz": "^2.7.0", "progress": "^2.0.3", "read-package-up": "^12.0.0", - "semver": "7.7.3", + "semver": "7.7.4", "string-argv": "0.3.1", "supports-color": "^8.1.1", "type-fest": "^4.41.0", @@ -4941,9 +4945,9 @@ } }, "node_modules/@cucumber/cucumber-expressions": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-18.1.0.tgz", - "integrity": "sha512-9yc+wForrn15FaqLWNjYb19iQ/gPXhcq1kc4X1Ex1lR7NcJpa5pGnCow3bc1HERVM5IoYH+gwwrcJogSMsf+Vw==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-19.0.0.tgz", + "integrity": "sha512-4FKoOQh2Uf6F6/Ln+1OxuK8LkTg6PyAqekhf2Ix8zqV2M54sH+m7XNJNLhOFOAW/t9nxzRbw2CcvXbCLjcvHZg==", "dev": true, "license": "MIT", "dependencies": { @@ -4960,27 +4964,14 @@ "node": ">=20" } }, - "node_modules/@cucumber/cucumber/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@cucumber/gherkin": { - "version": "37.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-37.0.1.tgz", - "integrity": "sha512-VmX+PKa9vqKZiycZoQKYlCsA0N7gAfiOfrcHSjK+suEVUwvKEH2sjO47NznrFFLmVWYTRmw3DLHQnpBAznkYEA==", + "version": "38.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-38.0.0.tgz", + "integrity": "sha512-duEXK+KDfQUzu3vsSzXjkxQ2tirF5PRsc1Xrts6THKHJO6mjw4RjM8RV+vliuDasmhhrmdLcOcM7d9nurNTJKw==", "dev": true, "license": "MIT", "dependencies": { - "@cucumber/messages": ">=31.0.0 <32" + "@cucumber/messages": ">=31.0.0 <33" } }, "node_modules/@cucumber/gherkin-streams": { @@ -5013,91 +5004,36 @@ } }, "node_modules/@cucumber/gherkin-utils": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-10.0.0.tgz", - "integrity": "sha512-BcujlDT343GXXNrMPl3ws6Il3zs8dQw3Yp/d3HnOJF8i2snGGgiapoTbko7MdvAt7ivDL7SDo+e1d5Cnpl3llA==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-11.0.0.tgz", + "integrity": "sha512-LJ+s4+TepHTgdKWDR4zbPyT7rQjmYIcukTwNbwNwgqr6i8Gjcmzf6NmtbYDA19m1ZFg6kWbFsmHnj37ZuX+kZA==", "dev": true, "license": "MIT", "dependencies": { - "@cucumber/gherkin": "^34.0.0", - "@cucumber/messages": "^29.0.0", + "@cucumber/gherkin": "^38.0.0", + "@cucumber/messages": "^32.0.0", "@teppeis/multimaps": "3.0.0", - "commander": "14.0.0", + "commander": "14.0.2", "source-map-support": "^0.5.21" }, "bin": { "gherkin-utils": "bin/gherkin-utils" } }, - "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/gherkin": { - "version": "34.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-34.0.0.tgz", - "integrity": "sha512-659CCFsrsyvuBi/Eix1fnhSheMnojSfnBcqJ3IMPNawx7JlrNJDcXYSSdxcUw3n/nG05P+ptCjmiZY3i14p+tA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cucumber/messages": ">=19.1.4 <29" - } - }, - "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/gherkin/node_modules/@cucumber/messages": { - "version": "28.1.0", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-28.1.0.tgz", - "integrity": "sha512-2LzZtOwYKNlCuNf31ajkrekoy2M4z0Z1QGiPH40n4gf5t8VOUFb7m1ojtR4LmGvZxBGvJZP8voOmRqDWzBzYKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/uuid": "10.0.0", - "class-transformer": "0.5.1", - "reflect-metadata": "0.2.2", - "uuid": "11.1.0" - } - }, - "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/messages": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-29.0.1.tgz", - "integrity": "sha512-aAvIYfQD6/aBdF8KFQChC3CQ1Q+GX9orlR6GurGiX6oqaCnBkxA4WU3OQUVepDynEFrPayerqKRFcAMhdcXReQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "class-transformer": "0.5.1", - "reflect-metadata": "0.2.2" - } - }, - "node_modules/@cucumber/gherkin-utils/node_modules/@types/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@cucumber/gherkin-utils/node_modules/commander": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", - "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", "dev": true, "license": "MIT", "engines": { "node": ">=20" } }, - "node_modules/@cucumber/gherkin-utils/node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/@cucumber/html-formatter": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-22.3.0.tgz", - "integrity": "sha512-0s3G7kznCRDiiesQ4K0yBdswGqU9E0j2AWUug41NpedBzhaY+Hn192ANRF597GZtuWrCjE53aFb3fOyOsT8B+g==", + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-23.0.0.tgz", + "integrity": "sha512-WwcRzdM8Ixy4e53j+Frm3fKM5rNuIyWUfy4HajEN+Xk/YcjA6yW0ACGTFDReB++VDZz/iUtwYdTlPRY36NbqJg==", "dev": true, "license": "MIT", "peerDependencies": { @@ -5131,9 +5067,9 @@ } }, "node_modules/@cucumber/messages": { - "version": "31.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-31.2.0.tgz", - "integrity": "sha512-3urzBNCwmU/YKrKR0b3XdioFcOFNuxlLwEImsxeP8rXnweLs+Ky04QURcbKpFom3T6a6v9zVioLCfHUuSQ72pg==", + "version": "32.0.1", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-32.0.1.tgz", + "integrity": "sha512-1OSoW+GQvFUNAl6tdP2CTBexTXMNJF0094goVUcvugtQeXtJ0K8sCP0xbq7GGoiezs/eJAAOD03+zAPT64orHQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5158,6 +5094,19 @@ "@cucumber/messages": "*" } }, + "node_modules/@cucumber/pretty-formatter/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/@cucumber/query": { "version": "14.7.0", "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-14.7.0.tgz", @@ -5173,9 +5122,9 @@ } }, "node_modules/@cucumber/tag-expressions": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-8.1.0.tgz", - "integrity": "sha512-UFeOVUyc711/E7VHjThxMwg3jbGod9TlbM1gxNixX/AGDKg82Eha4cE0tKki3GGUs7uB2NyI+hQAuhB8rL2h5A==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-9.1.0.tgz", + "integrity": "sha512-bvHjcRFZ+J1TqIa9eFNO1wGHqwx4V9ZKV3hYgkuK/VahHx73uiP4rKV3JVrvWSMrwrFvJG6C8aEwnCWSvbyFdQ==", "dev": true, "license": "MIT" }, @@ -5204,7 +5153,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5221,7 +5169,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5238,7 +5185,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5255,7 +5201,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5272,7 +5217,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5289,7 +5233,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5306,7 +5249,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5323,7 +5265,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5340,7 +5281,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5357,7 +5297,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5374,7 +5313,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5391,7 +5329,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5408,7 +5345,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5425,7 +5361,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5442,7 +5377,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5459,7 +5393,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5476,7 +5409,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5493,7 +5425,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5510,7 +5441,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5527,7 +5457,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5544,7 +5473,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5561,7 +5489,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5578,7 +5505,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5595,7 +5521,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5612,7 +5537,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5629,7 +5553,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5797,9 +5720,9 @@ } }, "node_modules/@exodus/bytes": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.14.1.tgz", - "integrity": "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.11.0.tgz", + "integrity": "sha512-wO3vd8nsEHdumsXrjGO/v4p6irbg7hy9kvIeR6i2AwylZSk4HJdWgL0FNaVquW1+AweJcdvU1IEpuIWk/WaPnA==", "dev": true, "license": "MIT", "engines": { @@ -6033,7 +5956,7 @@ "version": "0.3.11", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "dependencies": { @@ -6081,98 +6004,439 @@ "react": ">=16" } }, - "node_modules/@monaco-editor/loader": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz", - "integrity": "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==", + "node_modules/@module-federation/dts-plugin": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.21.6.tgz", + "integrity": "sha512-YIsDk8/7QZIWn0I1TAYULniMsbyi2LgKTi9OInzVmZkwMC6644x/ratTWBOUDbdY1Co+feNkoYeot1qIWv2L7w==", "license": "MIT", "dependencies": { - "state-local": "^1.0.6" + "@module-federation/error-codes": "0.21.6", + "@module-federation/managers": "0.21.6", + "@module-federation/sdk": "0.21.6", + "@module-federation/third-party-dts-extractor": "0.21.6", + "adm-zip": "^0.5.10", + "ansi-colors": "^4.1.3", + "axios": "^1.12.0", + "chalk": "3.0.0", + "fs-extra": "9.1.0", + "isomorphic-ws": "5.0.0", + "koa": "3.0.3", + "lodash.clonedeepwith": "4.5.0", + "log4js": "6.9.1", + "node-schedule": "2.1.1", + "rambda": "^9.1.0", + "ws": "8.18.0" + }, + "peerDependencies": { + "typescript": "^4.9.0 || ^5.0.0", + "vue-tsc": ">=1.0.24" + }, + "peerDependenciesMeta": { + "vue-tsc": { + "optional": true + } } }, - "node_modules/@monaco-editor/react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", - "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "node_modules/@module-federation/dts-plugin/node_modules/@module-federation/error-codes": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.21.6.tgz", + "integrity": "sha512-MLJUCQ05KnoVl8xd6xs9a5g2/8U+eWmVxg7xiBMeR0+7OjdWUbHwcwgVFatRIwSZvFgKHfWEiI7wsU1q1XbTRQ==", + "license": "MIT" + }, + "node_modules/@module-federation/dts-plugin/node_modules/@module-federation/sdk": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.21.6.tgz", + "integrity": "sha512-x6hARETb8iqHVhEsQBysuWpznNZViUh84qV2yE7AD+g7uIzHKiYdoWqj10posbo5XKf/147qgWDzKZoKoEP2dw==", + "license": "MIT" + }, + "node_modules/@module-federation/dts-plugin/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "license": "MIT", "dependencies": { - "@monaco-editor/loader": "^1.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, - "peerDependencies": { - "monaco-editor": ">= 0.25.0 < 1", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dev": true, + "node_modules/@module-federation/dts-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "license": "MIT", "dependencies": { - "eslint-scope": "5.1.1" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@module-federation/dts-plugin/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@module-federation/dts-plugin/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@module-federation/dts-plugin/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@module-federation/error-codes": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.23.0.tgz", + "integrity": "sha512-CzcKOPKh/qB1wPkVBC0iEK/Cg4jRAS1DnZsTx7b3JUCIXDcIaRq/XkTdo+EQ0cAsF5Os9lQ0f50O9DC/uFC8eA==", + "license": "MIT" + }, + "node_modules/@module-federation/managers": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.21.6.tgz", + "integrity": "sha512-BeV6m2/7kF5MDVz9JJI5T8h8lMosnXkH2bOxxFewcra7ZjvDOgQu7WIio0mgk5l1zjNPvnEVKhnhrenEdcCiWg==", "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" + "@module-federation/sdk": "0.21.6", + "find-pkg": "2.0.0", + "fs-extra": "9.1.0" } }, - "node_modules/@parcel/watcher": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", - "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", - "dev": true, - "hasInstallScript": true, + "node_modules/@module-federation/managers/node_modules/@module-federation/sdk": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.21.6.tgz", + "integrity": "sha512-x6hARETb8iqHVhEsQBysuWpznNZViUh84qV2yE7AD+g7uIzHKiYdoWqj10posbo5XKf/147qgWDzKZoKoEP2dw==", + "license": "MIT" + }, + "node_modules/@module-federation/managers/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "license": "MIT", - "optional": true, "dependencies": { - "detect-libc": "^2.0.3", - "is-glob": "^4.0.3", - "node-addon-api": "^7.0.0", - "picomatch": "^4.0.3" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=10" + } + }, + "node_modules/@module-federation/managers/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.6", - "@parcel/watcher-darwin-arm64": "2.5.6", + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@module-federation/runtime": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.23.0.tgz", + "integrity": "sha512-ZHJcfM1O8RqYVrlIbhyeQ3S6gJW3mqHso3/QY7cKs1za+UvOgB8aTsDwq7Fv+aJZWSmtGzWa4zbSuxthyucw3g==", + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.23.0", + "@module-federation/runtime-core": "0.23.0", + "@module-federation/sdk": "0.23.0" + } + }, + "node_modules/@module-federation/runtime-core": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.23.0.tgz", + "integrity": "sha512-+Orumtyg6Q2v19Gz15P3kDmRf4Q6KEpv8DggKWHdM8AX4xyVT8dMRJxdIxaVddbIYTd7aL7o2U3LLK6EjUe4UA==", + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.23.0", + "@module-federation/sdk": "0.23.0" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.23.0.tgz", + "integrity": "sha512-1+DICHIF1z6yggtsZypmcn1gL35iitiSDXcsaqWynK4v5aw9MBRUS4zP3kG7eQDFTMmIo+rGbPN37AUsOq/RRQ==", + "license": "MIT" + }, + "node_modules/@module-federation/third-party-dts-extractor": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.21.6.tgz", + "integrity": "sha512-Il6x4hLsvCgZNk1DFwuMBNeoxD1BsZ5AW2BI/nUgu0k5FiAvfcz1OFawRFEHtaM/kVrCsymMOW7pCao90DaX3A==", + "license": "MIT", + "dependencies": { + "find-pkg": "2.0.0", + "fs-extra": "9.1.0", + "resolve": "1.22.8" + } + }, + "node_modules/@module-federation/third-party-dts-extractor/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@module-federation/third-party-dts-extractor/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@module-federation/third-party-dts-extractor/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@module-federation/vite": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@module-federation/vite/-/vite-1.11.0.tgz", + "integrity": "sha512-dawLMF1JUt/4IUwQh7dUF5TBcetGg3qPKBX+hCFL2aHFd8m3EI+HmGc4qIGVlGZMub6mpTIGo9EHfhV5cDIOmQ==", + "license": "MIT", + "dependencies": { + "@module-federation/dts-plugin": "^0.21.6", + "@module-federation/runtime": "^0.21.6", + "@module-federation/sdk": "^0.21.6", + "@rollup/pluginutils": "^5.1.0", + "defu": "^6.1.4", + "estree-walker": "^2", + "magic-string": "^0.30.11", + "pathe": "^1.1.2" + }, + "peerDependencies": { + "vite": "<=7.1.7" + } + }, + "node_modules/@module-federation/vite/node_modules/@module-federation/error-codes": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.21.6.tgz", + "integrity": "sha512-MLJUCQ05KnoVl8xd6xs9a5g2/8U+eWmVxg7xiBMeR0+7OjdWUbHwcwgVFatRIwSZvFgKHfWEiI7wsU1q1XbTRQ==", + "license": "MIT" + }, + "node_modules/@module-federation/vite/node_modules/@module-federation/runtime": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.21.6.tgz", + "integrity": "sha512-+caXwaQqwTNh+CQqyb4mZmXq7iEemRDrTZQGD+zyeH454JAYnJ3s/3oDFizdH6245pk+NiqDyOOkHzzFQorKhQ==", + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.21.6", + "@module-federation/runtime-core": "0.21.6", + "@module-federation/sdk": "0.21.6" + } + }, + "node_modules/@module-federation/vite/node_modules/@module-federation/runtime-core": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.21.6.tgz", + "integrity": "sha512-5Hd1Y5qp5lU/aTiK66lidMlM/4ji2gr3EXAtJdreJzkY+bKcI5+21GRcliZ4RAkICmvdxQU5PHPL71XmNc7Lsw==", + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.21.6", + "@module-federation/sdk": "0.21.6" + } + }, + "node_modules/@module-federation/vite/node_modules/@module-federation/sdk": { + "version": "0.21.6", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.21.6.tgz", + "integrity": "sha512-x6hARETb8iqHVhEsQBysuWpznNZViUh84qV2yE7AD+g7uIzHKiYdoWqj10posbo5XKf/147qgWDzKZoKoEP2dw==", + "license": "MIT" + }, + "node_modules/@module-federation/vite/node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@module-federation/vite/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/@module-federation/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@monaco-editor/loader": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz", + "integrity": "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", + "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.5.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", "@parcel/watcher-darwin-x64": "2.5.6", "@parcel/watcher-freebsd-x64": "2.5.6", "@parcel/watcher-linux-arm-glibc": "2.5.6", @@ -6193,7 +6457,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6214,7 +6477,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6235,7 +6497,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6256,7 +6517,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6277,7 +6537,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6298,7 +6557,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6319,7 +6577,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6340,7 +6597,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6361,7 +6617,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6382,7 +6637,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6403,7 +6657,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6424,7 +6677,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6445,7 +6697,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6460,10 +6711,9 @@ } }, "node_modules/@parcel/watcher/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", "optional": true, "engines": { @@ -6643,13 +6893,12 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", + "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==", "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6657,13 +6906,12 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz", + "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6671,13 +6919,12 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz", + "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6685,13 +6932,12 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz", + "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6699,13 +6945,12 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz", + "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6713,13 +6958,12 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz", + "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6727,13 +6971,12 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz", + "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==", "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6741,13 +6984,12 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz", + "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==", "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6755,13 +6997,12 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz", + "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6769,13 +7010,12 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz", + "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6783,13 +7023,12 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz", + "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==", "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6797,13 +7036,12 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz", + "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==", "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6811,13 +7049,12 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz", + "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==", "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6825,13 +7062,12 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz", + "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==", "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6839,13 +7075,12 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz", + "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==", "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6853,13 +7088,12 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz", + "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==", "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6867,13 +7101,12 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz", + "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==", "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6881,13 +7114,12 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz", + "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6895,13 +7127,12 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz", + "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6909,13 +7140,12 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz", + "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6923,13 +7153,12 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz", + "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6937,13 +7166,12 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz", + "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6951,13 +7179,12 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz", + "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==", "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6965,13 +7192,12 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz", + "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6979,13 +7205,12 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz", + "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -7000,9 +7225,9 @@ "license": "MIT" }, "node_modules/@sinclair/typebox": { - "version": "0.27.10", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", - "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true, "license": "MIT" }, @@ -7293,14 +7518,14 @@ } }, "node_modules/@storybook/core": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.17.tgz", - "integrity": "sha512-lndZDYIvUddWk54HmgYwE4h2B0JtWt8ztIRAzHRt6ReZZ9QQbmM5b85Qpa+ng4dyQEKc2JAtYD3Du7RRFcpHlw==", + "version": "8.6.15", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.15.tgz", + "integrity": "sha512-VFpKcphNurJpSC4fpUfKL3GTXVoL53oytghGR30QIw5jKWwaT50HVbTyb41BLOUuZjmMhUQA8weiQEew6RX0gw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@storybook/theming": "8.6.17", + "@storybook/theming": "8.6.15", "better-opn": "^3.0.2", "browser-assert": "^1.2.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", @@ -7325,21 +7550,6 @@ } } }, - "node_modules/@storybook/core/node_modules/@storybook/theming": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.17.tgz", - "integrity": "sha512-IttFvRqozpuzN5MlQEWGOzUA2rZg86688Dyv1d+bjpYcFHtY1X4XyTCGwv1BPTaTsB959oM8R2yoNYWQkABbBA==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" - } - }, "node_modules/@storybook/csf-plugin": { "version": "8.6.14", "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.14.tgz", @@ -8137,7 +8347,17 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/aria-query": { + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", @@ -8498,7 +8718,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, "node_modules/@types/geojson": { @@ -8605,10 +8824,10 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", - "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", - "dev": true, + "version": "25.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", + "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~7.16.0" @@ -8629,9 +8848,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "version": "19.2.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.10.tgz", + "integrity": "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==", "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -8892,6 +9111,19 @@ "node": ">=18.20.0" } }, + "node_modules/@wdio/logger/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/@wdio/logger/node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", @@ -8905,6 +9137,22 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/@wdio/logger/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -9098,9 +9346,9 @@ "peer": true }, "node_modules/@zip.js/zip.js": { - "version": "2.8.20", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.20.tgz", - "integrity": "sha512-oJzVhK9gnSKD++WLG37QEgeTgm5W8XUYmNv0EhOxytSr85vXn9EMpOoKNTK3yWDLa55Z0MovKW/6RNeh9OUmnA==", + "version": "2.8.16", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.16.tgz", + "integrity": "sha512-kCjaXh50GCf9afcof6ekjXPKR//rBVIxNHJLSUaM3VAET2F0+hymgrK1GpInRIIFUpt+wsnUfgx2+bbrmc+7Tw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -9113,7 +9361,6 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -9169,6 +9416,15 @@ "node": ">=8.9" } }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -9216,9 +9472,9 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "peer": true, @@ -9251,6 +9507,15 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-regex": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", @@ -9262,13 +9527,15 @@ } }, "node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" @@ -9597,7 +9864,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, "license": "ISC", "engines": { "node": ">= 4.0.0" @@ -9793,25 +10059,19 @@ } }, "node_modules/babel-plugin-inline-react-svg/node_modules/resolve": { - "version": "2.0.0-next.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", - "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "node-exports-info": "^1.6.0", - "object-keys": "^1.1.1", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, - "engines": { - "node": ">= 0.4" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10116,9 +10376,9 @@ } }, "node_modules/basic-ftp": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", - "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.1.0.tgz", + "integrity": "sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==", "dev": true, "license": "MIT", "engines": { @@ -10356,7 +10616,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/bytes": { @@ -10477,9 +10737,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001770", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", - "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", + "version": "1.0.30001767", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001767.tgz", + "integrity": "sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==", "dev": true, "funding": [ { @@ -10544,21 +10804,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/chalk/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10777,25 +11022,21 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/clone-deep": { @@ -10922,7 +11163,6 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -10935,7 +11175,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -10965,6 +11204,19 @@ "dev": true, "license": "MIT" }, + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/core-js": { "version": "3.48.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz", @@ -11025,6 +11277,18 @@ "node": ">= 6" } }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/cronstrue": { "version": "2.59.0", "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.59.0.tgz", @@ -11057,7 +11321,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -11432,9 +11695,9 @@ } }, "node_modules/cssstyle/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", + "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -11793,11 +12056,19 @@ "url": "https://github.com/sponsors/kossnocorp" } }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -11888,6 +12159,12 @@ "node": ">=6" } }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "license": "MIT" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -11951,6 +12228,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, "node_modules/degenerator": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", @@ -11989,11 +12272,16 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT" + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -12013,7 +12301,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8", @@ -12024,7 +12311,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, "license": "Apache-2.0", "optional": true, "engines": { @@ -12224,6 +12510,60 @@ "node": ">=10" } }, + "node_modules/dotenv-cli": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-10.0.0.tgz", + "integrity": "sha512-lnOnttzfrzkRx2echxJHQRB6vOAMSCzzZg79IxpC00tU42wZPuZkQxNNrrwVAxaQZIIh001l4PxVlCrBxngBzA==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.6", + "dotenv": "^17.1.0", + "dotenv-expand": "^11.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "dotenv": "cli.js" + } + }, + "node_modules/dotenv-cli/node_modules/dotenv": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", + "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-cli/node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-cli/node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dotenv-expand": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", @@ -12265,7 +12605,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true, "license": "MIT" }, "node_modules/electron-to-chromium": { @@ -12294,7 +12633,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -12564,7 +12902,6 @@ "version": "0.25.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -12629,7 +12966,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true, "license": "MIT" }, "node_modules/escape-string-regexp": { @@ -12962,25 +13298,19 @@ } }, "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", - "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "node-exports-info": "^1.6.0", - "object-keys": "^1.1.1", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, - "engines": { - "node": ">= 0.4" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -13218,7 +13548,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, "license": "MIT" }, "node_modules/esutils": { @@ -13272,6 +13601,18 @@ "node": ">=8" } }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -13679,6 +14020,30 @@ "node": ">=6" } }, + "node_modules/find-file-up": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-2.0.1.tgz", + "integrity": "sha512-qVdaUhYO39zmh28/JLQM5CoYN9byEOKEH4qfa8K1eNV17W0UUMJ9WgbR/hHFH+t5rcl+6RTb5UC7ck/I+uRkpQ==", + "license": "MIT", + "dependencies": { + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-pkg/-/find-pkg-2.0.0.tgz", + "integrity": "sha512-WgZ+nKbELDa6N3i/9nrHeNznm+lY3z4YfhDDWgW+5P0pdmMj26bxaxU11ookgY3NyP9GC7HvZ9etp0jRFqGEeQ==", + "license": "MIT", + "dependencies": { + "find-file-up": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -13721,10 +14086,9 @@ } }, "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", - "dev": true, + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "license": "ISC" }, "node_modules/follow-redirects": { @@ -13840,7 +14204,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -13944,7 +14308,6 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -14215,18 +14578,18 @@ } }, "node_modules/glob": { - "version": "13.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.4.tgz", - "integrity": "sha512-KACie1EOs9BIOMtenFaxwmYODWA3/fTfGSUnLhMJpXRntu1g+uL/Xvub5f8SCTppvo9q62Qy4LeOoUiaL54G5A==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "minimatch": "^10.2.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -14562,7 +14925,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, "license": "MIT", "dependencies": { "parse-passwd": "^1.0.0" @@ -14581,27 +14943,11 @@ } }, "node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^11.1.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", - "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } + "license": "ISC" }, "node_modules/html-encoding-sniffer": { "version": "6.0.0", @@ -14666,16 +15012,62 @@ "node": ">= 6" } }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dev": true, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", "license": "MIT", "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-assert/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-assert/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-assert/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" }, @@ -14850,9 +15242,9 @@ } }, "node_modules/immutable": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.3.tgz", - "integrity": "sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", "dev": true, "license": "MIT", "engines": { @@ -14945,7 +15337,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, "license": "ISC" }, "node_modules/ini": { @@ -15645,6 +16036,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", @@ -15680,7 +16080,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/isobject": { @@ -15693,6 +16092,15 @@ "node": ">=0.10.0" } }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -16007,6 +16415,18 @@ "setimmediate": "^1.0.5" } }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "license": "MIT", + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -16063,6 +16483,89 @@ "seed-random": "~2.2.0" } }, + "node_modules/koa": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-3.0.3.tgz", + "integrity": "sha512-MeuwbCoN1daWS32/Ni5qkzmrOtQO2qrnfdxDHjrm6s4b59yG4nexAJ0pTEFyzjLp0pBVO80CZp0vW8Ze30Ebow==", + "license": "MIT", + "dependencies": { + "accepts": "^1.3.8", + "content-disposition": "~0.5.4", + "content-type": "^1.0.5", + "cookies": "~0.9.1", + "delegates": "^1.0.0", + "destroy": "^1.2.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.5.0", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "mime-types": "^3.0.1", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "license": "MIT" + }, + "node_modules/koa/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/koa/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/koa/node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -16153,6 +16656,12 @@ "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, + "node_modules/lodash.clonedeepwith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz", + "integrity": "sha512-QRBRSxhbtsX1nc0baxSkkK5WlVTTm/s48DSukcGcWZwIyI8Zz+lB+kFiELJXtzfH4Aj6kMWQ1VWW4U5uUDgZMA==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -16212,6 +16721,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/loglevel": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", @@ -16233,6 +16758,12 @@ "dev": true, "license": "MIT" }, + "node_modules/long-timeout": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", + "integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==", + "license": "MIT" + }, "node_modules/longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", @@ -16290,7 +16821,6 @@ "version": "3.7.2", "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -16311,7 +16841,6 @@ "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -16725,7 +17254,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -16757,11 +17285,11 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -16816,7 +17344,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/mz": { @@ -16859,7 +17386,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -16914,7 +17440,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, "license": "MIT", "optional": true }, @@ -16956,35 +17481,6 @@ "semver": "bin/semver" } }, - "node_modules/node-exports-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", - "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array.prototype.flatmap": "^1.3.3", - "es-errors": "^1.3.0", - "object.entries": "^1.1.9", - "semver": "^6.3.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/node-exports-info/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -16999,6 +17495,20 @@ "dev": true, "license": "MIT" }, + "node_modules/node-schedule": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.1.1.tgz", + "integrity": "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==", + "license": "MIT", + "dependencies": { + "cron-parser": "^4.2.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.3.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/nodemon": { "version": "3.1.11", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.11.tgz", @@ -17052,18 +17562,26 @@ } }, "node_modules/normalize-package-data": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", - "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "hosted-git-info": "^9.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, "node_modules/normalize-path": { @@ -17279,7 +17797,6 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -17505,7 +18022,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17528,7 +18044,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -17558,7 +18073,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17571,9 +18085,9 @@ "license": "MIT" }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -17581,7 +18095,7 @@ "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -17652,9 +18166,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -19611,6 +20125,20 @@ "node": ">=8" } }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/prismjs": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", @@ -19828,6 +20356,12 @@ "performance-now": "^2.1.0" } }, + "node_modules/rambda": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/rambda/-/rambda-9.4.2.tgz", + "integrity": "sha512-++euMfxnl7OgaEKwXh9QqThOjMeta2HH001N1v4mYQzBjJBnmXBh2BCK6dZAbICFVXOFUVD3xFG0R3ZPU0mxXw==", + "license": "MIT" + }, "node_modules/randexp": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", @@ -19941,16 +20475,6 @@ "node": ">=14" } }, - "node_modules/react-dev-utils/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/react-dev-utils/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -20057,19 +20581,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/react-dev-utils/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -20083,6 +20594,15 @@ "react": "^18.3.1" } }, + "node_modules/react-error-boundary": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.1.tgz", + "integrity": "sha512-BrYwPOdXi5mqkk5lw+Uvt0ThHx32rCt3BkukS4X23A2AIWDPSGX6iaWTc0y9TU/mHDA/6qOSGel+B2ERkOvD1w==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, "node_modules/react-error-overlay": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.1.0.tgz", @@ -20173,9 +20693,9 @@ } }, "node_modules/react-resizable-panels": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-4.6.4.tgz", - "integrity": "sha512-E7Szs1xyaMZ7xOI2gG4TECNz4r/gmpV1AsXyZRnER6OQnfFf9uclFmrHHZR3h/iF8vQS+nQ1LKyZv9bzwGxPSg==", + "version": "4.5.9", + "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-4.5.9.tgz", + "integrity": "sha512-7l0w2TxYq032F2o6PnfxDbDEKzi1lohDw3BKx4OBkh6uu7uh+Gj1C0Ubpv0/fOO2bRvo+IIQMOoFE0l2LgpeAg==", "license": "MIT", "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -20296,23 +20816,76 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-package-up/node_modules/type-fest": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.4.4.tgz", - "integrity": "sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==", + "node_modules/read-package-up/node_modules/hosted-git-info": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "ISC", "dependencies": { - "tagged-tag": "^1.0.0" + "lru-cache": "^11.1.0" }, "engines": { - "node": ">=20" + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/read-package-up/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/read-package-up/node_modules/normalize-package-data": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", + "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^9.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/read-package-up/node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg": { + "node_modules/read-package-up/node_modules/parse-json/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-package-up/node_modules/read-pkg": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", @@ -20332,45 +20905,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/read-package-up/node_modules/type-fest": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.4.4.tgz", + "integrity": "sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==", "dev": true, - "license": "MIT", + "license": "(MIT OR CC0-1.0)", "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "tagged-tag": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/read-pkg-up/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg-up/node_modules/read-pkg": { + "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", @@ -20386,81 +20937,42 @@ "node": ">=8" } }, - "node_modules/read-pkg-up/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "index-to-position": "^1.1.0", - "type-fest": "^4.39.1" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, "engines": { - "node": ">=18" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg/node_modules/parse-json/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/read-pkg/node_modules/type-fest": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.4.4.tgz", - "integrity": "sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/readable-stream": { @@ -20854,6 +21366,67 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-dir/node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-dir/node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-dir/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/resolve-dir/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -20906,6 +21479,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -20927,7 +21506,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -20946,10 +21525,9 @@ } }, "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", - "dev": true, + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz", + "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", "license": "MIT", "dependencies": { "@types/estree": "1.0.8" @@ -20962,31 +21540,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", + "@rollup/rollup-android-arm-eabi": "4.57.1", + "@rollup/rollup-android-arm64": "4.57.1", + "@rollup/rollup-darwin-arm64": "4.57.1", + "@rollup/rollup-darwin-x64": "4.57.1", + "@rollup/rollup-freebsd-arm64": "4.57.1", + "@rollup/rollup-freebsd-x64": "4.57.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", + "@rollup/rollup-linux-arm-musleabihf": "4.57.1", + "@rollup/rollup-linux-arm64-gnu": "4.57.1", + "@rollup/rollup-linux-arm64-musl": "4.57.1", + "@rollup/rollup-linux-loong64-gnu": "4.57.1", + "@rollup/rollup-linux-loong64-musl": "4.57.1", + "@rollup/rollup-linux-ppc64-gnu": "4.57.1", + "@rollup/rollup-linux-ppc64-musl": "4.57.1", + "@rollup/rollup-linux-riscv64-gnu": "4.57.1", + "@rollup/rollup-linux-riscv64-musl": "4.57.1", + "@rollup/rollup-linux-s390x-gnu": "4.57.1", + "@rollup/rollup-linux-x64-gnu": "4.57.1", + "@rollup/rollup-linux-x64-musl": "4.57.1", + "@rollup/rollup-openbsd-x64": "4.57.1", + "@rollup/rollup-openharmony-arm64": "4.57.1", + "@rollup/rollup-win32-arm64-msvc": "4.57.1", + "@rollup/rollup-win32-ia32-msvc": "4.57.1", + "@rollup/rollup-win32-x64-gnu": "4.57.1", + "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" } }, @@ -21055,7 +21633,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -21155,7 +21732,7 @@ "version": "1.97.3", "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.0", @@ -21215,7 +21792,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -21228,17 +21805,17 @@ } }, "node_modules/sass/node_modules/immutable": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", - "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", - "dev": true, + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "devOptional": true, "license": "MIT" }, "node_modules/sass/node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -21248,16 +21825,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/sax": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", - "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=11.0.0" - } - }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -21332,6 +21899,16 @@ "node": ">= 20.0.0" } }, + "node_modules/selenium-webdriver/node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", @@ -21486,7 +22063,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, "license": "ISC" }, "node_modules/shallow-clone": { @@ -21506,7 +22082,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -21519,7 +22094,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -21617,13 +22191,6 @@ "dev": true, "license": "ISC" }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -21671,22 +22238,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -21739,6 +22290,12 @@ "node": ">= 14" } }, + "node_modules/sorted-array-functions": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", + "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==", + "license": "MIT" + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -21795,7 +22352,7 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -21892,7 +22449,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -21920,14 +22476,14 @@ } }, "node_modules/storybook": { - "version": "8.6.17", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.17.tgz", - "integrity": "sha512-krR/l680A6qVnkGiK9p8jY0ucX3+kFCs2f4zw+S3w2Cdq8EiM/tFebPcX2V4S3z2UsO0v0dwAJOJNpzbFPdmVg==", + "version": "8.6.15", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.15.tgz", + "integrity": "sha512-Ob7DMlwWx8s7dMvcQ3xPc02TvUeralb+xX3oaPRk9wY9Hc6M1IBC/7cEoITkSmRS2v38DHubC+mtEKNc1u2gQg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@storybook/core": "8.6.17" + "@storybook/core": "8.6.15" }, "bin": { "getstorybook": "bin/index.cjs", @@ -21947,6 +22503,52 @@ } } }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/streamroller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/streamroller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -21988,27 +22590,6 @@ "node": ">=8" } }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.matchall": { "version": "4.0.12", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", @@ -22108,32 +22689,24 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/strip-bom": { @@ -22336,16 +22909,6 @@ "node": ">=4" } }, - "node_modules/stylelint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/stylelint/node_modules/autoprefixer": { "version": "9.8.8", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", @@ -22438,18 +23001,12 @@ "node": ">=4" } }, - "node_modules/stylelint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/stylelint/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } + "license": "ISC" }, "node_modules/stylelint/node_modules/write-file-atomic": { "version": "3.0.3", @@ -22499,7 +23056,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "postcss": "^7.0.2" @@ -22546,18 +23103,18 @@ "dev": true }, "node_modules/svgo": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.2.tgz", - "integrity": "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "dev": true, "license": "MIT", "dependencies": { + "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^4.1.3", "css-tree": "^1.1.3", "csso": "^4.2.0", "picocolors": "^1.0.0", - "sax": "^1.5.0", "stable": "^0.1.8" }, "bin": { @@ -22639,9 +23196,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { @@ -22655,16 +23212,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/table/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -22672,19 +23219,6 @@ "dev": true, "license": "MIT" }, - "node_modules/table/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/tagged-tag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", @@ -22798,7 +23332,7 @@ "version": "5.46.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "peer": true, "dependencies": { @@ -22851,9 +23385,9 @@ } }, "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "peer": true, @@ -22931,7 +23465,7 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "bin": { @@ -22945,7 +23479,7 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true }, @@ -22968,7 +23502,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -23085,9 +23619,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", "engines": { "node": ">=12" @@ -23107,35 +23641,25 @@ } }, "node_modules/tldts": { - "version": "7.0.23", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.23.tgz", - "integrity": "sha512-ASdhgQIBSay0R/eXggAkQ53G4nTJqTXqC2kbaBbdDwM7SkjyZyO0OaaN1/FH7U/yCeqOHDwFO5j8+Os/IS1dXw==", + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.21.tgz", + "integrity": "sha512-Plu6V8fF/XU6d2k8jPtlQf5F4Xx2hAin4r2C2ca7wR8NK5MbRTo9huLUWRe28f3Uk8bYZfg74tit/dSjc18xnw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.0.23" + "tldts-core": "^7.0.21" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.0.23", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.23.tgz", - "integrity": "sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ==", + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.21.tgz", + "integrity": "sha512-oVOMdHvgjqyzUZH1rOESgJP1uNe2bVrfK0jUHHmiM2rpEiRbf3j4BrsIc6JigJRbHGanQwuZv/R+LTcHsw+bLA==", "dev": true, "license": "MIT" }, - "node_modules/tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -23159,7 +23683,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.6" @@ -23300,6 +23823,15 @@ "dev": true, "license": "0BSD" }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "license": "MIT", + "engines": { + "node": ">=0.6.x" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -23442,7 +23974,6 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, "license": "Apache-2.0", "peer": true, "bin": { @@ -23483,7 +24014,7 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -23850,7 +24381,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -23892,7 +24422,6 @@ "version": "6.4.1", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", - "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", @@ -24031,9 +24560,9 @@ } }, "node_modules/vite-plugin-eslint/node_modules/rollup": { - "version": "2.80.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz", - "integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, "license": "MIT", "bin": { @@ -24085,9 +24614,9 @@ } }, "node_modules/vite-plugin-svgr/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -24101,7 +24630,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -24116,10 +24644,9 @@ } }, "node_modules/vite/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", "engines": { "node": ">=12" @@ -24207,9 +24734,9 @@ } }, "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -24268,9 +24795,9 @@ } }, "node_modules/webpack": { - "version": "5.105.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.2.tgz", - "integrity": "sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==", + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", "dev": true, "license": "MIT", "peer": true, @@ -24318,9 +24845,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", - "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "dev": true, "license": "MIT", "peer": true, @@ -24364,9 +24891,9 @@ } }, "node_modules/webpack/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "peer": true, @@ -24482,7 +25009,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -24610,59 +25136,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -24684,11 +25157,17 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ws": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package.json b/package.json index 107eafb65a..b776b581b9 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "homepage": "/mlrun", "dependencies": { "@dagrejs/dagre": "^1.1.5", + "@module-federation/runtime": "^0.23.0", + "@module-federation/vite": "^1.2.6", "@monaco-editor/react": "^4.7.0", "@reduxjs/toolkit": "^1.9.5", "axios": "1.13.5", @@ -16,6 +18,7 @@ "concurrently": "^6.4.2", "cronstrue": "^2.49.0", "dotenv": "^10.0.0", + "dotenv-cli": "^10.0.0", "dotenv-expand": "^5.1.0", "file-saver": "^2.0.5", "final-form": "^4.20.10", @@ -35,6 +38,7 @@ "qs": "^6.15.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-error-boundary": "^6.1.0", "react-final-form": "^6.5.9", "react-final-form-arrays": "^3.1.4", "react-modal-promise": "^1.0.2", @@ -67,6 +71,7 @@ "scripts": { "start": "vite", "build": "vite build", + "preview:federation": "cross-env PREVIEW_MODE=true dotenv -e .env.development.mf -- vite build && node scripts/previewLocalBuildMF.mjs", "lint": "eslint \"src/**/*.{js,jsx}\"", "lint:fix": "eslint \"src/**/*.{js,jsx}\" --fix", "format:check": "prettier --check \"src/**/*.{js,jsx}\"", @@ -75,6 +80,7 @@ "preinstall": "npx force-resolutions", "test:coverage": "npm run test -- --coverage --watchAll=false", "docker": "docker build -t ${MLRUN_DOCKER_REGISTRY}${MLRUN_DOCKER_REPO:-mlrun}/mlrun-ui:${MLRUN_DOCKER_TAG:-latest} --build-arg COMMIT_HASH=\"`git rev-parse --short HEAD`\" --build-arg DATE=\"`date -u`\" -f Dockerfile .", + "docker:mf": "docker buildx build --platform linux/amd64 -t ${MLRUN_DOCKER_REGISTRY}${MLRUN_DOCKER_REPO:-mlrun}/mlrun-ui:${MLRUN_DOCKER_TAG:-latest} --build-arg COMMIT_HASH=\"`git rev-parse --short HEAD`\" --build-arg DATE=\"`date -u`\" -f Dockerfile.mf .", "generate-rn": "./generate-release-notes.js ${MLRUN_OLD_VERSION} ${MLRUN_VERSION} ${MLRUN_RELEASE_BRANCH} ${MLRUN_RELEASE_TYPE}", "storybook": "start-storybook -p 6006", "build-storybook": "build-storybook", diff --git a/public/config.json b/public/config.json index 8d111a5c0b..cc2b881b35 100644 --- a/public/config.json +++ b/public/config.json @@ -1,5 +1,6 @@ { "betaMode": "enabled", "nuclioMode": "enabled", - "nuclioUiUrl": "http://localhost:8070" + "nuclioUiUrl": "http://localhost:8070", + "nuclioRemoteEntryUrl": "http://localhost:5189" } diff --git a/public/landing.html b/public/landing.html new file mode 100644 index 0000000000..3872792cf4 --- /dev/null +++ b/public/landing.html @@ -0,0 +1,59 @@ + + + + + + MLRun UI + + + +
+

MLRun Remote UI

+

This is a remote module component.

+

Please access it via the main Iguazio Dashboard.

+
+ + diff --git a/scripts/previewLocalBuildMF.mjs b/scripts/previewLocalBuildMF.mjs new file mode 100644 index 0000000000..f1ac97f363 --- /dev/null +++ b/scripts/previewLocalBuildMF.mjs @@ -0,0 +1,9 @@ +import { spawn } from 'child_process' + +const preview = spawn( + 'dotenv', + ['-e', '.env.development.mf', '--', 'vite', 'preview', '--port', '5179'], + { stdio: 'inherit', shell: true } +) + +preview.on('exit', code => process.exit(code ?? 0)) diff --git a/src/App.jsx b/src/App.jsx index 77dfeccb37..2badccb840 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -63,81 +63,125 @@ import { JOBS_MONITORING_JOBS_TAB, JOBS_MONITORING_WORKFLOWS_TAB, JOBS_MONITORING_SCHEDULED_TAB, - INACTIVE_JOBS_TAB + INACTIVE_JOBS_TAB, + IS_MF_MODE } from './constants' import 'reactflow/dist/style.css' import 'igz-controls/index.css' import './scss/main.scss' +import RemoteNuclioRouteWrapper from './components/RemoteNuclio/RemoteNuclioRouteWrapper' -const Page = lazyRetry(() => import('./layout/Page/Page')) -const Datasets = lazyRetry(() => import('./components/Datasets/Datasets')) -const FeatureStore = lazyRetry(() => import('./components/FeatureStore/FeatureStore')) -const Files = lazyRetry(() => import('./components/Files/Files')) -const FunctionsOld = lazyRetry(() => import('./components/FunctionsPageOld/FunctionsOld')) // todo [functionsWithPagination] delete FunctionsOld and other related logic in 1.9.0 -const Functions = lazyRetry(() => import('./components/FunctionsPage/Functions')) -const Jobs = lazyRetry(() => import('./components/Jobs/Jobs')) -const MonitorJobs = lazyRetry(() => import('./components/Jobs/MonitorJobs/MonitorJobs')) +const Page = lazyRetry(() => import('./layout/Page/Page'), 'Page') +const Datasets = lazyRetry(() => import('./components/Datasets/Datasets'), 'Datasets') +const FeatureStore = lazyRetry( + () => import('./components/FeatureStore/FeatureStore'), + 'FeatureStore' +) +const Files = lazyRetry(() => import('./components/Files/Files'), 'Files') +const FunctionsOld = lazyRetry( + () => import('./components/FunctionsPageOld/FunctionsOld'), + 'FunctionsOld' +) // todo [functionsWithPagination] delete FunctionsOld and other related logic in 1.9.0 +const Functions = lazyRetry(() => import('./components/FunctionsPage/Functions'), 'Functions') +const Jobs = lazyRetry(() => import('./components/Jobs/Jobs'), 'Jobs') +const MonitorJobs = lazyRetry( + () => import('./components/Jobs/MonitorJobs/MonitorJobs'), + 'MonitorJobs' +) const MonitorWorkflows = lazyRetry( - () => import('./components/Jobs/MonitorWorkflows/MonitorWorkflows') + () => import('./components/Jobs/MonitorWorkflows/MonitorWorkflows'), + 'MonitorWorkflows' +) +const ScheduledJobs = lazyRetry( + () => import('./components/Jobs/ScheduledJobs/ScheduledJobs'), + 'ScheduledJobs' ) -const ScheduledJobs = lazyRetry(() => import('./components/Jobs/ScheduledJobs/ScheduledJobs')) -const Models = lazyRetry(() => import('./components/ModelsPage/Models/Models')) +const Models = lazyRetry(() => import('./components/ModelsPage/Models/Models'), 'Models') const RealTimePipelines = lazyRetry( - () => import('./components/ModelsPage/RealTimePipelines/RealTimePipelines') + () => import('./components/ModelsPage/RealTimePipelines/RealTimePipelines'), + 'RealTimePipelines' ) const ModelEndpoints = lazyRetry( - () => import('./components/ModelsPage/ModelEndpoints/ModelEndpoints') + () => import('./components/ModelsPage/ModelEndpoints/ModelEndpoints'), + 'ModelEndpoints' +) +const ModelsPage = lazyRetry(() => import('./components/ModelsPage/ModelsPage'), 'ModelsPage') +const Projects = lazyRetry(() => import('./components/ProjectsPage/Projects'), 'Projects') +const ProjectMonitor = lazyRetry( + () => import('./components/Project/ProjectMonitor'), + 'ProjectMonitor' ) -const ModelsPage = lazyRetry(() => import('./components/ModelsPage/ModelsPage')) -const Projects = lazyRetry(() => import('./components/ProjectsPage/Projects')) -const ProjectMonitor = lazyRetry(() => import('./components/Project/ProjectMonitor')) const ConsumerGroupsWrapper = lazyRetry( - () => import('./components/ConsumerGroupsWrapper/ConsumerGroupsWrapper') + () => import('./components/ConsumerGroupsWrapper/ConsumerGroupsWrapper'), + 'ConsumerGroupsWrapper' +) +const ConsumerGroup = lazyRetry( + () => import('./components/ConsumerGroup/ConsumerGroup'), + 'ConsumerGroup' +) +const ConsumerGroups = lazyRetry( + () => import('./components/ConsumerGroups/ConsumerGroups'), + 'ConsumerGroups' ) -const ConsumerGroup = lazyRetry(() => import('./components/ConsumerGroup/ConsumerGroup')) -const ConsumerGroups = lazyRetry(() => import('./components/ConsumerGroups/ConsumerGroups')) const ProjectOverview = lazyRetry( - () => import('./components/Project/ProjectOverview/ProjectOverview') + () => import('./components/Project/ProjectOverview/ProjectOverview'), + 'ProjectOverview' +) +const ProjectSettings = lazyRetry( + () => import('./components/ProjectSettings/ProjectSettings'), + 'ProjectSettings' ) -const ProjectSettings = lazyRetry(() => import('./components/ProjectSettings/ProjectSettings')) const AddToFeatureVectorPage = lazyRetry( - () => import('./components/AddToFeatureVectorPage/AddToFeatureVectorPage') + () => import('./components/AddToFeatureVectorPage/AddToFeatureVectorPage'), + 'AddToFeatureVectorPage' +) +const FeatureSets = lazyRetry( + () => import('./components/FeatureStore/FeatureSets/FeatureSets'), + 'FeatureSets' ) -const FeatureSets = lazyRetry(() => import('./components/FeatureStore/FeatureSets/FeatureSets')) -const Features = lazyRetry(() => import('./components/FeatureStore/Features/Features')) +const Features = lazyRetry(() => import('./components/FeatureStore/Features/Features'), 'Features') const FeatureVectors = lazyRetry( - () => import('./components/FeatureStore/FeatureVectors/FeatureVectors') + () => import('./components/FeatureStore/FeatureVectors/FeatureVectors'), + 'FeatureVectors' ) const ProjectsJobsMonitoring = lazyRetry( - () => import('./components/ProjectsJobsMonitoring/ProjectsJobsMonitoring') + () => import('./components/ProjectsJobsMonitoring/ProjectsJobsMonitoring'), + 'ProjectsJobsMonitoring' ) -const ProjectsAlerts = lazyRetry(() => import('./components/Alerts/Alerts')) +const ProjectsAlerts = lazyRetry(() => import('./components/Alerts/Alerts'), 'ProjectsAlerts') const JobsMonitoring = lazyRetry( - () => import('./components/ProjectsJobsMonitoring/JobsMonitoring/JobsMonitoring') + () => import('./components/ProjectsJobsMonitoring/JobsMonitoring/JobsMonitoring'), + 'JobsMonitoring' ) const ScheduledMonitoring = lazyRetry( - () => import('./components/ProjectsJobsMonitoring/ScheduledMonitoring/ScheduledMonitoring') + () => import('./components/ProjectsJobsMonitoring/ScheduledMonitoring/ScheduledMonitoring'), + 'ScheduledMonitoring' ) const WorkflowsMonitoring = lazyRetry( - () => import('./components/ProjectsJobsMonitoring/WorkflowsMonitoring/WorkflowsMonitoring') + () => import('./components/ProjectsJobsMonitoring/WorkflowsMonitoring/WorkflowsMonitoring'), + 'WorkflowsMonitoring' ) -const Documents = lazyRetry(() => import('./components/Documents/Documents')) -const LLMPrompts = lazyRetry(() => import('./components/LLMPrompts/LLMPrompts')) +const Documents = lazyRetry(() => import('./components/Documents/Documents'), 'Documents') +const LLMPrompts = lazyRetry(() => import('./components/LLMPrompts/LLMPrompts'), 'LLMPrompts') const ApplicationMetrics = lazyRetry( - () => import('./components/ApplicationMetrics/ApplicationMetrics') + () => import('./components/ApplicationMetrics/ApplicationMetrics'), + 'ApplicationMetrics' ) const MonitoringApplicationsPage = lazyRetry( - () => import('./components/MonitoringApplicationsPage/MonitoringApplicationsPage') + () => import('./components/MonitoringApplicationsPage/MonitoringApplicationsPage'), + 'MonitoringApplicationsPage' ) const MonitoringApplications = lazyRetry( () => - import('./components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplications') + import('./components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplications'), + 'MonitoringApplications' ) const MonitoringApplication = lazyRetry( () => - import('./components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication') + import('./components/MonitoringApplicationsPage/MonitoringApplications/MonitoringApplication/MonitoringApplication'), + 'MonitoringApplication' ) const App = () => { @@ -158,6 +202,14 @@ const App = () => { <> }> } /> + {IS_MF_MODE && ( + + } /> + } /> + } /> + } /> + + )} }> {[ `${JOBS_MONITORING_JOBS_TAB}/:jobName/:jobId/:tab`, @@ -184,7 +236,6 @@ const App = () => { } /> } /> - } /> } /> {[ diff --git a/src/api/jobs-api.js b/src/api/jobs-api.js index 34da1baddc..bd5686840b 100644 --- a/src/api/jobs-api.js +++ b/src/api/jobs-api.js @@ -19,7 +19,7 @@ such restriction. */ import { isNil } from 'lodash' -import { mainBaseUrl, mainHttpClient } from '../httpClient' +import { mainHttpClient } from '../httpClient' const jobsApi = { abortJob: (project, jobId, iter) => { @@ -76,10 +76,17 @@ const jobsApi = { params = `?attempt=${attempt}` } - return fetch(`${mainBaseUrl}/projects/${project}/logs/${id}${params}`, { - method: 'get', - signal - }) + // when we use adapter: 'fetch' in axios, we need to pass params as query string, because axios drops params in this case + const queryParams = new URLSearchParams(params).toString() + + return mainHttpClient.get( + `/projects/${project}/logs/${id}${queryParams ? '?' + queryParams : ''}`, + { + signal, + responseType: 'stream', + adapter: 'fetch' + } + ) }, getScheduledJobs: (project, newConfig) => { return mainHttpClient.get(`/projects/${project}/schedules`, newConfig) diff --git a/src/api/projects-iguazio-api.js b/src/api/projects-iguazio-api.js index edc7d3c702..2648eaf8fe 100644 --- a/src/api/projects-iguazio-api.js +++ b/src/api/projects-iguazio-api.js @@ -19,51 +19,51 @@ such restriction. */ import { iguazioHttpClient } from '../httpClient' -const projectsIguazioApi = { +const igz3Api = { editProject: (projectId, data) => iguazioHttpClient.put(`/projects/${projectId}`, data), getProjectJob: jobId => iguazioHttpClient.get(`/jobs/${jobId}`), - getProjects: config => { - return iguazioHttpClient.get('/projects', config) - }, - getProjectMembers: projectId => { - return iguazioHttpClient.get(`/projects/${projectId}`, { + getProjects: config => iguazioHttpClient.get('/projects', config), + getProjectMembers: projectId => + iguazioHttpClient.get(`/projects/${projectId}`, { params: { include: 'project_authorization_roles.principal_users,project_authorization_roles.principal_user_groups' } - }) - }, - getProjectMembersVisibility: project => { - return iguazioHttpClient.get(`/projects/__name__/${project}/authorization`, { - params: { - action: 'authorization/roles', - sub_resource: 'authorization/roles' - } - }) - }, - getProjectOwnerVisibility: project => { - return iguazioHttpClient.get(`/projects/__name__/${project}/authorization`, { - params: { - action: 'update', - sub_resource: 'authorization/owner' - } - }) - }, - getProjectWorkflowsUpdateAuthorization: project => { - return iguazioHttpClient.get(`/projects/__name__/${project}/authorization`, { - params: { - action: 'update', - sub_resource: 'workflow' - } - }) - }, - - updateProjectMembers: data => { - return iguazioHttpClient.post('/async_transactions', data) - }, + }), + getProjectMembersVisibility: project => + iguazioHttpClient.get(`/projects/__name__/${project}/authorization`, { + params: { action: 'authorization/roles', sub_resource: 'authorization/roles' } + }), + getProjectOwnerVisibility: project => + iguazioHttpClient.get(`/projects/__name__/${project}/authorization`, { + params: { action: 'update', sub_resource: 'authorization/owner' } + }), + getProjectWorkflowsUpdateAuthorization: project => + iguazioHttpClient.get(`/projects/__name__/${project}/authorization`, { + params: { action: 'update', sub_resource: 'workflow' } + }), + updateProjectMembers: data => iguazioHttpClient.post('/async_transactions', data), getScrubbedUsers: config => iguazioHttpClient.get('/scrubbed_users', config), getScrubbedUserGroups: config => iguazioHttpClient.get('/scrubbed_user_groups', config), getActiveUser: () => iguazioHttpClient.get('/self') } -export default projectsIguazioApi +const igz4Api = { + updateProjectOwner: (projectName, owner) => + iguazioHttpClient.put(`/v1/authorization/projects/${projectName}/owner`, { + owner, + project: projectName + }), + getProjectPolicies: projectName => + iguazioHttpClient.get(`/v1/authorization/projects/${projectName}/policies`), + setProjectMembership: (projectName, data) => + iguazioHttpClient.put(`/v1/authorization/projects/${projectName}/roles`, data), + searchUsersMetadata: searchTerm => + iguazioHttpClient.get('/v1/profile/search-users-metadata', { params: { searchTerm } }), + searchGroupsMetadata: searchTerm => + iguazioHttpClient.get('/v1/profile/search-groups-metadata', { params: { searchTerm } }), + getActiveUser: () => + iguazioHttpClient.get('/v1/authentication/self', { params: { format: 'full' } }) +} + +export default import.meta.env.VITE_FEDERATION === 'true' ? igz4Api : igz3Api diff --git a/src/common/Breadcrumbs/breadcrumbs.util.js b/src/common/Breadcrumbs/breadcrumbs.util.js index f09aa4bbd2..03620e6c90 100644 --- a/src/common/Breadcrumbs/breadcrumbs.util.js +++ b/src/common/Breadcrumbs/breadcrumbs.util.js @@ -35,7 +35,8 @@ import { PROJECTS_PAGE_PATH, MONITORING_APP_PAGE, DOCUMENTS_PAGE, - LLM_PROMPTS_PAGE + LLM_PROMPTS_PAGE, + IS_MF_MODE } from '../../constants' import { generateNuclioLink } from '../../utils' @@ -60,16 +61,20 @@ export const generateMlrunScreens = params => { label: 'Monitoring app', id: MONITORING_APP_PAGE }, { label: 'Jobs and workflows', id: 'jobs' }, { label: 'ML functions', id: 'functions' }, - { - label: 'Real-time functions', - id: 'Real-time functions', - link: generateNuclioLink(`/projects/${params.projectName}/functions`) - }, - { - label: 'API gateways', - id: 'API gateways', - link: generateNuclioLink(`/projects/${params.projectName}/api-gateways`) - }, + IS_MF_MODE + ? { label: 'Real-time functions', id: 'real-time-functions' } + : { + label: 'Real-time functions', + id: 'Real-time functions', + link: generateNuclioLink(`/projects/${params.projectName}/functions`) + }, + IS_MF_MODE + ? { label: 'API gateways', id: 'api-gateways' } + : { + label: 'API gateways', + id: 'API gateways', + link: generateNuclioLink(`/projects/${params.projectName}/api-gateways`) + }, { label: 'Alerts', id: ALERTS_PAGE_PATH, diff --git a/src/common/Download/Download.jsx b/src/common/Download/Download.jsx index 2789e10b0c..145bd9d8e9 100644 --- a/src/common/Download/Download.jsx +++ b/src/common/Download/Download.jsx @@ -48,8 +48,8 @@ const Download = ({ () => disabled || !path || - (artifactLimits?.max_download_size && fileSize > artifactLimits.max_download_size), - [disabled, artifactLimits.max_download_size, fileSize, path] + (artifactLimits?.max_download_size && fileSize > artifactLimits?.max_download_size), + [disabled, artifactLimits?.max_download_size, fileSize, path] ) const downloadClassNames = classnames( 'download', diff --git a/src/components/Datasets/datasets.util.jsx b/src/components/Datasets/datasets.util.jsx index be254d15cf..3003f9d074 100644 --- a/src/components/Datasets/datasets.util.jsx +++ b/src/components/Datasets/datasets.util.jsx @@ -176,7 +176,7 @@ export const generateActionsMenu = ( disabled: !isTargetPathValid || datasetMin.size > - (frontendSpec.artifact_limits.max_download_size ?? ARTIFACT_MAX_DOWNLOAD_SIZE), + (frontendSpec.artifact_limits?.max_download_size ?? ARTIFACT_MAX_DOWNLOAD_SIZE), icon: , onClick: datasetMin => { getFullDataset(datasetMin).then(dataset => { diff --git a/src/components/Details/details.util.js b/src/components/Details/details.util.js index 5fa49e7b9f..982ce421d5 100644 --- a/src/components/Details/details.util.js +++ b/src/components/Details/details.util.js @@ -40,7 +40,9 @@ import { FUNCTION_TYPE_LOCAL, MODEL_ENDPOINTS_TAB, MODELS_TAB, - TAG_LATEST + TAG_LATEST, + IS_MF_MODE, + NUCLIO_FUNCTIONS_PATH } from '../../constants' import { generateLinkPath, generateNuclioLink, parseUri } from '../../utils' import { getFunctionImage } from '../FunctionsPage/functions.util' @@ -314,8 +316,10 @@ export const generateRealTimePipelinesContent = selectedItem => { value: selectedItem.name, status: selectedItem.state.value, className: selectedItem.state.className, - link: generateNuclioLink(`/projects/${selectedItem.project}/functions/${nuclioFunctionName}`), - linkIsExternal: true + link: generateNuclioLink( + `/projects/${selectedItem.project}/${NUCLIO_FUNCTIONS_PATH}/${nuclioFunctionName}` + ), + linkIsExternal: !IS_MF_MODE }, childFunction: { value: selectedItem.childFunctions ?? selectedItem.function_refs ?? [], diff --git a/src/components/JobWizard/JobWizard.jsx b/src/components/JobWizard/JobWizard.jsx index 779234c451..2afb533317 100644 --- a/src/components/JobWizard/JobWizard.jsx +++ b/src/components/JobWizard/JobWizard.jsx @@ -54,7 +54,8 @@ import { PARAMETERS_STEP, RESOURCES_STEP, RUN_DETAILS_STEP, - SCHEDULE_TAB + SCHEDULE_TAB, + IS_MF_MODE } from '../../constants' import { generateJobRequestData, @@ -363,14 +364,13 @@ const JobWizard = ({ mode, true ) - const credentials = jobRequestData.function?.metadata?.credentials - - delete jobRequestData.function.metadata + const credentials = IS_MF_MODE ? null : jobRequestData.function?.metadata?.credentials + if (!IS_MF_MODE) delete jobRequestData.function.metadata dispatch( editJob({ postData: { - credentials, + ...(credentials && { credentials }), scheduled_object: jobRequestData, cron_trigger: jobRequestData.schedule }, diff --git a/src/components/JobWizard/JobWizard.util.js b/src/components/JobWizard/JobWizard.util.js index e3e596b06e..1f2b7aa3d1 100644 --- a/src/components/JobWizard/JobWizard.util.js +++ b/src/components/JobWizard/JobWizard.util.js @@ -42,6 +42,7 @@ import { EXISTING_IMAGE_SOURCE, FUNCTION_DEFAULT_HANDLER, HYPERPARAMETER_STRATEGY_STEP, + IS_MF_MODE, JOB_DEFAULT_OUTPUT_PATH, LIST_TUNING_STRATEGY, MAX_SELECTOR_CRITERIA, @@ -167,12 +168,12 @@ export const generateJobWizardData = ( }, [ADVANCED_STEP]: { inputPath: null, - outputPath: - currentProject?.spec?.artifact_path || - (frontendSpec.ce?.version && frontendSpec.default_artifact_path) || - JOB_DEFAULT_OUTPUT_PATH, - accessKey: true, - accessKeyInput: '', + outputPath: IS_MF_MODE + ? currentProject?.spec?.artifact_path || frontendSpec.default_artifact_path + : currentProject?.spec?.artifact_path || + (frontendSpec.ce?.version && frontendSpec.default_artifact_path) || + JOB_DEFAULT_OUTPUT_PATH, + ...(IS_MF_MODE ? { apiTokenInput: 'default' } : { accessKey: true, accessKeyInput: '' }), environmentVariablesTable: parseEnvironmentVariables(environmentVariables) // secretSourcesTable - currently not shown // secretSourcesTable: [] @@ -290,12 +291,16 @@ export const generateJobWizardDefaultData = ( [ADVANCED_STEP]: { inputPath: defaultData.task.spec.input_path, outputPath: defaultData.task.spec.output_path, - accessKey: - defaultData.function?.metadata?.credentials?.access_key === PANEL_DEFAULT_ACCESS_KEY, - accessKeyInput: - defaultData.function?.metadata?.credentials?.access_key === PANEL_DEFAULT_ACCESS_KEY - ? '' - : defaultData.function?.metadata?.credentials?.access_key, + ...(IS_MF_MODE + ? { apiTokenInput: defaultData.task.spec?.auth?.token_name ?? '' } + : { + accessKey: + defaultData.function?.metadata?.credentials?.access_key === PANEL_DEFAULT_ACCESS_KEY, + accessKeyInput: + defaultData.function?.metadata?.credentials?.access_key === PANEL_DEFAULT_ACCESS_KEY + ? '' + : defaultData.function?.metadata?.credentials?.access_key + }), environmentVariablesTable: parseEnvironmentVariables(defaultData.function?.spec?.env ?? []) // secretSourcesTable - currently not shown // secretSourcesTable: parseSecretSources(defaultData.task.spec.secret_sources) @@ -1025,6 +1030,10 @@ export const generateJobRequestData = ( labels: convertChipsData(labels) }, spec: { + ...(IS_MF_MODE && + formData[ADVANCED_STEP].apiTokenInput && { + auth: { token_name: formData[ADVANCED_STEP].apiTokenInput } + }), inputs: generateDataInputs(formData[DATA_INPUTS_STEP].dataInputsTable), parameters: generateParameters(formData[PARAMETERS_STEP].parametersTable), // secretSourcesTable - currently not shown @@ -1044,13 +1053,15 @@ export const generateJobRequestData = ( } }, function: { - metadata: { - credentials: { - access_key: formData[ADVANCED_STEP].accessKey - ? PANEL_DEFAULT_ACCESS_KEY - : formData[ADVANCED_STEP].accessKeyInput + ...(!IS_MF_MODE && { + metadata: { + credentials: { + access_key: formData[ADVANCED_STEP].accessKey + ? PANEL_DEFAULT_ACCESS_KEY + : formData[ADVANCED_STEP].accessKeyInput + } } - }, + }), spec: { image: formData[RUN_DETAILS_STEP].image?.imageSource === EXISTING_IMAGE_SOURCE diff --git a/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/JobWizardAdvanced.jsx b/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/JobWizardAdvanced.jsx index af40a04ab6..ea00869ac6 100644 --- a/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/JobWizardAdvanced.jsx +++ b/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/JobWizardAdvanced.jsx @@ -24,7 +24,7 @@ import { useSelector } from 'react-redux' import FormEnvironmentVariablesTable from '../../../../elements/FormEnvironmentVariablesTable/FormEnvironmentVariablesTable' import { FormCheckBox, FormInput, FormKeyValueTable, FormOnChange } from 'igz-controls/components' -import { ADVANCED_STEP } from '../../../../constants' +import { ADVANCED_STEP, API_TOKEN_TIP, IS_MF_MODE } from '../../../../constants' import { secretsKindOptions } from './JobWizardAdvanced.util' import './jobWizardAdvanced.scss' @@ -73,19 +73,35 @@ const JobWizardAdvanced = ({ formState, stepIsActive = false }) => { -
- {!frontendSpec.ce?.version && ( -
- -
- )} - {!formState.values?.[ADVANCED_STEP]?.accessKey && ( -
- -
- )} -
- {stepIsActive && ( + {!frontendSpec.ce?.version && ( +
+ {IS_MF_MODE ? ( +
+ +
+ ) : ( + <> +
+ +
+ {!formState.values?.[ADVANCED_STEP]?.accessKey && ( +
+ +
+ )} + + )} +
+ )} + {!IS_MF_MODE && formState.values?.[ADVANCED_STEP] !== undefined && stepIsActive && ( formState.form.change(`${ADVANCED_STEP}.accessKeyInput`, '')} name={`${ADVANCED_STEP}.accessKey`} diff --git a/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/jobWizardAdvanced.scss b/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/jobWizardAdvanced.scss index d4dbe92516..0a183a6a5f 100644 --- a/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/jobWizardAdvanced.scss +++ b/src/components/JobWizard/JobWizardSteps/JobWizardAdvanced/jobWizardAdvanced.scss @@ -2,4 +2,9 @@ .access-key-checkbox { margin: 30px 10px 0 10px; } + + .api-token-field { + display: flex; + align-items: center; + } } diff --git a/src/components/Jobs/jobs.util.js b/src/components/Jobs/jobs.util.js index deaeb4d74b..8dfc514bf5 100644 --- a/src/components/Jobs/jobs.util.js +++ b/src/components/Jobs/jobs.util.js @@ -41,6 +41,7 @@ import { COMPLETED_STATE, ABORTED_STATE, ABORTING_STATE, + IS_MF_MODE, PENDING_RETRY_STATE } from '../../constants' import { @@ -177,11 +178,13 @@ const generateEditableItem = (functionData, job) => { return { rerun_object: { function: { - metadata: { - credentials: { - access_key: functionData?.metadata?.credentials?.access_key ?? '' + ...(!IS_MF_MODE && { + metadata: { + credentials: { + access_key: functionData?.metadata?.credentials?.access_key ?? '' + } } - }, + }), spec: { env: functionData?.spec.env ?? [], resources: functionData?.spec.resources, @@ -200,6 +203,7 @@ const generateEditableItem = (functionData, job) => { project: job.project }, spec: { + ...(IS_MF_MODE && job.auth?.token_name && { auth: { token_name: job.auth.token_name } }), hyper_param_options: job.hyper_param_options, function: job.function, handler: job?.handler ?? '', diff --git a/src/components/LLMPrompts/llmPrompts.util.jsx b/src/components/LLMPrompts/llmPrompts.util.jsx index f10cdc8a23..c02e782cee 100644 --- a/src/components/LLMPrompts/llmPrompts.util.jsx +++ b/src/components/LLMPrompts/llmPrompts.util.jsx @@ -143,7 +143,7 @@ export const generateActionsMenu = ( disabled: !isTargetPathValid || llmPromptMin.size > - (frontendSpec.artifact_limits.max_download_size ?? ARTIFACT_MAX_DOWNLOAD_SIZE), + (frontendSpec.artifact_limits?.max_download_size ?? ARTIFACT_MAX_DOWNLOAD_SIZE), icon: , onClick: llmPromptMin => { getFullLLMPrompt(llmPromptMin).then(llmPrompt => { diff --git a/src/components/MonitoringApplicationsPage/MonitoringApplications/monitoringApplications.util.js b/src/components/MonitoringApplicationsPage/MonitoringApplications/monitoringApplications.util.js index 0030cddf53..0522b327e5 100644 --- a/src/components/MonitoringApplicationsPage/MonitoringApplications/monitoringApplications.util.js +++ b/src/components/MonitoringApplicationsPage/MonitoringApplications/monitoringApplications.util.js @@ -21,6 +21,7 @@ import classnames from 'classnames' import moment from 'moment' import { generateNuclioLink } from '../../../utils' +import { IS_MF_MODE, NUCLIO_FUNCTIONS_PATH } from '../../../constants' import { formatDatetime } from 'igz-controls/utils/datetime.util' export const generateOperatingFunctionsTable = (functions, projectName) => { @@ -52,7 +53,9 @@ export const generateOperatingFunctionsTable = (functions, projectName) => { return { name: { value: func.name, - href: generateNuclioLink(`/projects/${projectName}/functions/${nuclioFunctionName}`), + [IS_MF_MODE ? 'link' : 'href']: generateNuclioLink( + `/projects/${projectName}/${NUCLIO_FUNCTIONS_PATH}/${nuclioFunctionName}` + ), className: 'table-cell_big' }, status: { diff --git a/src/components/Project/ProjectOverview/ProjectOverview.util.jsx b/src/components/Project/ProjectOverview/ProjectOverview.util.jsx index ba917a7a29..f04649e4a4 100644 --- a/src/components/Project/ProjectOverview/ProjectOverview.util.jsx +++ b/src/components/Project/ProjectOverview/ProjectOverview.util.jsx @@ -23,7 +23,7 @@ import JobWizard from '../../JobWizard/JobWizard' import RegisterArtifactModal from '../../RegisterArtifactModal/RegisterArtifactModal' import RegisterModelModal from '../../../elements/RegisterModelModal/RegisterModelModal' -import { ARTIFACT_TYPE, DATASET_TYPE } from '../../../constants' +import { ARTIFACT_TYPE, DATASET_TYPE, IS_MF_MODE, NUCLIO_FUNCTIONS_PATH } from '../../../constants' import { PRIMARY_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' import { generateNuclioLink } from '../../../utils' import { isSubmitDisabled } from 'igz-controls/utils/form.util' @@ -392,8 +392,10 @@ export const getInitialCards = (params, navigate, isDemoMode) => { icon: , label: 'Create real-time function', handleClick: () => ({ - path: generateNuclioLink(`${base_url}/create-function`), - externalLink: true + path: IS_MF_MODE + ? `/projects/${params.projectName}/${NUCLIO_FUNCTIONS_PATH}/create-function` + : generateNuclioLink(`/projects/${params.projectName}/create-function`), + externalLink: !IS_MF_MODE }), tooltip: 'These are typically used for serving, APIs, and stream processing. Specify the code, resources, and triggers.' @@ -464,8 +466,8 @@ export const getInitialCards = (params, navigate, isDemoMode) => { { id: 'nuclioFunctions', handleClick: () => ({ - path: generateNuclioLink(`${base_url}/functions`), - externalLink: true + path: generateNuclioLink(`${base_url}/${NUCLIO_FUNCTIONS_PATH}`), + externalLink: !IS_MF_MODE }), label: 'Nuclio functions' }, diff --git a/src/components/Project/project.utils.jsx b/src/components/Project/project.utils.jsx index 81ba1719dc..2091bce9b4 100644 --- a/src/components/Project/project.utils.jsx +++ b/src/components/Project/project.utils.jsx @@ -21,7 +21,7 @@ import React from 'react' import JobWizard from '../JobWizard/JobWizard' -import { ARTIFACT_TYPE, DATASET_TYPE } from '../../constants' +import { ARTIFACT_TYPE, DATASET_TYPE, IS_MF_MODE, NUCLIO_FUNCTIONS_PATH } from '../../constants' import { PRIMARY_BUTTON, FORBIDDEN_ERROR_STATUS_CODE } from 'igz-controls/constants' import { showErrorNotification } from 'igz-controls/utils/notification.util' @@ -114,7 +114,11 @@ export const generateCreateNewOptions = ( id: 'createRealTimeFunction', icon: , handler: () => { - const url = generateNuclioLink(`/projects/${params.projectName}/create-function`) + if (IS_MF_MODE) { + return navigate(`/projects/${params.projectName}/${NUCLIO_FUNCTIONS_PATH}/create-function`) + } + + const url = generateNuclioLink(`/projects/${params.projectName}}/create-function`) if (window.top && window.top !== window.self) { window.top.location.assign(url) diff --git a/src/components/ProjectSettings/ProjectSettings.jsx b/src/components/ProjectSettings/ProjectSettings.jsx index 5d75f70f82..aa174016da 100644 --- a/src/components/ProjectSettings/ProjectSettings.jsx +++ b/src/components/ProjectSettings/ProjectSettings.jsx @@ -44,6 +44,7 @@ import projectsIguazioApi from '../../api/projects-iguazio-api' import { DANGER_BUTTON, TERTIARY_BUTTON } from 'igz-controls/constants' import { COMPLETED_STATE, + IS_MF_MODE, PROJECTS_SETTINGS_MEMBERS_TAB, PROJECTS_SETTINGS_SECRETS_TAB } from '../../constants' @@ -75,14 +76,36 @@ const ProjectSettings = () => { ) const userIsProjectOwner = useMemo(() => { + if (IS_MF_MODE) { + const activeUsername = membersState?.activeUser?.data?.attributes?.username + const ownerUsername = membersState?.projectInfo?.owner?.username + return Boolean(activeUsername && activeUsername === ownerUsername) + } return membersState?.activeUser?.data?.id === membersState?.projectInfo?.owner.id }, [membersState]) + const userIsSystemAdmin = useMemo( + () => + membersState?.activeUser?.data?.attributes?.user_policies_collection?.has('System Admin') ?? + false, + [membersState?.activeUser?.data?.attributes?.user_policies_collection] + ) + const projectMembersTabIsShown = useMemo( () => isProjectMembersTabShown(projectMembershipIsEnabled, userIsProjectOwner, membersState), [userIsProjectOwner, membersState, projectMembershipIsEnabled] ) + const fetchProjectPolicies = useCallback(() => { + return projectsIguazioApi + .getProjectPolicies(params.projectName) + .then(policiesResponse => generateMembers(policiesResponse, membersDispatch)) + .catch(error => { + showErrorNotification(dispatch, error, 'Failed to fetch project members') + throw error + }) + }, [dispatch, params.projectName]) + const fetchProjectIdAndOwner = useCallback(() => { return projectsIguazioApi .getProjects({ @@ -120,6 +143,7 @@ const ProjectSettings = () => { }, [dispatch] ) + const fetchProjectMembersVisibility = project => { projectsIguazioApi .getProjectMembersVisibility(project) @@ -130,23 +154,58 @@ const ProjectSettings = () => { setProjectMembersIsShown(false) }) } + const fetchActiveUser = () => { projectsIguazioApi.getActiveUser().then(response => { - const activeUser = response.data - activeUser.data.attributes.user_policies_collection = new Set([ - ...activeUser.data.attributes.assigned_policies, - ...(activeUser.included?.reduce?.( - (policies, group) => [...policies, ...group.attributes.assigned_policies], - [] - ) || []) - ]) - - membersDispatch({ - type: membersActions.SET_ACTIVE_USER, - payload: activeUser - }) + if (IS_MF_MODE) { + const activeUser = response.data + const relationships = activeUser.relationships || [] + + const userGroupNames = new Set( + relationships + .filter(rel => rel['@type']?.includes('usergroup')) + .map(rel => rel.spec?.name) + .filter(Boolean) + ) + + const userPoliciesCollection = new Set( + relationships + .filter(rel => rel['@type']?.includes('policy.Policy')) + .map(rel => rel.spec?.displayName) + .filter(Boolean) + ) + + membersDispatch({ + type: membersActions.SET_ACTIVE_USER, + payload: { + data: { + id: activeUser.metadata?.id, + attributes: { + username: activeUser.metadata?.username, + user_policies_collection: userPoliciesCollection, + user_group_names: userGroupNames + } + } + } + }) + } else { + const activeUser = response.data + activeUser.data.attributes.user_policies_collection = new Set([ + ...activeUser.data.attributes.assigned_policies, + ...(activeUser.included?.reduce?.( + (policies, group) => [...policies, ...group.attributes.assigned_policies], + [] + ) || []) + ]) + + membersDispatch({ + type: membersActions.SET_ACTIVE_USER, + payload: activeUser + }) + } }) } + const fetchProjectOwnerVisibility = project => { projectsIguazioApi .getProjectOwnerVisibility(project) @@ -160,39 +219,125 @@ const ProjectSettings = () => { const fetchProjectUsersData = useCallback(() => { if (projectMembershipIsEnabled) { - fetchProjectOwnerVisibility(params.projectName) - fetchProjectIdAndOwner() - .then(({ id: projectId, owner }) => { - fetchActiveUser() - fetchProjectMembersVisibility(params.projectName) + if (IS_MF_MODE) { + fetchActiveUser() - return fetchProjectMembers(projectId, owner) - }) - .catch(() => { - setProjectMembersIsShown(false) - }) - .finally(() => - membersDispatch({ - type: membersActions.GET_PROJECT_USERS_DATA_END + fetchProjectPolicies() + .catch(() => { + setProjectMembersIsShown(false) + setProjectOwnerIsShown(false) }) - ) + .finally(() => + membersDispatch({ + type: membersActions.GET_PROJECT_USERS_DATA_END + }) + ) + } else { + fetchProjectOwnerVisibility(params.projectName) + fetchProjectIdAndOwner() + .then(({ id: projectId, owner }) => { + fetchActiveUser() + fetchProjectMembersVisibility(params.projectName) + + return fetchProjectMembers(projectId, owner) + }) + .catch(() => { + setProjectMembersIsShown(false) + }) + .finally(() => + membersDispatch({ + type: membersActions.GET_PROJECT_USERS_DATA_END + }) + ) + } } - }, [fetchProjectIdAndOwner, fetchProjectMembers, params.projectName, projectMembershipIsEnabled]) - - const changeMembersCallback = (jobId, userIsValid) => { - const fetchJob = () => { - projectsIguazioApi - .getProjectJob(jobId) - .then(response => { - if (response.data.data.attributes.state !== COMPLETED_STATE) { - setTimeout(fetchJob, 1000) - } else { - if (userIsValid) { - fetchProjectMembers(membersState.projectInfo.id, membersState.projectInfo.owner).then( - () => { - membersDispatch({ - type: membersActions.GET_PROJECT_USERS_DATA_END + }, [ + fetchProjectIdAndOwner, + fetchProjectMembers, + fetchProjectPolicies, + params.projectName, + projectMembershipIsEnabled + ]) + + useEffect(() => { + if (!IS_MF_MODE) return + + const activeUsername = membersState?.activeUser?.data?.attributes?.username + const projectId = membersState?.projectInfo?.id + + if (activeUsername && projectId) { + setProjectOwnerIsShown(userIsProjectOwner || userIsSystemAdmin) + setProjectMembersIsShown(projectMembersTabIsShown) + } + }, [ + membersState?.activeUser?.data?.attributes?.username, + membersState?.projectInfo?.id, + userIsProjectOwner, + userIsSystemAdmin, + projectMembersTabIsShown + ]) + + const changeMembersCallback = IS_MF_MODE + ? userIsStillMember => { + membersDispatch({ + type: membersActions.GET_PROJECT_USERS_DATA_BEGIN + }) + + if (userIsStillMember) { + fetchProjectPolicies() + .then(() => { + membersDispatch({ + type: membersActions.GET_PROJECT_USERS_DATA_END + }) + dispatch( + setNotification({ + status: 200, + id: Math.random(), + message: 'Members updated successfully' + }) + ) + }) + .catch(() => { + membersDispatch({ + type: membersActions.GET_PROJECT_USERS_DATA_END + }) + }) + } else { + dispatch( + setNotification({ + status: 200, + id: Math.random(), + message: 'Members updated successfully' + }) + ) + navigate('/projects/') + } + } + : (jobId, userIsValid) => { + const fetchJob = () => { + projectsIguazioApi + .getProjectJob(jobId) + .then(response => { + if (response.data.data.attributes.state !== COMPLETED_STATE) { + setTimeout(fetchJob, 1000) + } else { + if (userIsValid) { + fetchProjectMembers( + membersState.projectInfo.id, + membersState.projectInfo.owner + ).then(() => { + membersDispatch({ + type: membersActions.GET_PROJECT_USERS_DATA_END + }) + dispatch( + setNotification({ + status: 200, + id: Math.random(), + message: 'Members updated successfully' + }) + ) }) + } else { dispatch( setNotification({ status: 200, @@ -200,42 +345,42 @@ const ProjectSettings = () => { message: 'Members updated successfully' }) ) + navigate('/projects/') } - ) - } else { - dispatch( - setNotification({ - status: 200, - id: Math.random(), - message: 'Members updated successfully' - }) - ) - navigate('/projects/') - } - } - }) - .catch(() => { - membersDispatch({ - type: membersActions.GET_PROJECT_USERS_DATA_END - }) - }) - } + } + }) + .catch(() => { + membersDispatch({ + type: membersActions.GET_PROJECT_USERS_DATA_END + }) + }) + } - membersDispatch({ - type: membersActions.GET_PROJECT_USERS_DATA_BEGIN - }) + membersDispatch({ + type: membersActions.GET_PROJECT_USERS_DATA_BEGIN + }) - fetchJob() - } + fetchJob() + } const changeOwnerCallback = () => { - const prevOwner = membersState.projectInfo.owner.id + if (IS_MF_MODE) { + const prevOwnerUsername = membersState.projectInfo.owner.username - return fetchProjectIdAndOwner().then(() => { - if (!membersState.users.some(member => member.id === prevOwner)) { - navigate('/projects/') - } - }) + return fetchProjectPolicies().then(() => { + if (!membersState.members.some(member => member.id === prevOwnerUsername)) { + navigate('/projects/') + } + }) + } else { + const prevOwner = membersState.projectInfo.owner.id + + return fetchProjectIdAndOwner().then(() => { + if (!membersState.users.some(member => member.id === prevOwner)) { + navigate('/projects/') + } + }) + } } const resetProjectData = useCallback(() => { diff --git a/src/components/ProjectSettings/projectSettings.util.jsx b/src/components/ProjectSettings/projectSettings.util.jsx index 81f7bd982d..2b076dbebc 100644 --- a/src/components/ProjectSettings/projectSettings.util.jsx +++ b/src/components/ProjectSettings/projectSettings.util.jsx @@ -23,6 +23,7 @@ import { forEach, groupBy } from 'lodash' import { membersActions } from '../../elements/MembersPopUp/membersReducer' import { + IS_MF_MODE, PROJECTS_SETTINGS_GENERAL_TAB, PROJECTS_SETTINGS_PAGE, PROJECTS_SETTINGS_MEMBERS_TAB, @@ -77,7 +78,69 @@ const addMember = (members, name, id, type, initialRole, role) => { }) } -export const generateMembers = (membersResponse, membersDispatch, owner) => { +const generateMembersMF = (policiesResponse, membersDispatch) => { + const members = [] + const memberSet = new Set() + const policies = policiesResponse.data.items || [] + + membersDispatch({ + type: membersActions.SET_PROJECT_AUTHORIZATION_ROLES, + payload: policies + }) + + const ownerPolicy = policies.find(policy => policy.spec.displayName === OWNER_ROLE) + const ownerMembers = ownerPolicy?.status?.assignedMembers || [] + const ownerMemberIds = new Set(ownerMembers.map(m => m.id)) + const ownerUsername = ownerMembers[0]?.id || '' + + membersDispatch({ + type: membersActions.SET_PROJECT_INFO, + payload: { + id: policies[0]?.spec?.projectName || '', + owner: { id: ownerUsername, username: ownerUsername, firstName: '', lastName: '' } + } + }) + + policies.forEach(policy => { + const roleName = policy.spec.displayName + const assignedMembers = policy.status?.assignedMembers || [] + + assignedMembers.forEach(assignedMember => { + if (memberSet.has(assignedMember.id)) return + + const memberType = assignedMember.kind === USER_ROLE ? USER_ROLE : USER_GROUP_ROLE + const isOwner = ownerMemberIds.has(assignedMember.id) + const effectiveRole = isOwner ? OWNER_ROLE : roleName + + addMember( + members, + assignedMember.id, + assignedMember.id, + memberType, + effectiveRole, + effectiveRole + ) + memberSet.add(assignedMember.id) + }) + }) + + membersDispatch({ + type: membersActions.SET_MEMBERS_ORIGINAL, + payload: members + }) + membersDispatch({ + type: membersActions.SET_MEMBERS, + payload: members + }) +} + +const isOwnerInMembersList = (ownerId, membersList) => { + return membersList.some(member => { + return member.id === ownerId + }) +} + +const generateMembersIGZ3 = (membersResponse, membersDispatch, owner) => { const members = [] const { project_authorization_role: projectAuthorizationRoles = [], @@ -86,6 +149,7 @@ export const generateMembers = (membersResponse, membersDispatch, owner) => { } = groupBy(membersResponse.data.included, includeItem => { return includeItem.type }) + membersDispatch({ type: membersActions.SET_PROJECT_AUTHORIZATION_ROLES, payload: projectAuthorizationRoles @@ -129,6 +193,7 @@ export const generateMembers = (membersResponse, membersDispatch, owner) => { }) } }) + membersDispatch({ type: membersActions.SET_MEMBERS_ORIGINAL, payload: members @@ -139,6 +204,8 @@ export const generateMembers = (membersResponse, membersDispatch, owner) => { }) } +export const generateMembers = IS_MF_MODE ? generateMembersMF : generateMembersIGZ3 + export const isProjectMembersTabShown = ( projectMembershipIsEnabled, userIsProjectOwner, @@ -150,21 +217,27 @@ export const isProjectMembersTabShown = ( const userIsProjectSecurityAdmin = activeUser.data?.attributes?.user_policies_collection?.has('Project Security Admin') ?? false - const userIsAdmin = members.some( - member => - member.role === ADMIN_ROLE && - (member.id === activeUser.data?.id || - (member.type === USER_GROUP_ROLE && - activeUser.data?.relationships?.user_groups?.data?.some?.( - group => group.id === member.id - ))) - ) - return userIsProjectOwner || userIsAdmin || userIsProjectSecurityAdmin -} + const userIsAdmin = IS_MF_MODE + ? (() => { + const activeUsername = activeUser.data?.attributes?.username + return members.some( + member => + member.role === ADMIN_ROLE && + (member.id === activeUsername || + (member.type === USER_GROUP_ROLE && + activeUser.data?.attributes?.user_group_names?.has(member.id))) + ) + })() + : members.some( + member => + member.role === ADMIN_ROLE && + (member.id === activeUser.data?.id || + (member.type === USER_GROUP_ROLE && + activeUser.data?.relationships?.user_groups?.data?.some?.( + group => group.id === member.id + ))) + ) -const isOwnerInMembersList = (ownerId, membersList) => { - return membersList.some(member => { - return member.id === ownerId - }) + return userIsProjectOwner || userIsAdmin || userIsProjectSecurityAdmin } diff --git a/src/components/ProjectsPage/projects.util.jsx b/src/components/ProjectsPage/projects.util.jsx index 70631352a9..eaa1853860 100644 --- a/src/components/ProjectsPage/projects.util.jsx +++ b/src/components/ProjectsPage/projects.util.jsx @@ -107,7 +107,7 @@ export const generateProjectActionsMenu = ( icon: , className: 'danger', hidden: - window.mlrunConfig.nuclioMode === 'enabled' && project.metadata.name === 'default', + window.mlrunConfig?.nuclioMode === 'enabled' && project?.metadata?.name === 'default', disabled: projectIsDeleting, onClick: deleteProject } diff --git a/src/components/RemoteNuclio/NuclioRemoteError.jsx b/src/components/RemoteNuclio/NuclioRemoteError.jsx new file mode 100644 index 0000000000..54d3f3ad8f --- /dev/null +++ b/src/components/RemoteNuclio/NuclioRemoteError.jsx @@ -0,0 +1,36 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import React from 'react' + +const NuclioRemoteError = () => { + return ( +
+

Nuclio App Unavailable

+

+ The Nuclio remote app could not be loaded. + + Please check your network connection or make sure the remote is running. + +

+
+ ) +} + +export default NuclioRemoteError diff --git a/src/components/RemoteNuclio/RemoteNuclio.scss b/src/components/RemoteNuclio/RemoteNuclio.scss new file mode 100644 index 0000000000..93c94676d5 --- /dev/null +++ b/src/components/RemoteNuclio/RemoteNuclio.scss @@ -0,0 +1,58 @@ +.remote-nuclio-container { + width: 100%; + height: 100%; + + .nuclio-app-wrapper { + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + min-height: 800px; + } + + .flex-center { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + min-height: 400px; + } + + .remote-error-card { + display: flex; + flex-direction: column; + align-items: center; + max-width: 576px; + margin: 160px auto; + padding: 56px; + text-align: center; + color: #000000; + background-color: #f9fafb; + border-radius: 16px; + box-shadow: + 0 20px 25px -5px rgba(0, 0, 0, 0.1), + 0 10px 10px -5px rgba(0, 0, 0, 0.04); + transition: all 0.3s ease-in-out; + + .title { + margin-bottom: 20px; + font-weight: 600; + font-size: 24px; + line-height: 1.4; + } + + .description { + max-width: 440px; + color: #1f2937; + font-size: 16px; + line-height: 1.625; + + .subtext { + display: block; + margin-top: 4px; + font-size: 14px; + color: #4b5563; + } + } + } +} diff --git a/src/components/RemoteNuclio/RemoteNuclioRouteWrapper.jsx b/src/components/RemoteNuclio/RemoteNuclioRouteWrapper.jsx new file mode 100644 index 0000000000..93ec9b8d87 --- /dev/null +++ b/src/components/RemoteNuclio/RemoteNuclioRouteWrapper.jsx @@ -0,0 +1,107 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import React, { useEffect, useState, Suspense } from 'react' +import { ErrorBoundary } from 'react-error-boundary' +import { ensureNuclioRemote, loadNuclioApp } from '../../utils/nuclio.remotes.utils' +import NuclioRemoteError from './NuclioRemoteError' +import { Loader } from 'igz-controls/components' + +import './RemoteNuclio.scss' +import Breadcrumbs from '../../common/Breadcrumbs/Breadcrumbs' + +const RemoteNuclioApp = React.lazy(() => loadNuclioApp()) + +const RemoteNuclioRouteWrapper = () => { + const [ready, setReady] = useState(false) + const [error, setError] = useState(false) + + useEffect(() => { + const origPushState = history.pushState + const origReplaceState = history.replaceState + + history.pushState = function (...args) { + origPushState.apply(this, args) + Promise.resolve().then(() => { + window.dispatchEvent(new PopStateEvent('popstate')) + }) + } + + history.replaceState = function (...args) { + origReplaceState.apply(this, args) + Promise.resolve().then(() => { + window.dispatchEvent(new PopStateEvent('popstate')) + }) + } + + return () => { + history.pushState = origPushState + history.replaceState = origReplaceState + } + }, []) + + useEffect(() => { + const init = async () => { + try { + await ensureNuclioRemote() + setReady(true) + } catch { + setError(true) + } + } + void init() + }, []) + + const renderContent = () => { + if (error) { + return + } + + if (!ready) { + return ( +
+ +
+ ) + } + + return ( + }> + + + + } + > +
+
+ +
+ +
+
+
+ ) + } + + return
{renderContent()}
+} + +export default RemoteNuclioRouteWrapper diff --git a/src/components/Workflow/workflow.util.js b/src/components/Workflow/workflow.util.js index c3285093b2..a6941afebc 100644 --- a/src/components/Workflow/workflow.util.js +++ b/src/components/Workflow/workflow.util.js @@ -31,7 +31,7 @@ import { JOBS_MONITORING_WORKFLOWS_TAB, WORKFLOW_TYPE_SKIPPED } from '../../constants' -import projectsIguazioApi from '../../api/projects-iguazio-api' +import { checkProjectWriteAccess } from '../../utils/projectAuth.util' import tasksApi from '../../api/tasks-api' import workflowsApi from '../../api/workflow-api' import { page } from '../Jobs/jobs.util' @@ -312,15 +312,10 @@ export const fetchMissingProjectsPermissions = async (projectNames, currentMap, await Promise.all( missingProjects.map(async projectName => { try { - await projectsIguazioApi.getProjectOwnerVisibility(projectName) - return [projectName, true] + const hasAccess = await checkProjectWriteAccess(projectName) + return [projectName, hasAccess] } catch { - try { - await projectsIguazioApi.getProjectWorkflowsUpdateAuthorization(projectName) - return [projectName, true] - } catch { - return [projectName, false] - } + return [projectName, false] } }) ) @@ -333,15 +328,12 @@ export const fetchMissingProjectsPermissions = async (projectNames, currentMap, export const fetchMissingProjectPermission = async (projectName, currentMap, dispatch) => { if (projectName in currentMap) return - const hasPermission = await projectsIguazioApi - .getProjectOwnerVisibility(projectName) - .then(() => true) - .catch(() => - projectsIguazioApi - .getProjectWorkflowsUpdateAuthorization(projectName) - .then(() => true) - .catch(() => false) - ) + let hasPermission = false + try { + hasPermission = await checkProjectWriteAccess(projectName) + } catch { + hasPermission = false + } dispatch(setAccessibleProjectsMap({ [projectName]: hasPermission })) } diff --git a/src/constants.js b/src/constants.js index 76adcbe734..47ba2ba606 100644 --- a/src/constants.js +++ b/src/constants.js @@ -19,6 +19,8 @@ such restriction. */ /*=========== GENERAL =============*/ +export const IS_MF_MODE = import.meta.env.VITE_FEDERATION === 'true' + export const SET_LOADING = 'SET_LOADING' export const AZURE_STORAGE_INPUT_PATH_SCHEME = 'az://' @@ -145,6 +147,8 @@ export const PROJECT_QUICK_ACTIONS_PAGE = 'quick-actions' export const ALL_VERSIONS_PATH = 'all-versions' +export const NUCLIO_FUNCTIONS_PATH = IS_MF_MODE ? 'real-time-functions' : 'functions' + /*=========== CONSUMER_GROUPS =============*/ export const CONSUMER_GROUP_PAGE = 'CONSUMER_GROUP' @@ -444,6 +448,8 @@ export const ENV_VARIABLE_TYPE_VALUE = 'value' export const ENV_VARIABLE_TYPE_SECRET = 'secret' export const PANEL_DEFAULT_ACCESS_KEY = '$generate' +export const API_TOKEN_TIP = + 'Get a valid API Token from your API tokens list (under Personal Settings)' /*=========== ML REACT FLOW =============*/ diff --git a/src/elements/BreadcrumbsDropdown/breadcrumbsDropdown.scss b/src/elements/BreadcrumbsDropdown/breadcrumbsDropdown.scss index dad7cf67ec..e450338b29 100644 --- a/src/elements/BreadcrumbsDropdown/breadcrumbsDropdown.scss +++ b/src/elements/BreadcrumbsDropdown/breadcrumbsDropdown.scss @@ -11,7 +11,7 @@ position: absolute; top: 35px; left: 14px; - z-index: 7; + z-index: 100; min-width: 130px; padding: 12px 0; font-size: 15px; diff --git a/src/elements/ChangeOwnerPopUp/ChangeOwnerPopUp.jsx b/src/elements/ChangeOwnerPopUp/ChangeOwnerPopUp.jsx index 3b045f4fcb..27bce99e3e 100644 --- a/src/elements/ChangeOwnerPopUp/ChangeOwnerPopUp.jsx +++ b/src/elements/ChangeOwnerPopUp/ChangeOwnerPopUp.jsx @@ -39,7 +39,7 @@ import { setNotification } from 'igz-controls/reducers/notificationReducer' import { showErrorNotification } from 'igz-controls/utils/notification.util' import { useDetectOutsideClick } from 'igz-controls/hooks' -import { USER_ROLE } from '../../constants' +import { IS_MF_MODE, USER_ROLE } from '../../constants' import SearchIcon from 'igz-controls/images/search.svg?react' @@ -74,48 +74,104 @@ const ChangeOwnerPopUp = ({ changeOwnerCallback, projectId }) => { setShowSuggestionList(false) } - const applyChanges = () => { - if (newOwnerId) { - const projectData = { - data: { - type: 'project', - attributes: {}, - relationships: { - owner: { - data: { - id: newOwnerId, - type: USER_ROLE - } + const applyChangesMF = () => { + projectsIguazioApi + .updateProjectOwner(projectId, newOwnerId) + .then(changeOwnerCallback) + .then(() => { + dispatch( + setNotification({ + status: 200, + id: Math.random(), + message: 'Owner updated successfully' + }) + ) + }) + .catch(error => { + const customErrorMsg = + error.response?.status === FORBIDDEN_ERROR_STATUS_CODE + ? 'Missing edit permission for the project' + : getErrorMsg(error, 'Failed to edit project data') + + showErrorNotification(dispatch, error, '', customErrorMsg, () => applyChanges()) + }) + .finally(handleOnClose) + } + + const applyChangesIGZ3 = () => { + const projectData = { + data: { + type: 'project', + attributes: {}, + relationships: { + owner: { + data: { + id: newOwnerId, + type: USER_ROLE } } } } + } + + projectsIguazioApi + .editProject(projectId, projectData) + .then(changeOwnerCallback) + .then(() => { + dispatch( + setNotification({ + status: 200, + id: Math.random(), + message: 'Owner updated successfully' + }) + ) + }) + .catch(error => { + const customErrorMsg = + error.response?.status === FORBIDDEN_ERROR_STATUS_CODE + ? 'Missing edit permission for the project' + : getErrorMsg(error, 'Failed to edit project data') + + showErrorNotification(dispatch, error, '', customErrorMsg, () => applyChanges(newOwnerId)) + }) + .finally(handleOnClose) + } + + const applyChanges = () => { + if (newOwnerId) { + if (IS_MF_MODE) { + applyChangesMF() + } else { + applyChangesIGZ3() + } + } + } + + const generateSuggestionListMF = async (memberName, resolve) => { + let formattedUsers = [] + + try { + const response = await projectsIguazioApi.searchUsersMetadata(memberName) + const users = response.data.items || [] - projectsIguazioApi - .editProject(projectId, projectData) - .then(changeOwnerCallback) - .then(() => { - dispatch( - setNotification({ - status: 200, - id: Math.random(), - message: 'Owner updated successfully' - }) - ) - }) - .catch(error => { - const customErrorMsg = - error.response?.status === FORBIDDEN_ERROR_STATUS_CODE - ? 'Missing edit permission for the project' - : getErrorMsg(error, 'Failed to edit project data') - - showErrorNotification(dispatch, error, '', customErrorMsg, () => applyChanges(newOwnerId)) - }) - .finally(handleOnClose) + formattedUsers = users.map(user => { + return { + name: `${user.firstName} ${user.lastName}`, + username: user.username, + label: `${user.firstName} ${user.lastName} (${user.username})`, + id: user.username, + role: '' + } + }) + setUsersList(formattedUsers) + } catch (error) { + showErrorNotification(dispatch, error, 'Failed to fetch users') } + + resolve(formattedUsers) } - const generateSuggestionList = async (memberName, resolve) => { + const generateSuggestionListIGZ3 = async (memberName, resolve) => { const params = { 'filter[assigned_policies]': '[$contains_any]Developer,Project Admin', 'page[size]': 200 @@ -128,10 +184,7 @@ const ChangeOwnerPopUp = ({ changeOwnerCallback, projectId }) => { } try { - const response = await projectsIguazioApi.getScrubbedUsers({ - params - }) - + const response = await projectsIguazioApi.getScrubbedUsers({ params }) const { data: { data: users } } = response @@ -153,6 +206,8 @@ const ChangeOwnerPopUp = ({ changeOwnerCallback, projectId }) => { resolve(formattedUsers) } + const generateSuggestionList = IS_MF_MODE ? generateSuggestionListMF : generateSuggestionListIGZ3 + const onSearchChange = debounce(memberName => { const memberNameEscaped = deleteUnsafeHtml(memberName) setSearchValue(memberNameEscaped) diff --git a/src/elements/MembersPopUp/MembersPopUp.jsx b/src/elements/MembersPopUp/MembersPopUp.jsx index 6f757b0408..34c0707fb0 100644 --- a/src/elements/MembersPopUp/MembersPopUp.jsx +++ b/src/elements/MembersPopUp/MembersPopUp.jsx @@ -38,7 +38,7 @@ import { isIgzVersionCompatible } from '../../utils/isIgzVersionCompatible' import { membersActions } from './membersReducer' import { showErrorNotification } from 'igz-controls/utils/notification.util' -import { USER_GROUP_ROLE, USER_ROLE } from '../../constants' +import { IS_MF_MODE, OWNER_ROLE, USER_GROUP_ROLE, USER_ROLE } from '../../constants' import Add from 'igz-controls/images/add.svg?react' import Close from 'igz-controls/images/close.svg?react' @@ -96,7 +96,61 @@ const MembersPopUp = ({ changeMembersCallback, membersDispatch, membersState }) setMembersData(state => ({ ...state, members: membersCopy })) } - const applyMembersChanges = () => { + const applyMembersChangesMF = () => { + const projectName = membersData.projectInfo.id + const visibleMembers = membersData.members.filter( + member => member.modification !== DELETE_MODIFICATION && member.role !== OWNER_ROLE + ) + const groupedByRole = groupBy(visibleMembers, 'role') + + const membership = {} + + membersState.projectAuthorizationRoles + .filter(policy => policy.spec.displayName !== OWNER_ROLE) + .forEach(policy => { + const roleName = policy.spec.displayName.toLowerCase() + membership[roleName] = { + values: (groupedByRole[policy.spec.displayName] || []).map(member => member.id) + } + }) + + const body = { + membership, + override: true + } + + membersDispatch({ + type: membersActions.SET_MEMBERS, + payload: membersData.members + }) + + projectsIguazioApi + .setProjectMembership(projectName, body) + .then(() => { + const activeUsername = membersData.activeUser.data?.attributes?.username + const userIsStillMember = membersData.members?.some( + member => + member.modification !== DELETE_MODIFICATION && + (member.id === activeUsername || + (member.type === USER_GROUP_ROLE && + membersData.activeUser.data?.attributes?.user_group_names?.has(member.id))) + ) + + changeMembersCallback(userIsStillMember) + }) + .catch(error => { + const customErrorMsg = + error.response?.status === FORBIDDEN_ERROR_STATUS_CODE + ? 'Missing edit permission for the project' + : getErrorMsg(error, 'Failed to edit project data') + + showErrorNotification(dispatch, error, '', customErrorMsg, () => applyMembersChanges()) + }) + + handleOnClose() + } + + const applyMembersChangesIGZ3 = () => { const changesBody = { data: { attributes: { @@ -207,6 +261,8 @@ const MembersPopUp = ({ changeMembersCallback, membersDispatch, membersState }) handleOnClose() } + const applyMembersChanges = IS_MF_MODE ? applyMembersChangesMF : applyMembersChangesIGZ3 + const areChangesMade = () => { return membersData.members.some(member => member.modification !== '') } @@ -225,13 +281,66 @@ const MembersPopUp = ({ changeMembersCallback, membersDispatch, membersState }) handleOnClose() } - const generateUsersSuggestionList = debounce(searchQuery => { + const toSuggestionItem = (id, label, type) => { + const existingMember = membersData.members.find( + member => member.id === id && member.modification !== DELETE_MODIFICATION + ) + + return { + label, + id, + subLabel: existingMember?.role ?? '', + disabled: Boolean(existingMember), + icon: + type === USER_ROLE ? ( + + + + ) : ( + + + + ), + ui: { type } + } + } + + const generateUsersSuggestionListMF = debounce(searchQuery => { + const getUsersPromise = projectsIguazioApi.searchUsersMetadata(searchQuery) + const getUserGroupsPromise = projectsIguazioApi.searchGroupsMetadata(searchQuery) + + Promise.all([getUsersPromise, getUserGroupsPromise]) + .then(([usersResponse, groupsResponse]) => { + const users = usersResponse.data.items || [] + const groups = groupsResponse.data.items || [] + const suggestionList = [ + ...users.map(user => toSuggestionItem(user.username, user.username, USER_ROLE)), + ...groups.map(group => + toSuggestionItem( + group.groupId, + group.path.replace(/^\//, '') ?? group.groupId, + USER_GROUP_ROLE + ) + ) + ] + + setNewMembersSuggestionList(suggestionList) + }) + .catch(error => { + showErrorNotification(dispatch, error, 'Failed to fetch users') + }) + }, 400) + + const generateUsersSuggestionListIGZ3 = debounce(searchQuery => { const requiredIgzVersion = '3.5.3' let paramsScrubbedUsers = { 'filter[username]': `[$match-i]^.*${searchQuery}.*$`, 'page[size]': 200 } - let paramsUserGroups = { 'filter[name]': `[$match-i]^.*${searchQuery}.*$`, 'page[size]': 200 } + let paramsUserGroups = { + 'filter[name]': `[$match-i]^.*${searchQuery}.*$`, + 'page[size]': 200 + } if (isIgzVersionCompatible(requiredIgzVersion)) { paramsScrubbedUsers['filter[username]'] = `[$contains_istr]${searchQuery}` @@ -286,6 +395,10 @@ const MembersPopUp = ({ changeMembersCallback, membersDispatch, membersState }) }) }, 400) + const generateUsersSuggestionList = IS_MF_MODE + ? generateUsersSuggestionListMF + : generateUsersSuggestionListIGZ3 + return (
diff --git a/src/elements/MembersPopUp/membersReducer.js b/src/elements/MembersPopUp/membersReducer.js index 9a045856a9..865deb46d0 100644 --- a/src/elements/MembersPopUp/membersReducer.js +++ b/src/elements/MembersPopUp/membersReducer.js @@ -23,8 +23,7 @@ import { groupBy } from 'lodash' * - activeUser : logged in user data * - projectInfo : additional information about the project such as ID and Owner of the project * (data is received from iguazio API). - * - users : the list of user members (original list from response) - * - useGroups : the list of user-group members (original list from response) + * - projectAuthorizationRoles: the list of project policies from /authorization/projects/{project}/policies * - membersOriginal : the list of users and user-groups that is used to revert changes * - members : the list of users and user-groups that is displayed in the table of the `Member` dialog (includes owner) * - groupedOriginalMembers : grouped members list by their role, which is used to display the number of diff --git a/src/elements/ProjectFunctions/ProjectFunctions.jsx b/src/elements/ProjectFunctions/ProjectFunctions.jsx index ea8c54617a..48c0d872f7 100644 --- a/src/elements/ProjectFunctions/ProjectFunctions.jsx +++ b/src/elements/ProjectFunctions/ProjectFunctions.jsx @@ -32,7 +32,9 @@ import { FAILED_STATE, FUNCTION_READY_STATE, REQUEST_CANCELED, - RUNNING_STATE + RUNNING_STATE, + NUCLIO_FUNCTIONS_PATH, + IS_MF_MODE } from '../../constants' import { fetchApiGateways } from '../../reducers/nuclioReducer' import { generateNuclioLink } from '../../utils' @@ -82,7 +84,9 @@ const ProjectFunctions = ({ nuclioStreamsAreEnabled, project }) => { label: 'Running', className: RUNNING_STATE, status: RUNNING_STATE, - href: generateNuclioLink(`/projects/${params.projectName}/functions`), + [IS_MF_MODE ? 'link' : 'href']: generateNuclioLink( + `/projects/${params.projectName}/${NUCLIO_FUNCTIONS_PATH}` + ), loading: nuclioStore.loading }, failed: { @@ -91,14 +95,18 @@ const ProjectFunctions = ({ nuclioStreamsAreEnabled, project }) => { label: 'Failed', status: FAILED_STATE, className: functionsFailed > 0 ? FAILED_STATE : RUNNING_STATE, - href: generateNuclioLink(`/projects/${params.projectName}/functions`), + [IS_MF_MODE ? 'link' : 'href']: generateNuclioLink( + `/projects/${params.projectName}/${NUCLIO_FUNCTIONS_PATH}` + ), loading: nuclioStore.loading }, apiGateways: { value: nuclioStore.apiGateways, label: 'API gateways', className: RUNNING_STATE, - href: generateNuclioLink(`/projects/${params.projectName}/api-gateways`), + [IS_MF_MODE ? 'link' : 'href']: generateNuclioLink( + `/projects/${params.projectName}/api-gateways` + ), loading: nuclioStore.loading }, ...(nuclioStreamsAreEnabled && { @@ -149,8 +157,8 @@ const ProjectFunctions = ({ nuclioStreamsAreEnabled, project }) => { ? // if nuclio func is generated by MLRun then name only in this case starts with project name and we need to slice it func.metadata.name.slice(params.projectName.length + 1) : func.metadata.name, - href: generateNuclioLink( - `/projects/${params.projectName}/functions/${func.metadata.name}` + [IS_MF_MODE ? 'link' : 'href']: generateNuclioLink( + `/projects/${params.projectName}/${NUCLIO_FUNCTIONS_PATH}/${func.metadata.name}` ), className: 'table-cell_big' }, @@ -177,7 +185,11 @@ const ProjectFunctions = ({ nuclioStreamsAreEnabled, project }) => { loading: nuclioStore.loading }} footerLinkText="All real-time functions" - href={generateNuclioLink(`/projects/${params.projectName}/functions`)} + {...{ + [IS_MF_MODE ? 'link' : 'href']: generateNuclioLink( + `/projects/${params.projectName}/${NUCLIO_FUNCTIONS_PATH}` + ) + }} statistics={functions} subTitle="Recent real-time functions" table={functionsTable} diff --git a/src/hooks/nuclioMode.hook.js b/src/hooks/nuclioMode.hook.js index 88c5fea164..0ba4da3fab 100644 --- a/src/hooks/nuclioMode.hook.js +++ b/src/hooks/nuclioMode.hook.js @@ -33,11 +33,11 @@ import { useLayoutEffect, useState } from 'react' */ export const useNuclioMode = () => { - const [mode, setMode] = useState(window.mlrunConfig.nuclioMode) + const [mode, setMode] = useState(window?.mlrunConfig?.nuclioMode) useLayoutEffect(() => { - if (mode !== window.mlrunConfig.nuclioMode) { - setMode(window.mlrunConfig.nuclioMode) + if (mode !== window?.mlrunConfig?.nuclioMode) { + setMode(window?.mlrunConfig?.nuclioMode) } }, [mode]) diff --git a/src/httpClient.js b/src/httpClient.js index a61f075bf2..142be3a0ba 100755 --- a/src/httpClient.js +++ b/src/httpClient.js @@ -29,6 +29,13 @@ const headers = { 'Cache-Control': 'no-cache' } +/** + * Resolve auth bridge provided by igz-ui (host). + * - Primary: injected via Module Federation + * - Fallback: host global (timing safety) + */ +export const getHostAuth = () => window.__mlrunHostServices?.auth || window.__igzAuth || null + // serialize a param with an array value as a repeated param, for example: // { label: ['host', 'owner=admin'] } => 'label=host&label=owner%3Dadmin' const paramsSerializer = params => qs.stringify(params, { arrayFormat: 'repeat' }) @@ -62,10 +69,66 @@ export const nuclioHttpClient = axios.create({ }) export const iguazioHttpClient = axios.create({ - baseURL: import.meta.env.MODE === 'production' ? '/api' : '/iguazio/api', + baseURL: + import.meta.env.MODE === 'production' + ? import.meta.env.VITE_FEDERATION === 'true' + ? '/igz/api' + : '/api' + : '/iguazio/api', headers }) +/** + * Module Federation auth: + * token injection and refresh are handled by the igz-ui host + */ + +const attachHostAuth = client => { + const auth = getHostAuth() + if (!auth) return + + client.interceptors.request.use(config => { + const token = auth.getAccessToken?.() + if (token) { + config.headers = config.headers ?? {} + config.headers.Authorization = `Bearer ${token}` + } + return config + }) + + client.interceptors.response.use( + res => res, + async err => { + const status = err?.response?.status + const req = err?.config + if (!req) throw err + + if (status === 401 && !req._retry) { + req._retry = true + + const token = await auth.refreshAccessToken?.() + if (!token) { + auth.redirectToLogin?.() + throw err + } + + req.headers = req.headers ?? {} + req.headers.Authorization = `Bearer ${token}` + + return client(req) + } + + throw err + } + ) +} + +attachHostAuth(mainHttpClient) +attachHostAuth(mainHttpClientV2) +attachHostAuth(functionTemplatesHttpClient) +attachHostAuth(nuclioHttpClient) +attachHostAuth(iguazioHttpClient) + const getAbortSignal = (controller, abortCallback, timeoutMs) => { let timeoutId = null const newController = new AbortController() diff --git a/src/index.jsx b/src/index.jsx index 9a141aaa0e..57839eb9e0 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -26,40 +26,23 @@ import ErrorBoundary from './components/ErrorBoundary/ErrorBoundary' import * as serviceWorker from './serviceWorker' import { Provider } from 'react-redux' import toolkitStore from './store/toolkitStore' -import { HTTP, HTTPS } from './constants' +import { loadRemoteConfig } from './loadRemoteConfig' if (!window.location.pathname.includes(import.meta.env.VITE_PUBLIC_URL)) { window.location.href = import.meta.env.VITE_PUBLIC_URL } -fetch(`${import.meta.env.VITE_PUBLIC_URL}/config.json`, { cache: 'no-store' }) - .then(response => response.json()) - .then(config => { - if (config.nuclioUiUrl) { - const mlrunProtocol = - config.nuclioUiUrl.startsWith(HTTP) || config.nuclioUiUrl.startsWith(HTTPS) - ? '' - : `${window.location.protocol}//` - - window.mlrunConfig = { - ...config, - nuclioUiUrl: `${mlrunProtocol}${config.nuclioUiUrl}` - } - } else { - window.mlrunConfig = config - } - }) - .then(() => { - const root = createRoot(document.getElementById('root')) - - root.render( - - - - - - ) - }) +loadRemoteConfig().then(() => { + const root = createRoot(document.getElementById('root')) + + root.render( + + + + + + ) +}) // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. diff --git a/src/layout/Navbar/navbar.util.jsx b/src/layout/Navbar/navbar.util.jsx index ea71474e0c..b8806e65ab 100644 --- a/src/layout/Navbar/navbar.util.jsx +++ b/src/layout/Navbar/navbar.util.jsx @@ -23,7 +23,9 @@ import { DOCUMENTS_PAGE, LLM_PROMPTS_PAGE, PROJECT_MONITOR, - PROJECT_QUICK_ACTIONS_PAGE + PROJECT_QUICK_ACTIONS_PAGE, + NUCLIO_FUNCTIONS_PATH, + IS_MF_MODE } from '../../constants' import { generateNuclioLink } from '../../utils' @@ -123,15 +125,15 @@ export const getLinks = projectName => { icon: , id: 'real-time-functions', label: 'Real-time functions', - link: generateNuclioLink(`${pathname}/functions`), - externalLink: true + link: generateNuclioLink(`${pathname}/${NUCLIO_FUNCTIONS_PATH}`), + externalLink: !IS_MF_MODE }, { icon: , id: 'api-gateways', label: 'API gateways', link: generateNuclioLink(`${pathname}/api-gateways`), - externalLink: true + externalLink: !IS_MF_MODE } ] } diff --git a/src/lazyWithRetry.js b/src/lazyWithRetry.js index f44786a6bb..4be065b970 100644 --- a/src/lazyWithRetry.js +++ b/src/lazyWithRetry.js @@ -19,26 +19,33 @@ such restriction. */ import { lazy } from 'react' // a function to retry loading a chunk to avoid chunk load error for out of date code -export const lazyRetry = componentImport => - lazy(() => { +export const lazyRetry = (componentImport, name) => { + if (!name) { + throw new Error('lazyRetry requires a name for the component being imported') + } + + return lazy(() => { return new Promise((resolve, reject) => { // check if the window has already been refreshed - const hasRefreshed = JSON.parse( - window.sessionStorage.getItem('retry-lazy-refreshed') || 'false' - ) + const componentStorageKey = `retry-lazy-refreshed-${name}` + const hasRefreshed = JSON.parse(window.sessionStorage.getItem(componentStorageKey) || 'false') // try to import the component componentImport() .then(component => { - window.sessionStorage.setItem('retry-lazy-refreshed', 'false') // success so reset the refresh + window.sessionStorage.setItem(componentStorageKey, 'false') // success so reset the refresh resolve(component) }) .catch(error => { + window.sessionStorage.setItem(componentStorageKey, 'true') if (!hasRefreshed) { // not been refreshed yet window.sessionStorage.setItem('retry-lazy-refreshed', 'true') // we are now going to refresh return window.location.reload() // refresh the page } - reject(error) // Default error behaviour as already tried refresh + // eslint-disable-next-line no-console + console.error(`Failed to load component ${name} after retrying`, error) + reject(error) // Default error behavior as already tried refresh }) }) }) +} diff --git a/src/loadRemoteConfig.js b/src/loadRemoteConfig.js new file mode 100644 index 0000000000..febebc05d6 --- /dev/null +++ b/src/loadRemoteConfig.js @@ -0,0 +1,60 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ + +import { HTTP, HTTPS } from './constants' + +const withProtocol = url => { + if (!url || url.startsWith(HTTP) || url.startsWith(HTTPS)) return url + return `${window.location.protocol}//${url.replace(/^\/+/, '')}` +} + +export const loadRemoteConfig = async (url, services = {}) => { + /** + * Store host-provided services (auth bridge from igz-ui) + */ + if (services && Object.keys(services).length > 0) { + window.__mlrunHostServices = services + } + + // Priority 1: Use config injected by the Host (igz-ui) + if (window.mlrunConfig && Object.keys(window.mlrunConfig).length > 0) { + window.mlrunConfig.nuclioUiUrl = withProtocol(window.mlrunConfig.nuclioUiUrl) + window.mlrunConfig.nuclioRemoteEntryUrl = withProtocol(window.mlrunConfig.nuclioRemoteEntryUrl) + return + } + + // Priority 2: Standalone Fallback (Local Dev) + try { + const configPath = `${url ?? import.meta.env.VITE_PUBLIC_URL}/config.json` + const response = await fetch(configPath, { cache: 'no-store' }) + if (!response.ok) throw new Error(response.status) + + const config = await response.json() + const uiUrl = withProtocol(config.nuclioUiUrl) + + window.mlrunConfig = { + ...config, + nuclioUiUrl: uiUrl, + nuclioRemoteEntryUrl: withProtocol(config.nuclioRemoteEntryUrl || uiUrl) + } + } catch (err) { + throw new Error('[mlrun-ui] Config load failed. Falling back to Host injection.', err) + } +} diff --git a/src/main.jsx b/src/main.jsx new file mode 100644 index 0000000000..40ada1bd44 --- /dev/null +++ b/src/main.jsx @@ -0,0 +1,20 @@ +import App from './App' +import { Provider } from 'react-redux' +import store from './store/toolkitStore' +import ErrorBoundary from './components/ErrorBoundary/ErrorBoundary' +// Eagerly initialize react-text-mask in the entry chunk so its CJS/UMD module +// is resolved against React before any lazy chunks try to reference it. +// TODO: remove this import when custom react-text-mask will be included in our codebase (in progress) or when https://github.com/rollup/rollup/issues/6296 fixed (deps of vite) +import 'react-text-mask' + +const RemoteApp = () => { + return ( + + + + + + ) +} + +export default RemoteApp diff --git a/src/reducers/jobReducer.js b/src/reducers/jobReducer.js index 4d0a98bccb..259d4a50da 100644 --- a/src/reducers/jobReducer.js +++ b/src/reducers/jobReducer.js @@ -27,7 +27,8 @@ import { LABELS_FILTER, NAME_FILTER, STATUS_FILTER, - TYPE_FILTER + TYPE_FILTER, + IS_MF_MODE } from '../constants' import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' import functionsApi from '../api/functions-api' @@ -65,11 +66,13 @@ const initialState = { } }, function: { - metadata: { - credentials: { - access_key: '' + ...(!IS_MF_MODE && { + metadata: { + credentials: { + access_key: '' + } } - }, + }), spec: { env: [], node_selector: {}, diff --git a/src/utils/createApplicationContent.jsx b/src/utils/createApplicationContent.jsx index d8422185dc..e9be466a5c 100644 --- a/src/utils/createApplicationContent.jsx +++ b/src/utils/createApplicationContent.jsx @@ -22,7 +22,7 @@ import { capitalize } from 'lodash' import { formatDatetime } from 'igz-controls/utils/datetime.util' import { generateNuclioLink } from './parseUri' import { saveAndTransformSearchParams } from 'igz-controls/utils/filter.util' -import { MONITORING_APP_PAGE } from '../constants' +import { IS_MF_MODE, MONITORING_APP_PAGE, NUCLIO_FUNCTIONS_PATH } from '../constants' export const createApplicationContent = (application, projectName) => { const identifierUnique = 'identifierUnique.' + application.name + application.application_class @@ -105,8 +105,10 @@ export const createApplicationContent = (application, projectName) => { value: application.name, className: 'table-cell-2', getLink: () => - generateNuclioLink(`/projects/${projectName}/functions/${nuclioFunctionName}`), - linkIsExternal: true, + generateNuclioLink( + `/projects/${projectName}/${NUCLIO_FUNCTIONS_PATH}/${nuclioFunctionName}` + ), + linkIsExternal: !IS_MF_MODE, showStatus: true } ] diff --git a/src/utils/createConsumerGroupsContent.js b/src/utils/createConsumerGroupsContent.js index db9ea22f54..14781c18c4 100644 --- a/src/utils/createConsumerGroupsContent.js +++ b/src/utils/createConsumerGroupsContent.js @@ -19,6 +19,7 @@ such restriction. */ import { generateNuclioLink } from './parseUri' import { getV3ioStreamIdentifier } from './getUniqueIdentifier' +import { IS_MF_MODE, NUCLIO_FUNCTIONS_PATH } from '../constants' const createConsumerGroupsContent = (content, params) => { return content.map(contentItem => { @@ -46,10 +47,10 @@ const createConsumerGroupsContent = (content, params) => { value: contentItem.functionName, getLink: () => { return generateNuclioLink( - `/projects/${params.projectName}/functions/${contentItem.functionName}` + `/projects/${params.projectName}/${NUCLIO_FUNCTIONS_PATH}/${contentItem.functionName}` ) }, - linkIsExternal: true, + linkIsExternal: !IS_MF_MODE, className: 'table-cell-1' } } diff --git a/src/utils/createRealTimePipelinesContent.js b/src/utils/createRealTimePipelinesContent.js index 5121112a3e..4375fde20e 100644 --- a/src/utils/createRealTimePipelinesContent.js +++ b/src/utils/createRealTimePipelinesContent.js @@ -19,7 +19,13 @@ such restriction. */ import { formatDatetime } from 'igz-controls/utils/datetime.util' -import { DETAILS_MODEL_ENDPOINTS_TAB, MODELS_PAGE, REAL_TIME_PIPELINES_TAB } from '../constants' +import { + DETAILS_MODEL_ENDPOINTS_TAB, + IS_MF_MODE, + MODELS_PAGE, + NUCLIO_FUNCTIONS_PATH, + REAL_TIME_PIPELINES_TAB +} from '../constants' import { typesOfJob } from './jobs.util' import { generateNuclioLink } from './parseUri' @@ -50,9 +56,11 @@ const createRealTimePipelinesContent = (pipelines, projectName) => className: 'table-cell-2', showStatus: true, showTag: true, - linkIsExternal: true, + linkIsExternal: !IS_MF_MODE, getLink: () => - generateNuclioLink(`/projects/${projectName}/functions/${nuclioFunctionName}`) + generateNuclioLink( + `/projects/${projectName}/${NUCLIO_FUNCTIONS_PATH}/${nuclioFunctionName}` + ) }, { id: `topology.${pipeline.ui.identifierUnique}`, diff --git a/src/utils/getArtifactPreview.jsx b/src/utils/getArtifactPreview.jsx index 6cdce1792c..1d77309949 100644 --- a/src/utils/getArtifactPreview.jsx +++ b/src/utils/getArtifactPreview.jsx @@ -165,7 +165,7 @@ export const fetchArtifactPreviewFromPath = async ( { data: { content: `The artifact is too large to ${ - fileSize > artifactLimits.max_download_size + fileSize > artifactLimits?.max_download_size ? `download. Go to ${path} to retrieve the data, or use mlrun api/sdk project.get_artifact('${artifact.db_key || artifact.name}').to_dataitem().get()` : 'preview, use the download option instead' }` diff --git a/src/utils/getJobLogs.util.js b/src/utils/getJobLogs.util.js index c78b971249..7d41761d6c 100644 --- a/src/utils/getJobLogs.util.js +++ b/src/utils/getJobLogs.util.js @@ -34,7 +34,7 @@ export const getJobLogs = ( dispatch(fetchJobLogs({ id, project, attempt, signal })) .unwrap() .then(res => { - const reader = res.body?.getReader() + const reader = res.data?.getReader() if (reader) { const decoder = new TextDecoder() diff --git a/src/utils/nuclio.remotes.utils.js b/src/utils/nuclio.remotes.utils.js new file mode 100644 index 0000000000..90bf9f0365 --- /dev/null +++ b/src/utils/nuclio.remotes.utils.js @@ -0,0 +1,69 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import { loadRemote, registerRemotes } from '@module-federation/runtime' + +let registerPromise = null + +const ensureNuclioRemote = async () => { + if (registerPromise) return registerPromise + + const config = window?.mlrunConfig + let remoteEntryUrl = config?.nuclioRemoteEntryUrl + + if (!remoteEntryUrl) { + throw new Error('[MF] Missing window.mlrunConfig.nuclioRemoteEntryUrl') + } + + if (window.location.hostname !== 'localhost') { + remoteEntryUrl = `${remoteEntryUrl.replace(/\/$/, '')}/nuclio-ui` + } else { + remoteEntryUrl = remoteEntryUrl.replace(/\/$/, '') + } + + registerPromise = (async () => { + try { + registerRemotes([ + { + name: 'nuclio', + entry: `${remoteEntryUrl.replace(/\/$/, '')}/remoteEntry.js`, + type: 'module', + shareScope: 'default' + } + ]) + } catch (err) { + registerPromise = null + throw err + } + })() + + return registerPromise +} + +const loadNuclioApp = async () => { + await ensureNuclioRemote() + const module = await loadRemote('nuclio/App') + + if (!module) throw new Error('[MF] Failed to load Nuclio application') + + const component = module.default?.default || module.default || module + return { default: component } +} + +export { ensureNuclioRemote, loadNuclioApp } diff --git a/src/utils/parseUri.js b/src/utils/parseUri.js index 26167d094d..b15de1ef1d 100644 --- a/src/utils/parseUri.js +++ b/src/utils/parseUri.js @@ -24,7 +24,8 @@ import { MONITOR_JOBS_TAB, FILES_PAGE, DATASETS_PAGE, - DOCUMENTS_PAGE + DOCUMENTS_PAGE, + IS_MF_MODE } from '../constants' /** @@ -117,10 +118,14 @@ const generateLinkPath = (uri = '') => { } const generateNuclioLink = pathname => { - const linkUrl = new URL(`${window.mlrunConfig.nuclioUiUrl}${pathname}`) + if (IS_MF_MODE) return pathname - if (window.location.origin !== window.mlrunConfig.nuclioUiUrl) { - linkUrl.searchParams.set?.('origin', window.location.origin) + const base = window.mlrunConfig?.nuclioUiUrl || window.location.origin + const cleanPath = pathname.startsWith('/') ? pathname : `/${pathname}` + const linkUrl = new URL(`${base}${cleanPath}`) + + if (window.location.origin !== base) { + linkUrl.searchParams.set('origin', window.location.origin) } return linkUrl.toString() diff --git a/src/utils/projectAuth.util.js b/src/utils/projectAuth.util.js new file mode 100644 index 0000000000..ec99b8b0b5 --- /dev/null +++ b/src/utils/projectAuth.util.js @@ -0,0 +1,53 @@ +/* +Copyright 2019 Iguazio Systems Ltd. + +Licensed under the Apache License, Version 2.0 (the "License") with +an addition restriction as set forth herein. You may not use this +file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +In addition, you may not use the software for any purposes that are +illegal under applicable law, and the grant of the foregoing license +under the Apache 2.0 license is conditioned upon your compliance with +such restriction. +*/ +import projectsIguazioApi from '../api/projects-iguazio-api' + +const WRITE_ROLES = ['Owner', 'Admin', 'Editor'] + +export const getActiveUsername = async () => { + const response = await projectsIguazioApi.getActiveUser() + return response.data.metadata?.username +} + +export const checkProjectWriteAccess = async (projectName, activeUsername = null) => { + if (import.meta.env.VITE_FEDERATION === 'true') { + if (!activeUsername) { + activeUsername = await getActiveUsername() + } + + const policiesResponse = await projectsIguazioApi.getProjectPolicies(projectName) + const policies = policiesResponse.data.items || [] + return policies.some( + policy => + WRITE_ROLES.includes(policy.spec.displayName) && + policy.status?.assignedMembers?.some(member => member.id === activeUsername) + ) + } else { + return projectsIguazioApi + .getProjectOwnerVisibility(projectName) + .then(() => true) + .catch(() => + projectsIguazioApi + .getProjectWorkflowsUpdateAuthorization(projectName) + .then(() => true) + .catch(() => false) + ) + } +} diff --git a/vite.config.mjs b/vite.config.mjs index 20b71de28d..2c886a4fd5 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -1,50 +1,40 @@ import commonjs from 'vite-plugin-commonjs' import eslint from 'vite-plugin-eslint' +import { federation } from '@module-federation/vite' import path from 'path' import react from '@vitejs/plugin-react-swc' import svgr from 'vite-plugin-svgr' import { defineConfig, loadEnv } from 'vite' -export default defineConfig(({ mode }) => { +import { loadMlrunProxyConfig } from './config/loadDevProxyConfig.js' +import { dependencies } from './package.json' + +export default defineConfig(async ({ mode }) => { const env = loadEnv(mode, path.resolve(process.cwd()), '') + const mlrunProxyConfig = await loadMlrunProxyConfig(mode) + + const federationPlugin = + env.VITE_FEDERATION === 'true' + ? federation({ + filename: 'remoteEntry.js', + name: 'mlrun', + exposes: { + './loadRemoteConfig': './src/loadRemoteConfig.js', + './app': './src/main.jsx' + }, + shared: { + react: { requiredVersion: dependencies.react, singleton: true }, + 'react-dom': { requiredVersion: dependencies['react-dom'], singleton: true } + } + }) + : null return { - plugins: [commonjs(), react(), svgr(), eslint({ failOnError: false })], + plugins: [commonjs(), react(), federationPlugin, svgr(), eslint({ failOnError: false })], base: env.NODE_ENV === 'production' ? env.VITE_PUBLIC_URL : '/', server: { proxy: { - '/api': env.VITE_MLRUN_API_URL - ? { - target: env.VITE_MLRUN_API_URL, - changeOrigin: true, - headers: { - Connection: 'keep-alive', - 'x-v3io-session-key': env.VITE_MLRUN_V3IO_ACCESS_KEY, - 'x-remote-user': 'admin' - } - } - : undefined, - '/nuclio': env.VITE_NUCLIO_API_URL - ? { - target: env.VITE_NUCLIO_API_URL, - changeOrigin: true, - rewrite: path => path.replace(/^\/nuclio/, '') - } - : undefined, - '/iguazio': env.VITE_IGUAZIO_API_URL - ? { - target: env.VITE_IGUAZIO_API_URL, - changeOrigin: true, - rewrite: path => path.replace(/^\/iguazio/, '') - } - : undefined, - '/function-catalog': env.VITE_FUNCTION_CATALOG_URL - ? { - target: env.VITE_FUNCTION_CATALOG_URL, - changeOrigin: true, - rewrite: path => path.replace(/^\/function-catalog/, '') - } - : undefined + ...mlrunProxyConfig(env) }, fs: { strict: false @@ -79,6 +69,7 @@ export default defineConfig(({ mode }) => { force: true }, build: { + target: 'esnext', sourcemap: true, outDir: 'build', chunkSizeWarningLimit: 3000