From 711a43ff007e55cab3c4a186b57ad197724913af Mon Sep 17 00:00:00 2001 From: d02ev Date: Fri, 15 Nov 2024 14:18:19 +0530 Subject: [PATCH 01/66] added `apiKey` and `serverUrl` cols to `teams` rel and gen migration --- ...84356-api_key_server_url_cols_teams_rel.js | 19 +++++++++++++++++++ backend/src/models/Team.js | 8 ++++++++ 2 files changed, 27 insertions(+) create mode 100644 backend/migrations/20241115084356-api_key_server_url_cols_teams_rel.js diff --git a/backend/migrations/20241115084356-api_key_server_url_cols_teams_rel.js b/backend/migrations/20241115084356-api_key_server_url_cols_teams_rel.js new file mode 100644 index 00000000..27797a8b --- /dev/null +++ b/backend/migrations/20241115084356-api_key_server_url_cols_teams_rel.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = { + async up (queryInterface, Sequelize) { + await queryInterface.addColumn('teams', 'apiKey', { + type: Sequelize.STRING(255), + allowNull: true, + }) + await queryInterface.addColumn('teams', 'serverUrl', { + type: Sequelize.STRING(255), + allowNull: true, + }) + }, + + async down (queryInterface, Sequelize) { + await queryInterface.removeColumn('teams', 'apiKey') + await queryInterface.removeColumn('teams', 'serverUrl') + } +}; diff --git a/backend/src/models/Team.js b/backend/src/models/Team.js index 593e6a86..9916f18b 100644 --- a/backend/src/models/Team.js +++ b/backend/src/models/Team.js @@ -11,6 +11,14 @@ module.exports = (sequelize, DataTypes) => { type: DataTypes.STRING(50), allowNull: false, }, + apiKey: { + type: DataTypes.STRING(255), + allowNull: true, + }, + serverUrl: { + type: DataTypes.STRING(255), + allowNull: true, + }, createdAt: { type: DataTypes.DATE, allowNull: false, From 7a18427cdfb79377337c20b7d8c878fef965821b Mon Sep 17 00:00:00 2001 From: d02ev Date: Fri, 15 Nov 2024 14:32:52 +0530 Subject: [PATCH 02/66] added backend API and business logic for `serverUrl` and `apiKey` --- backend/config/settings.js | 1 + backend/src/controllers/team.controller.js | 31 +++++++++++++++++++++- backend/src/routes/team.routes.js | 2 ++ backend/src/service/team.service.js | 19 +++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/backend/config/settings.js b/backend/config/settings.js index b77c4063..75e40c82 100644 --- a/backend/config/settings.js +++ b/backend/config/settings.js @@ -23,6 +23,7 @@ module.exports = { popups: [userRole.ADMIN], hints: [userRole.ADMIN], banners: [userRole.ADMIN], + serverUrlAndApiKey: [userRole.ADMIN] } } }; diff --git a/backend/src/controllers/team.controller.js b/backend/src/controllers/team.controller.js index 07206488..991b346d 100644 --- a/backend/src/controllers/team.controller.js +++ b/backend/src/controllers/team.controller.js @@ -3,6 +3,7 @@ const TeamService = require("../service/team.service"); const { internalServerError } = require("../utils/errors.helper"); const { MAX_ORG_NAME_LENGTH, ORG_NAME_REGEX } = require('../utils/constants.helper'); const db = require("../models"); +const bcrypt = require('bcrypt'); const Team = db.Team; const teamService = new TeamService(); @@ -101,6 +102,34 @@ const updateTeamDetails = async (req, res) => { } }; +const setConfig = async (req, res) => { + const { serverUrl, apiKey } = req.body; + if (!serverUrl || typeof serverUrl !== 'string' || serverUrl.length === 0) { + return res.status(400).json({ message: 'Server URL is required and should be a non-empty string' }); + } + if (!apiKey || typeof apiKey !== "string" || apiKey.length === 0) { + return res.status(400).json({ message: 'API Key is required and should be a non-empty string' }); + } + + try { + new URL(serverUrl); + } catch (err) { + return res.status(400).json({ message: 'Invalid server URL format' }); + } + + try { + encryptedApiKey = await bcrypt.hash(apiKey, 10); + await teamService.addServerUrlAndApiKey(serverUrl, encryptedApiKey); + return res.status(200).json({ message: "Server URL and API Key Set Successfully" }); + } catch (err) { + const { statusCode, payload } = internalServerError( + "SET_CONFIG_ERROR", + err.message + ) + res.status(statusCode).json(payload); + } +} + const removeMember = async (req, res) => { const userId = req.user.id; const { memberId } = req.params; @@ -130,4 +159,4 @@ const changeRole = async (req, res) => { } } -module.exports = { setOrganisation, getTeamDetails, updateTeamDetails, removeMember, changeRole, getTeamCount }; +module.exports = { setOrganisation, getTeamDetails, updateTeamDetails, removeMember, changeRole, getTeamCount, setConfig }; diff --git a/backend/src/routes/team.routes.js b/backend/src/routes/team.routes.js index 49a523a2..fc098c7a 100644 --- a/backend/src/routes/team.routes.js +++ b/backend/src/routes/team.routes.js @@ -1,6 +1,7 @@ const express = require("express"); const { setOrganisation, + setConfig, getTeamDetails, getTeamCount, updateTeamDetails, @@ -25,6 +26,7 @@ router.post("/set-organisation", authenticateJWT, accessGuard(teamPermissions.se router.post("/invite", authenticateJWT, accessGuard(teamPermissions.invite), sendTeamInvite); router.put("/update", authenticateJWT, accessGuard(teamPermissions.update), updateTeamDetails); router.put("/change-role", authenticateJWT, accessGuard(teamPermissions.changeRole), changeRole); +router.put('/set-config', authenticateJWT, accessGuard(teamPermissions.serverUrlAndApiKey), setServerUrlAndApiKey); router.delete("/remove/:memberId", authenticateJWT, accessGuard(teamPermissions.removeUser), removeMember); router.get('/get-all-invites', authenticateJWT, accessGuard(teamPermissions.removeUser), getAllInvites); diff --git a/backend/src/service/team.service.js b/backend/src/service/team.service.js index bb2a5ff0..f62a2134 100644 --- a/backend/src/service/team.service.js +++ b/backend/src/service/team.service.js @@ -1,3 +1,4 @@ +const { where } = require("sequelize"); const settings = require("../../config/settings"); const db = require("../models"); const Team = db.Team; @@ -127,6 +128,24 @@ class TeamService { throw new Error(`"Failed to update user role ~ ${err.message}`); } } + + async addServerUrlAndApiKey(serverUrl, apiKey) { + const transaction = await sequelize.transaction(); + try { + await Team.update({ + serverUrl, + apiKey + }, { + where: {} + }, { + transaction + }); + await transaction.commit(); + } catch (err) { + await transaction.rollback(); + throw new Error("Failed to add server url and api key"); + } + } } module.exports = TeamService; From 3fcbb846947f8d04d70fb90a3704aae4d871aa4e Mon Sep 17 00:00:00 2001 From: d02ev Date: Fri, 15 Nov 2024 14:56:31 +0530 Subject: [PATCH 03/66] fixed controller name typo --- backend/src/routes/team.routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/routes/team.routes.js b/backend/src/routes/team.routes.js index fc098c7a..7dbec25c 100644 --- a/backend/src/routes/team.routes.js +++ b/backend/src/routes/team.routes.js @@ -26,7 +26,7 @@ router.post("/set-organisation", authenticateJWT, accessGuard(teamPermissions.se router.post("/invite", authenticateJWT, accessGuard(teamPermissions.invite), sendTeamInvite); router.put("/update", authenticateJWT, accessGuard(teamPermissions.update), updateTeamDetails); router.put("/change-role", authenticateJWT, accessGuard(teamPermissions.changeRole), changeRole); -router.put('/set-config', authenticateJWT, accessGuard(teamPermissions.serverUrlAndApiKey), setServerUrlAndApiKey); +router.put('/set-config', authenticateJWT, accessGuard(teamPermissions.serverUrlAndApiKey), setConfig); router.delete("/remove/:memberId", authenticateJWT, accessGuard(teamPermissions.removeUser), removeMember); router.get('/get-all-invites', authenticateJWT, accessGuard(teamPermissions.removeUser), getAllInvites); From 84c34e9b45c7f7a89bcd885f11768d3b6139286f Mon Sep 17 00:00:00 2001 From: d02ev Date: Fri, 15 Nov 2024 15:10:52 +0530 Subject: [PATCH 04/66] removed `apiKey` hashing before storing --- backend/src/controllers/team.controller.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/src/controllers/team.controller.js b/backend/src/controllers/team.controller.js index 991b346d..cae05fec 100644 --- a/backend/src/controllers/team.controller.js +++ b/backend/src/controllers/team.controller.js @@ -118,8 +118,7 @@ const setConfig = async (req, res) => { } try { - encryptedApiKey = await bcrypt.hash(apiKey, 10); - await teamService.addServerUrlAndApiKey(serverUrl, encryptedApiKey); + await teamService.addServerUrlAndApiKey(serverUrl, apiKey); return res.status(200).json({ message: "Server URL and API Key Set Successfully" }); } catch (err) { const { statusCode, payload } = internalServerError( From a29edc07745443139d4ac612ed4e92650d8cbdc5 Mon Sep 17 00:00:00 2001 From: d02ev Date: Fri, 15 Nov 2024 15:11:44 +0530 Subject: [PATCH 05/66] added FE connection to BE --- .../src/scenes/settings/CodeTab/CodeTab.jsx | 27 ++++++++++++++++++- frontend/src/services/teamServices.js | 10 +++++++ frontend/src/utils/constants.js | 4 +-- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/frontend/src/scenes/settings/CodeTab/CodeTab.jsx b/frontend/src/scenes/settings/CodeTab/CodeTab.jsx index 4a80dcd5..73dcb6d0 100644 --- a/frontend/src/scenes/settings/CodeTab/CodeTab.jsx +++ b/frontend/src/scenes/settings/CodeTab/CodeTab.jsx @@ -5,6 +5,9 @@ import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined'; import Button from "@components/Button/Button"; import ContentCopyOutlinedIcon from '@mui/icons-material/ContentCopyOutlined'; import { generateApiKey } from "../../../utils/generalHelper"; +import { emitToastError } from "../../../utils/guideHelper"; +import { setConfig } from '../../../services/teamServices'; +import toastEmitter, { TOAST_EMITTER_KEY } from "../../../utils/toastEmitter"; const CodeTab = () => { const [apiKey, setApiKey] = useState('') @@ -22,6 +25,28 @@ const CodeTab = () => { setApiKey(''); } + const onSave = async () => { + if (!serverUrl.trim()) { + toastEmitter.emit(TOAST_EMITTER_KEY, 'Server URL cannot be empty'); + return; + } + if (!serverUrl.startsWith("http://") && !serverUrl.startsWith("https://")) { + toastEmitter.emit(TOAST_EMITTER_KEY, 'Server URL must start with http:// or https://'); + return; + } + if (!apiKey.trim()) { + toastEmitter.emit(TOAST_EMITTER_KEY, 'API key cannot be empty'); + return; + } + + try { + const response = await setConfig(serverUrl, apiKey); + toastEmitter.emit(TOAST_EMITTER_KEY, response.message); + } catch (err) { + emitToastError(err); + } + }; + return (

API key management

@@ -49,7 +74,7 @@ const CodeTab = () => { TextFieldWidth="550px" /> -
Already have an account? @@ -176,4 +229,4 @@ function CreateAccountPage() { ); } -export default CreateAccountPage; +export default CreateAccountPage; \ No newline at end of file diff --git a/frontend/src/scenes/login/ForgotPasswordPage.jsx b/frontend/src/scenes/login/ForgotPasswordPage.jsx index a5e1f3fc..0b6a90ad 100644 --- a/frontend/src/scenes/login/ForgotPasswordPage.jsx +++ b/frontend/src/scenes/login/ForgotPasswordPage.jsx @@ -1,58 +1,108 @@ -import React, { useState } from 'react'; -import styles from './Login.module.css'; -import ArrowBackIcon from '@mui/icons-material/ArrowBack'; -import { forgotPassword } from '../../services/loginServices'; // Make sure this function is properly implemented -import { useNavigate } from 'react-router-dom'; -import CustomTextField from '@components/TextFieldComponents/CustomTextField/CustomTextField'; -import CircularProgress from '@mui/material/CircularProgress'; -import Logo from '@components/Logo/Logo'; +import React, { useState } from "react"; +import styles from "./Login.module.css"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import { forgotPassword } from "../../services/loginServices"; // Make sure this function is properly implemented +import { useNavigate } from "react-router-dom"; +import CustomTextField from "../../components/TextFieldComponents/CustomTextField/CustomTextField"; +import CircularProgress from "@mui/material/CircularProgress"; +import Logo from "../../components/Logo/Logo"; +import * as Yup from "yup"; +import { useFormik } from "formik"; + +const validationSchema = Yup.object().shape({ + email: Yup.string() + .matches( + /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, + "Enter a valid email address" + ) + .required("Email is required") + .trim() +}) const ForgotPasswordPage = () => { const navigate = useNavigate(); - const [email, setEmail] = useState(''); - const [emailerror, setEmailError] = useState(false); - const [errorMessage, setErrorMessage] = useState(''); - const [loading, setLoading] = useState(false); + const [serverErrors, setServerErrors] = useState(""); + + const formik = useFormik({ + initialValues: { + email: "", + }, + validationSchema, + validateOnChange: true, + validateOnBlur: true, + onSubmit: async (values, { setSubmitting }) => { + setServerErrors([]); + try { + const response = await forgotPassword(values); + navigate("/check-email", { state: { values } }); + } catch (error) { + setServerErrors(error.response.data.error); + } finally { + setSubmitting(false); + } + }, + }); +console.log('hekki') +console.log(formik.errors.email) +console.log('yeah') - const handleSubmit = async (e) => { - e.preventDefault(); - setLoading(true); - try { - const userData = { email }; - const response = await forgotPassword(userData); - console.log('Password Reset successful:', response); - navigate('/check-email', { state: { email } }); - setLoading(false); - } catch (error) { - setEmailError(true); - setErrorMessage(error.response.data.error); - setLoading(false); - } - }; + const isFormEmpty = !formik.values.email; return ( - + { + e.preventDefault(); + formik.handleSubmit(e); + formik.setFieldTouched("email", true, false); + }} + className={styles["login-container"]} + > -

Forgot password?

+

Forgot password?

No worries, we'll send you reset instructions.

setEmail(e.target.value)} + required={true} + value={formik.values.email} + onChange={(e) => { + formik.handleChange(e); + formik.setFieldTouched('email', true, false) + }} + onBlur={formik.handleBlur} + error={Boolean(formik.touched.email && formik.errors.email)} + helperText={formik.touched.email && formik.errors.email} /> - {emailerror &&
{errorMessage}
} + + {serverErrors.length > 0 && ( +
{serverErrors}
+ )}
- - + diff --git a/frontend/src/scenes/login/LoginPage.jsx b/frontend/src/scenes/login/LoginPage.jsx index eb6214af..2ca9ee8e 100644 --- a/frontend/src/scenes/login/LoginPage.jsx +++ b/frontend/src/scenes/login/LoginPage.jsx @@ -1,53 +1,53 @@ -import React, { useState } from 'react'; -import styles from './Login.module.css'; -import CustomTextField from '@components/TextFieldComponents/CustomTextField/CustomTextField'; -import CircularProgress from '@mui/material/CircularProgress'; -import { login } from '../../services/loginServices'; -import CustomLink from '@components/CustomLink/CustomLink'; -import { handleAuthSuccess } from '../../utils/loginHelper'; -import { useAuth } from '../../services/authProvider'; -import { useNavigate } from 'react-router-dom'; -import Logo from '@components/Logo/Logo'; - +import React, { useState } from "react"; +import styles from "./Login.module.css"; +import CustomTextField from "../../components/TextFieldComponents/CustomTextField/CustomTextField"; +import CircularProgress from "@mui/material/CircularProgress"; +import { login } from "../../services/loginServices"; +import CustomLink from "../../components/CustomLink/CustomLink"; +import { handleAuthSuccess } from "../../utils/loginHelper"; +import { useAuth } from "../../services/authProvider"; +import { useNavigate } from "react-router-dom"; +import Logo from "../../components/Logo/Logo"; function LoginPage() { - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); const [rememberMe, setRememberMe] = useState(false); - const [loginError, setLoginError] = useState(false); const [loading, setLoading] = useState(false); - const [errorMessage, setErrorMessage] = useState(''); + const [errorMessages, setErrorMessages] = useState([]); const { loginAuth } = useAuth(); const navigate = useNavigate(); const handleSubmit = async (e) => { e.preventDefault(); setLoading(true); + setErrorMessages([]); try { const response = await login(email, password); handleAuthSuccess(response, loginAuth, navigate); + handleAuthSuccess(response, loginAuth, navigate); setLoading(false); } catch (error) { - setLoginError(true); - setLoading(false); - if (error.response?.data?.error) { - setErrorMessage(error.response.data.error); - } - else { - setErrorMessage('An error occurred. Please try again.'); + if (error.response?.data?.errors) { + setErrorMessages(error.response.data.errors); + } else if (error.response?.data?.error) { + setErrorMessages([error.response.data.error]); + } else { + setErrorMessages(["An error occurred. Please try again."]); } + setLoading(false); } }; - const handleEmailChange = e => { + const handleEmailChange = (e) => { setEmail(e.target.value); - setErrorMessage(''); - } + setErrorMessages([]); + }; - const handlePasswordChange = e => { + const handlePasswordChange = (e) => { setPassword(e.target.value); - setErrorMessage(''); - } + setErrorMessages([]); + }; return (
@@ -56,9 +56,9 @@ function LoginPage() {
- {loginError &&
{errorMessage}
} + {errorMessages.length > 0 && + errorMessages.map((msg, index) => ( +
+ {msg} +
+ ))}
@@ -92,8 +97,12 @@ function LoginPage() {
-
Don't have an account? diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index a75e31be..ae38e4a2 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -3,7 +3,7 @@ //export const API_BASE_URL = 'http://localhost:3000/api/'; //staging environment -export const API_BASE_URL = 'https://onboarding-demo.bluewavelabs.ca/api/'; +export const API_BASE_URL = 'http://localhost:3000/api/'; // Other constants export const APP_TITLE = 'Bluewave Onboarding'; export const SUPPORT_EMAIL = 'support@bluewave.com'; From b375c61b474abba044343895f8da3bef752c9b2c Mon Sep 17 00:00:00 2001 From: Amaan Pathan Date: Tue, 12 Nov 2024 22:46:11 +0530 Subject: [PATCH 19/66] Auth validations - frontend and backend --- backend/src/controllers/auth.controller.js | 2 + .../src/controllers/popuplog.controller.js | 2 +- backend/src/routes/auth.routes.js | 2 +- backend/src/utils/auth.helper.js | 8 +- frontend/dist/index.html | 5 +- .../src/scenes/login/CreateAccountPage.jsx | 59 ++++++--- .../src/scenes/login/ForgotPasswordPage.jsx | 20 ++- frontend/src/scenes/login/LoginPage.jsx | 125 +++++++++++------- frontend/src/services/loginServices.js | 47 +++---- 9 files changed, 161 insertions(+), 109 deletions(-) diff --git a/backend/src/controllers/auth.controller.js b/backend/src/controllers/auth.controller.js index 0afacd3c..4c34165a 100644 --- a/backend/src/controllers/auth.controller.js +++ b/backend/src/controllers/auth.controller.js @@ -9,6 +9,8 @@ const crypto = require('crypto'); const { TOKEN_LIFESPAN } = require('../utils/constants.helper'); const { sendSignupEmail, sendPasswordResetEmail } = require('../service/email.service'); const settings = require("../../config/settings"); +// const he = require('he'); +// const { create } = require("domain"); const findUserByEmail = async (email) => { return await User.findOne({ where: { email } }); diff --git a/backend/src/controllers/popuplog.controller.js b/backend/src/controllers/popuplog.controller.js index 9c42fe9d..cdf19d3f 100644 --- a/backend/src/controllers/popuplog.controller.js +++ b/backend/src/controllers/popuplog.controller.js @@ -1,5 +1,5 @@ const popupService = require("../service/popuplog.service.js"); -const { internalServerError } = require("../utils/errors.js"); +const { internalServerError } = require("../utils/errors.helper.js"); const {validationResult} = require('express-validator') const db = require("../models/index.js"); const PopupLog = db.PopupLog; diff --git a/backend/src/routes/auth.routes.js b/backend/src/routes/auth.routes.js index 9a2949fa..0eba22d4 100644 --- a/backend/src/routes/auth.routes.js +++ b/backend/src/routes/auth.routes.js @@ -9,6 +9,6 @@ router.post("/register", registerValidation, handleValidationErrors, register); router.post("/login", loginValidation, handleValidationErrors, login); router.post("/logout", authenticateJWT, logout); router.post("/forget-password", forgetPasswordValidation, handleValidationErrors, forgetPassword); -router.post("/reset-password", resetPassword, handleValidationErrors, resetPassword); +router.post("/reset-password", handleValidationErrors, resetPassword); module.exports = router; diff --git a/backend/src/utils/auth.helper.js b/backend/src/utils/auth.helper.js index 1d8ddcb5..0cb2d3ce 100644 --- a/backend/src/utils/auth.helper.js +++ b/backend/src/utils/auth.helper.js @@ -6,12 +6,16 @@ const registerValidation = [ body("password") .isLength({ min: 8 }) .withMessage("Must be atleast 8 characters") - .matches(/[!@#$%^&*(),.?":{}|<>]/) + .matches(/[!@#$%^&*(),.?":{}|<>_\-=]/) .withMessage("Must contain one special character"), ]; const loginValidation = [ - body("email").isEmail().withMessage("Invalid email address"), + body("email") + .isEmail() + .withMessage("Invalid email address") + .notEmpty() + .withMessage("Email is required"), body("password").notEmpty().withMessage("Password is required"), ]; diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 91ef3a93..da65df9b 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -5,13 +5,14 @@ Bluewave Onboarding - - + +
+ diff --git a/frontend/src/scenes/login/CreateAccountPage.jsx b/frontend/src/scenes/login/CreateAccountPage.jsx index 08c9ccbe..34fff3af 100644 --- a/frontend/src/scenes/login/CreateAccountPage.jsx +++ b/frontend/src/scenes/login/CreateAccountPage.jsx @@ -15,11 +15,17 @@ import { useFormik } from "formik"; const validationSchema = Yup.object().shape({ name: Yup.string() .required("Name is required") - .matches(/^[A-Za-z'-]+$/, "Name can only contain letters, hyphens and apostrophes") + .matches( + /^[A-Za-z'-]+$/, + "Name can only contain letters, hyphens and apostrophes" + ) .trim(), surname: Yup.string() .required("Surname is required") - .matches(/^[A-Za-z'-]+$/, "Surname can only contain letters, hyphens and apostrophes") + .matches( + /^[A-Za-z'-]+$/, + "Surname can only contain letters, hyphens and apostrophes" + ) .trim(), email: Yup.string() .matches( @@ -31,7 +37,10 @@ const validationSchema = Yup.object().shape({ password: Yup.string() .required("Password is required") .min(8, "Password must be at least 8 characters") - .matches(/[!@#$%^&*-_]/, "Password must contain at least one special character"), + .matches( + /[!@#$%^&*(),.?":{}|<>_\-=]/, + "Password must contain at least one special character" + ), }); function CreateAccountPage() { @@ -59,7 +68,9 @@ function CreateAccountPage() { } else if (error.response?.data?.error) { setServerErrors([error.response.data.error]); } else { - setServerErrors(["An error occurred. Please check your network connection and try again."]); + setServerErrors([ + "An error occurred. Please check your network connection and try again.", + ]); } } finally { setSubmitting(false); @@ -74,14 +85,16 @@ function CreateAccountPage() { !formik.values.password; const hasMinLength = formik.values.password.length >= 8; - const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(formik.values.password); + const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>_\-=]/.test( + formik.values.password + ); return ( { e.preventDefault(); formik.handleSubmit(e); - Object.keys(formik.values).forEach(key => { + Object.keys(formik.values).forEach((key) => { formik.setFieldTouched(key, true, false); }); }} @@ -90,14 +103,6 @@ function CreateAccountPage() {

Create an account

- {serverErrors.length > 0 && ( -
- {serverErrors.map((error, index) => ( -
{error}
- ))} -
- )} -
{ formik.handleChange(e); - formik.setFieldTouched('name', true, false); + formik.setFieldTouched("name", true, false); }} onBlur={formik.handleBlur} error={Boolean(formik.touched.surname && formik.errors.surname)} @@ -158,7 +165,7 @@ function CreateAccountPage() { value={formik.values.email} onChange={(e) => { formik.handleChange(e); - formik.setFieldTouched('surname', true, false); + formik.setFieldTouched("surname", true, false); }} onBlur={formik.handleBlur} error={Boolean(formik.touched.email && formik.errors.email)} @@ -173,7 +180,9 @@ function CreateAccountPage() { name="password" labelText="Password*:" checkCircleIconVisible={true} - displayCheckCircleIcon={formik.touched.password && !formik.errors.password} + displayCheckCircleIcon={ + formik.touched.password && !formik.errors.password + } placeholder="Create your password" textFieldMargin="none" TextFieldWidth="full" @@ -181,8 +190,8 @@ function CreateAccountPage() { value={formik.values.password} onChange={(e) => { formik.handleChange(e); - formik.setFieldTouched('email', true, false) - formik.setFieldTouched('password', true, false); + formik.setFieldTouched("email", true, false); + formik.setFieldTouched("password", true, false); }} onBlur={formik.handleBlur} error={Boolean(formik.touched.password && formik.errors.password)} @@ -211,6 +220,14 @@ function CreateAccountPage() { Must contain one special character
+ {serverErrors.length > 0 && ( +
+ {serverErrors.map((error, index) => ( +
{error}
+ ))} +
+ )} +
Don't have an account? diff --git a/frontend/src/services/loginServices.js b/frontend/src/services/loginServices.js index 8963fc11..caf3854b 100644 --- a/frontend/src/services/loginServices.js +++ b/frontend/src/services/loginServices.js @@ -1,6 +1,6 @@ -import {apiClient} from './apiClient'; -import axios from 'axios'; -import Cookies from 'js-cookie'; +import { apiClient } from "./apiClient"; +import axios from "axios"; +import Cookies from "js-cookie"; const authClient = axios.create({ ...apiClient.defaults, @@ -8,15 +8,15 @@ const authClient = axios.create({ }); // Function to handle login -export const login = async (email, password) => { +export const login = async (values) => { try { - const response = await authClient.post('/login', { email, password }); + const response = await authClient.post("/login", values); const token = response.data.token; - localStorage.setItem('authToken', token); + localStorage.setItem("authToken", token); return response.data; } catch (error) { - console.error('Login error:', error.response); + console.error("Login error:", error.response); throw error; } }; @@ -24,12 +24,12 @@ export const login = async (email, password) => { // Function to handle logout export const logout = async () => { try { - await apiClient.post('auth/logout'); - localStorage.removeItem('authToken'); + await apiClient.post("auth/logout"); + localStorage.removeItem("authToken"); return true; } catch (error) { - console.error('Logout error:', error.response); - localStorage.removeItem('authToken'); + console.error("Logout error:", error.response); + localStorage.removeItem("authToken"); throw error; } }; @@ -37,12 +37,12 @@ export const logout = async () => { // Function to handle sign up export const signUp = async (userData) => { try { - const response = await authClient.post('/register', userData); + const response = await authClient.post("/register", userData); const token = response.data.token; - localStorage.setItem('authToken', token); + localStorage.setItem("authToken", token); return response.data; } catch (error) { - console.error('Sign up error:', error.response); + console.error("Sign up error:", error.response); throw error; } }; @@ -50,7 +50,7 @@ export const signUp = async (userData) => { // Function to handle sign up export const forgotPassword = async (userData) => { try { - const response = await authClient.post('/forget-password', userData); + const response = await authClient.post("/forget-password", userData); return response.data; } catch (error) { console.error(error.response); @@ -60,7 +60,7 @@ export const forgotPassword = async (userData) => { export const resetPassword = async (userData) => { try { - const response = await authClient.post('/reset-password', userData); + const response = await authClient.post("/reset-password", userData); return response.data; } catch (error) { console.error(error.response); @@ -68,23 +68,20 @@ export const resetPassword = async (userData) => { } }; -export const getCurrentUser = async ()=> { +export const getCurrentUser = async () => { try { - const response = await apiClient.get('users/current-user'); + const response = await apiClient.get("users/current-user"); const user = response.data.user; const fullName = user.surname ? user.name + " " + user.surname : user.name; - Cookies.set('fullName', fullName); - Cookies.set('role', user.role); + Cookies.set("fullName", fullName); + Cookies.set("role", user.role); return user; } catch (error) { - console.error('Get user error:', error.response); - return {'fullName': 'John Doe', 'role': 'visitor'} + console.error("Get user error:", error.response); + return { fullName: "John Doe", role: "visitor" }; } }; export default authClient; - - - From a7f3dea34d3f34a238b43691560f4b497d51ae5e Mon Sep 17 00:00:00 2001 From: Amaan Pathan Date: Tue, 12 Nov 2024 22:50:10 +0530 Subject: [PATCH 20/66] undid some comments --- backend/src/controllers/auth.controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/controllers/auth.controller.js b/backend/src/controllers/auth.controller.js index 4c34165a..9ea5bf7e 100644 --- a/backend/src/controllers/auth.controller.js +++ b/backend/src/controllers/auth.controller.js @@ -9,8 +9,8 @@ const crypto = require('crypto'); const { TOKEN_LIFESPAN } = require('../utils/constants.helper'); const { sendSignupEmail, sendPasswordResetEmail } = require('../service/email.service'); const settings = require("../../config/settings"); -// const he = require('he'); -// const { create } = require("domain"); +const he = require('he'); +const { create } = require("domain"); const findUserByEmail = async (email) => { return await User.findOne({ where: { email } }); From 9456dd59a500965b438cce337e657c5b32415094 Mon Sep 17 00:00:00 2001 From: Amaan Pathan Date: Wed, 13 Nov 2024 23:35:32 +0530 Subject: [PATCH 21/66] Fixed onBlur validation checks --- .../CustomTextField/CustomTextField.jsx | 3 + .../src/scenes/login/CreateAccountPage.jsx | 349 ++++++++---------- .../src/scenes/login/ForgotPasswordPage.jsx | 151 ++++---- frontend/src/scenes/login/LoginPage.jsx | 223 ++++++----- 4 files changed, 349 insertions(+), 377 deletions(-) diff --git a/frontend/src/components/TextFieldComponents/CustomTextField/CustomTextField.jsx b/frontend/src/components/TextFieldComponents/CustomTextField/CustomTextField.jsx index d09c1124..6e1f2bc3 100644 --- a/frontend/src/components/TextFieldComponents/CustomTextField/CustomTextField.jsx +++ b/frontend/src/components/TextFieldComponents/CustomTextField/CustomTextField.jsx @@ -13,6 +13,7 @@ const CustomTextField = ({ labelText = "", value = "", onChange = () => { }, + onBlur = () => { }, helperText = "", error = false, multiline = false, @@ -52,6 +53,7 @@ const CustomTextField = ({ type={type} name={name} autoFocus={autofocus} + onBlur={onBlur} required={Boolean(required)} className="textField" sx={{ width: TextFieldWidth }} @@ -92,6 +94,7 @@ CustomTextField.propTypes = { labelText: PropTypes.string, value: PropTypes.string, onChange: PropTypes.func, + onBlur: PropTypes.func, defaultValue: PropTypes.string, helperText: PropTypes.string, error: PropTypes.bool, diff --git a/frontend/src/scenes/login/CreateAccountPage.jsx b/frontend/src/scenes/login/CreateAccountPage.jsx index 34fff3af..7293d3f7 100644 --- a/frontend/src/scenes/login/CreateAccountPage.jsx +++ b/frontend/src/scenes/login/CreateAccountPage.jsx @@ -10,7 +10,7 @@ import { useAuth } from "../../services/authProvider"; import { useNavigate } from "react-router-dom"; import Logo from "../../components/Logo/Logo"; import * as Yup from "yup"; -import { useFormik } from "formik"; +import { Form, Formik } from "formik"; const validationSchema = Yup.object().shape({ name: Yup.string() @@ -47,202 +47,177 @@ function CreateAccountPage() { const { loginAuth } = useAuth(); const navigate = useNavigate(); const [serverErrors, setServerErrors] = useState([]); - - const formik = useFormik({ - initialValues: { - name: "", - surname: "", - email: "", - password: "", - }, - validationSchema, - validateOnMount: false, - onSubmit: async (values, { setSubmitting }) => { - setServerErrors([]); - try { - const response = await signUp(values); - handleAuthSuccess(response, loginAuth, navigate); - } catch (error) { - if (error.response?.data?.errors) { - setServerErrors(error.response.data.errors); - } else if (error.response?.data?.error) { - setServerErrors([error.response.data.error]); - } else { - setServerErrors([ - "An error occurred. Please check your network connection and try again.", - ]); - } - } finally { - setSubmitting(false); - } - }, - }); - - const isFormEmpty = - !formik.values.name && - !formik.values.surname && - !formik.values.email && - !formik.values.password; - - const hasMinLength = formik.values.password.length >= 8; - const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>_\-=]/.test( - formik.values.password - ); - return ( - { - e.preventDefault(); - formik.handleSubmit(e); - Object.keys(formik.values).forEach((key) => { - formik.setFieldTouched(key, true, false); - }); + { + setServerErrors([]); + try { + const response = await signUp(values); + handleAuthSuccess(response, loginAuth, navigate); + } catch (error) { + if (error.response?.data?.errors) { + setServerErrors(error.response.data.errors); + } else if (error.response?.data?.error) { + setServerErrors([error.response.data.error]); + } else { + setServerErrors([ + "An error occurred. Please check your network connection and try again.", + ]); + } + } finally { + setSubmitting(false); + } }} - className={styles["login-container"]} > - -

Create an account

+ {({ + isSubmitting, + touched, + errors, + handleChange, + handleBlur, + values, + }) => ( + + +

Create an account

-
- { - formik.handleChange(e); - }} - onBlur={formik.handleBlur} - error={Boolean(formik.touched.name && formik.errors.name)} - helperText={formik.touched.name && formik.errors.name} - /> -
+
+ +
-
- { - formik.handleChange(e); - formik.setFieldTouched("name", true, false); - }} - onBlur={formik.handleBlur} - error={Boolean(formik.touched.surname && formik.errors.surname)} - helperText={formik.touched.surname && formik.errors.surname} - /> -
+
+ +
-
- { - formik.handleChange(e); - formik.setFieldTouched("surname", true, false); - }} - onBlur={formik.handleBlur} - error={Boolean(formik.touched.email && formik.errors.email)} - helperText={formik.touched.email && formik.errors.email} - /> -
+
+ +
-
- { - formik.handleChange(e); - formik.setFieldTouched("email", true, false); - formik.setFieldTouched("password", true, false); - }} - onBlur={formik.handleBlur} - error={Boolean(formik.touched.password && formik.errors.password)} - helperText={formik.touched.password && formik.errors.password} - /> -
+
+ +
-
- - Must be at least 8 characters -
-
- - Must contain one special character -
+
+ = 8 ? "green" : "#D0D5DD", + fontSize: "20px", + marginRight: "5px", + }} + /> + Must be at least 8 characters +
+
+ _\-=]/.test(values.password) + ? "green" + : "#D0D5DD", + fontSize: "20px", + marginRight: "5px", + }} + /> + Must contain one special character +
- {serverErrors.length > 0 && ( -
- {serverErrors.map((error, index) => ( -
{error}
- ))} -
- )} + {serverErrors.length > 0 && ( +
+ {serverErrors.map((error, index) => ( +
{error}
+ ))} +
+ )} - -
- Already have an account? -
- + +
+ Already have an account? +
+ + )} +
); } diff --git a/frontend/src/scenes/login/ForgotPasswordPage.jsx b/frontend/src/scenes/login/ForgotPasswordPage.jsx index beeddb9d..0721e993 100644 --- a/frontend/src/scenes/login/ForgotPasswordPage.jsx +++ b/frontend/src/scenes/login/ForgotPasswordPage.jsx @@ -7,7 +7,7 @@ import CustomTextField from "../../components/TextFieldComponents/CustomTextFiel import CircularProgress from "@mui/material/CircularProgress"; import Logo from "../../components/Logo/Logo"; import * as Yup from "yup"; -import { useFormik } from "formik"; +import { Form, Formik } from "formik"; const validationSchema = Yup.object().shape({ email: Yup.string() @@ -22,86 +22,83 @@ const validationSchema = Yup.object().shape({ const ForgotPasswordPage = () => { const navigate = useNavigate(); const [serverErrors, setServerErrors] = useState(""); - - const formik = useFormik({ - initialValues: { - email: "", - }, - validationSchema, - validateOnChange: true, - validateOnBlur: true, - onSubmit: async (values, { setSubmitting }) => { - setServerErrors([]); - try { - const response = await forgotPassword(values); - navigate("/check-email", { state: { values } }); - } catch (error) { - setServerErrors(error.response.data.error); - } finally { - setSubmitting(false); - } - }, - }); - const isFormEmpty = !formik.values.email; - return ( -
{ - e.preventDefault(); - formik.handleSubmit(e); - formik.setFieldTouched("email", true, false); + { + setServerErrors([]); + try { + const response = await forgotPassword(values); + navigate("/check-email", { state: { values } }); + } catch (error) { + setServerErrors(error.response.data.error); + } finally { + setSubmitting(false); + } }} - className={styles["login-container"]} > - -

Forgot password?

-

No worries, we'll send you reset instructions.

-
- { - formik.handleChange(e); - formik.setFieldTouched("email", true, false); - }} - onBlur={formik.handleBlur} - error={Boolean(formik.touched.email && formik.errors.email)} - helperText={formik.touched.email && formik.errors.email} - /> + {({ + isSubmitting, + touched, + errors, + handleChange, + handleBlur, + values, + }) => ( + + +

Forgot password?

+

No worries, we'll send you reset instructions.

+
+ - {serverErrors.length > 0 && ( -
{serverErrors}
- )} -
- - - + {serverErrors.length > 0 && ( +
{serverErrors}
+ )} +
+ + + + )} +
); }; diff --git a/frontend/src/scenes/login/LoginPage.jsx b/frontend/src/scenes/login/LoginPage.jsx index 7ac859dd..ab52edce 100644 --- a/frontend/src/scenes/login/LoginPage.jsx +++ b/frontend/src/scenes/login/LoginPage.jsx @@ -1,4 +1,6 @@ import React, { useState } from "react"; +import { Formik, Form, Field } from "formik"; +import * as Yup from "yup"; import styles from "./Login.module.css"; import CustomTextField from "../../components/TextFieldComponents/CustomTextField/CustomTextField"; import CircularProgress from "@mui/material/CircularProgress"; @@ -8,8 +10,6 @@ import { handleAuthSuccess } from "../../utils/loginHelper"; import { useAuth } from "../../services/authProvider"; import { useNavigate } from "react-router-dom"; import Logo from "../../components/Logo/Logo"; -import * as Yup from "yup"; -import { useFormik } from "formik"; const validationSchema = Yup.object({ email: Yup.string() @@ -24,125 +24,122 @@ const validationSchema = Yup.object({ function LoginPage() { const [rememberMe, setRememberMe] = useState(false); + const [serverErrors, setServerErrors] = useState([]); const { loginAuth } = useAuth(); const navigate = useNavigate(); - const [serverErrors, setServerErrors] = useState([]); - - const formik = useFormik({ - initialValues: { - email: "", - password: "", - }, - validationSchema, - validateOnMount: false, - onSubmit: async (values, { setSubmitting }) => { - setServerErrors([]); - try { - const response = await login(values); - handleAuthSuccess(response, loginAuth, navigate); - } catch (error) { - if (error.response?.data?.errors) { - setServerErrors(error.response.data.errors); - } else if (error.response?.data?.error) { - setServerErrors([error.response.data.error]); - } else { - setServerErrors([ - "An error occurred. Please check your network connection and try again.", - ]); - } - } finally { - setSubmitting(false); - } - }, - }); - - const isFormEmpty = !formik.values.email && !formik.values.password; return ( -
{ - e.preventDefault(); - formik.handleSubmit(e); - Object.keys(formik.values).forEach((key) => { - formik.setFieldTouched(key, true, false); - }); + { + setServerErrors([]); + try { + const response = await login(values); + handleAuthSuccess(response, loginAuth, navigate); + } catch (error) { + if (error.response?.data?.errors) { + setServerErrors(error.response.data.errors); + } else if (error.response?.data?.error) { + setServerErrors([error.response.data.error]); + } else { + setServerErrors([ + "An error occurred. Please check your network connection and try again.", + ]); + } + } finally { + setSubmitting(false); + } }} - className={styles["login-container"]} > - -

Log in to your account

-
- { - formik.handleChange(e); - }} - onBlur={formik.handleBlur} - error={Boolean(formik.touched.email && formik.errors.email)} - helperText={formik.touched.email && formik.errors.email} - /> -
-
- { - formik.handleChange(e); - formik.setFieldTouched("email", true, false); - formik.setFieldTouched("password", true, false); - }} - onBlur={formik.handleBlur} - error={Boolean(formik.touched.password && formik.errors.password)} - helperText={formik.touched.password && formik.errors.password} - /> - {serverErrors.length > 0 && ( -
- {serverErrors.map((error, index) => ( -
{error}
- ))} + {({ + isSubmitting, + touched, + errors, + handleChange, + handleBlur, + values, + }) => ( + + +

Log in to your account

+ +
+
- )} -
-
-
-
- -
- Don't have an account? -
- + + {serverErrors.length > 0 && ( +
+ {serverErrors.map((error, index) => ( +
{error}
+ ))} +
+ )} +
+ +
+
+ + +
+
+ + + + )} + ); } From f73bb8d4aacb411fdfb2a7f7615d0e8558cfca78 Mon Sep 17 00:00:00 2001 From: Amaan Pathan Date: Thu, 14 Nov 2024 12:00:12 +0530 Subject: [PATCH 22/66] Enhanced login page with sign-up link, improved validation for name and surname fields and used Formik and Yup to simplify SetNewPassword --- backend/src/controllers/auth.controller.js | 127 ++++++--- backend/src/service/email.service.js | 39 +-- backend/src/utils/auth.helper.js | 12 +- frontend/src/scenes/login/LoginPage.jsx | 5 +- frontend/src/scenes/login/SetNewPassword.jsx | 270 +++++++++++-------- 5 files changed, 288 insertions(+), 165 deletions(-) diff --git a/backend/src/controllers/auth.controller.js b/backend/src/controllers/auth.controller.js index 9ea5bf7e..a8213873 100644 --- a/backend/src/controllers/auth.controller.js +++ b/backend/src/controllers/auth.controller.js @@ -5,22 +5,24 @@ const Token = db.Token; const Invite = db.Invite; const sequelize = db.sequelize; const { generateToken, verifyToken } = require("../utils/jwt.helper"); -const crypto = require('crypto'); -const { TOKEN_LIFESPAN } = require('../utils/constants.helper'); -const { sendSignupEmail, sendPasswordResetEmail } = require('../service/email.service'); +const crypto = require("crypto"); +const { TOKEN_LIFESPAN } = require("../utils/constants.helper"); +const { + sendSignupEmail, + sendPasswordResetEmail, + findUserByEmail, +} = require("../service/email.service"); const settings = require("../../config/settings"); -const he = require('he'); +const he = require("he"); const { create } = require("domain"); -const findUserByEmail = async (email) => { - return await User.findOne({ where: { email } }); -}; - +const isTestingEnv = process.env.NODE_ENV === "test"; const register = async (req, res) => { try { const { name, surname, email, password } = req.body; - const existingUser = await findUserByEmail(email) - if (existingUser) return res.status(400).json({ error: "Email already exists" }); + const existingUser = await findUserByEmail(email); + if (existingUser) + return res.status(400).json({ error: "Email already exists" }); const userCount = await User.count(); const hashedPassword = await bcrypt.hash(password, 10); @@ -31,11 +33,13 @@ const register = async (req, res) => { if (!isTestingEnv) { invite = await Invite.findOne({ - where: { invitedEmail: email } + where: { invitedEmail: email }, }); if (!invite) { - return res.status(404).json({ error: "Invitation not found or expired" }); + return res + .status(404) + .json({ error: "Invitation not found or expired" }); } } @@ -43,32 +47,62 @@ const register = async (req, res) => { try { if (!isTestingEnv && invite) { await invite.destroy({ transaction }); - newUser = await User.create({ name, surname, email, password: hashedPassword, role: invite.role }, { transaction }); - } - else{ newUser = await User.create( - { name, surname, email, password: hashedPassword, role: settings.user.role.admin }, + { + name, + surname, + email, + password: hashedPassword, + role: invite.role, + }, + { transaction } + ); + } else { + newUser = await User.create( + { + name, + surname, + email, + password: hashedPassword, + role: settings.user.role.admin, + }, { transaction } ); } - + await transaction.commit(); } catch (err) { await transaction.rollback(); - return res.status(400).json({ error: "Error registering user by invite" }); + return res + .status(400) + .json({ error: "Error registering user by invite" }); } - } - else { - newUser = await User.create({ name, surname, email, password: hashedPassword, role: settings.user.role.admin }); + } else { + newUser = await User.create({ + name, + surname, + email, + password: hashedPassword, + role: settings.user.role.admin, + }); } const token = generateToken({ id: newUser.id, email: newUser.email }); - await Token.create({ token, userId: newUser.id, type: 'auth' }); + await Token.create({ token, userId: newUser.id, type: "auth" }); await sendSignupEmail(newUser.email, newUser.name); - res.status(201).json({ user: { id: newUser.id, name: newUser.name, surname: newUser.surname, email: newUser.email, role: settings.user.roleName[newUser.role] }, token }); + res.status(201).json({ + user: { + id: newUser.id, + name: newUser.name, + surname: newUser.surname, + email: newUser.email, + role: settings.user.roleName[newUser.role], + }, + token, + }); } catch (error) { console.error("Error registering user:", error); res.status(500).json({ error: "Internal Server Error" }); @@ -78,17 +112,27 @@ const register = async (req, res) => { const login = async (req, res) => { try { const { email, password } = req.body; - const user = await findUserByEmail(email) + const user = await findUserByEmail(email); if (!user || !(await bcrypt.compare(password, user.password))) { return res.status(401).json({ error: "Invalid credentials" }); } - await Token.destroy({ where: { userId: user.id, type: 'auth' } }); + await Token.destroy({ where: { userId: user.id, type: "auth" } }); const token = generateToken({ id: user.id, email: user.email }); - await Token.create({ token, userId: user.id, type: 'auth' }); - - res.status(200).json({ user: { id: user.id, name: user.name, surname: user.surname, email: user.email, role: settings.user.roleName[user.role], picture: user.picture ? he.decode(user.picture) : '' }, token }); + await Token.create({ token, userId: user.id, type: "auth" }); + + res.status(200).json({ + user: { + id: user.id, + name: user.name, + surname: user.surname, + email: user.email, + role: settings.user.roleName[user.role], + picture: user.picture ? he.decode(user.picture) : "", + }, + token, + }); } catch (error) { console.error("Error logging in user:", error); res.status(500).json({ error: "Internal Server Error" }); @@ -104,7 +148,9 @@ const logout = async (req, res) => { return res.status(401).json({ error: "Invalid token" }); } - const dbToken = await Token.findOne({ where: { token, userId: decoded.id, type: 'auth' } }); + const dbToken = await Token.findOne({ + where: { token, userId: decoded.id, type: "auth" }, + }); if (!dbToken) { return res.status(401).json({ error: "Invalid token" }); } @@ -120,13 +166,18 @@ const logout = async (req, res) => { const forgetPassword = async (req, res) => { try { const { email } = req.body; - const user = await findUserByEmail(email) + const user = await findUserByEmail(email); if (!user) return res.status(400).json({ error: "User not found" }); - const resetToken = crypto.randomBytes(32).toString('hex'); + const resetToken = crypto.randomBytes(32).toString("hex"); const hash = await bcrypt.hash(resetToken, 10); const expiresAt = new Date(Date.now() + TOKEN_LIFESPAN); - await Token.create({ token: hash, userId: user.id, type: 'reset', expiresAt }); + await Token.create({ + token: hash, + userId: user.id, + type: "reset", + expiresAt, + }); await sendPasswordResetEmail(user.email, user.name, resetToken); res.status(200).json({ message: "Password reset token sent" }); @@ -139,9 +190,13 @@ const forgetPassword = async (req, res) => { const resetPassword = async (req, res) => { try { const { token, newPassword } = req.body; - const dbToken = await Token.findOne({ where: { type: 'reset' } }); + const dbToken = await Token.findOne({ where: { type: "reset" } }); - if (!dbToken || new Date(dbToken.expiresAt) < new Date() || !(await bcrypt.compare(token, dbToken.token))) { + if ( + !dbToken || + new Date(dbToken.expiresAt) < new Date() || + !(await bcrypt.compare(token, dbToken.token)) + ) { return res.status(400).json({ error: "Invalid or expired token" }); } @@ -162,5 +217,5 @@ module.exports = { login, logout, forgetPassword, - resetPassword -}; \ No newline at end of file + resetPassword, +}; diff --git a/backend/src/service/email.service.js b/backend/src/service/email.service.js index 4a1131ab..d58a4a73 100644 --- a/backend/src/service/email.service.js +++ b/backend/src/service/email.service.js @@ -1,24 +1,26 @@ -const nodemailer = require('nodemailer'); -const handlebars = require('handlebars'); -const fs = require('fs'); -const path = require('path'); -const { API_BASE_URL } = require('../utils/constants.helper'); +const nodemailer = require("nodemailer"); +const handlebars = require("handlebars"); +const fs = require("fs"); +const path = require("path"); +const { API_BASE_URL } = require("../utils/constants.helper"); +const db = require("../models"); +const User = db.User; -const emailEnabled = process.env.EMAIL_ENABLE === 'true'; +const emailEnabled = process.env.EMAIL_ENABLE === "true"; const transporter = nodemailer.createTransport({ - host: process.env.EMAIL_HOST || 'localhost', + host: process.env.EMAIL_HOST || "localhost", port: process.env.EMAIL_PORT || 465, secure: true, auth: { user: process.env.EMAIL, - pass: process.env.APP_PASSWORD - } + pass: process.env.APP_PASSWORD, + }, }); const readHTMLFile = (filePath) => { return new Promise((resolve, reject) => { - fs.readFile(filePath, { encoding: 'utf-8' }, (err, html) => { + fs.readFile(filePath, { encoding: "utf-8" }, (err, html) => { if (err) { reject(err); } else { @@ -28,9 +30,13 @@ const readHTMLFile = (filePath) => { }); }; +const findUserByEmail = async (email) => { + return await User.findOne({ where: { email } }); +}; + const sendEmail = async (to, subject, templateName, replacements) => { if (!emailEnabled) { - console.log('Email sending is disabled.'); + console.log("Email sending is disabled."); return; } @@ -43,19 +49,22 @@ const sendEmail = async (to, subject, templateName, replacements) => { from: process.env.EMAIL, to, subject, - html: htmlToSend + html: htmlToSend, }; await transporter.sendMail(mailOptions); }; const sendSignupEmail = async (email, name) => { - await sendEmail(email, 'Welcome to Our Service', 'signup', { name }); + await sendEmail(email, "Welcome to Our Service", "signup", { name }); }; const sendPasswordResetEmail = async (email, name, resetToken) => { const resetLink = `${API_BASE_URL}reset-password?token=${resetToken}`; - await sendEmail(email, 'Password Reset', 'resetPassword', { name, resetLink }); + await sendEmail(email, "Password Reset", "resetPassword", { + name, + resetLink, + }); }; -module.exports = { sendSignupEmail, sendPasswordResetEmail }; +module.exports = { sendSignupEmail, sendPasswordResetEmail, findUserByEmail }; diff --git a/backend/src/utils/auth.helper.js b/backend/src/utils/auth.helper.js index 0cb2d3ce..b5ddbcd8 100644 --- a/backend/src/utils/auth.helper.js +++ b/backend/src/utils/auth.helper.js @@ -1,7 +1,15 @@ const { body } = require("express-validator"); const registerValidation = [ - body("name").notEmpty().withMessage("Name is required"), - body("surname").notEmpty().withMessage("Surname is required"), + body("name") + .notEmpty() + .withMessage("Name is required") + .matches(/^[A-Za-z'-]+$/) + .withMessage("Name can only contain letters, hyphens and apostrophes"), + body("surname") + .notEmpty() + .withMessage("Surname is required") + .matches(/^[A-Za-z'-]+$/) + .withMessage("Name can only contain letters, hyphens and apostrophes"), body("email").isEmail().withMessage("Invalid email address"), body("password") .isLength({ min: 8 }) diff --git a/frontend/src/scenes/login/LoginPage.jsx b/frontend/src/scenes/login/LoginPage.jsx index ab52edce..82f1d1f3 100644 --- a/frontend/src/scenes/login/LoginPage.jsx +++ b/frontend/src/scenes/login/LoginPage.jsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { Formik, Form, Field } from "formik"; +import { Formik, Form } from "formik"; import * as Yup from "yup"; import styles from "./Login.module.css"; import CustomTextField from "../../components/TextFieldComponents/CustomTextField/CustomTextField"; @@ -137,6 +137,9 @@ function LoginPage() { "Sign In" )} +
+ Don't have an account? +
)} diff --git a/frontend/src/scenes/login/SetNewPassword.jsx b/frontend/src/scenes/login/SetNewPassword.jsx index df91ba48..53bbf9d3 100644 --- a/frontend/src/scenes/login/SetNewPassword.jsx +++ b/frontend/src/scenes/login/SetNewPassword.jsx @@ -1,121 +1,169 @@ -import React, { useState } from 'react'; -import styles from './Login.module.css'; -import CheckCircleIcon from '@mui/icons-material/CheckCircle'; -import CustomTextField from '@components/TextFieldComponents/CustomTextField/CustomTextField'; -import ArrowBackIcon from '@mui/icons-material/ArrowBack'; -import CircularProgress from '@mui/material/CircularProgress'; -import { resetPassword } from '../../services/loginServices'; -import { useNavigate } from 'react-router-dom'; +import React, { useState } from "react"; +import styles from "./Login.module.css"; +import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import CircularProgress from "@mui/material/CircularProgress"; +import { resetPassword } from "../../services/loginServices"; +import { useNavigate } from "react-router-dom"; +import * as Yup from "yup"; +import { Formik } from "formik"; -function SetNewPasswordPage({ email = 'asdf@asdf.com' }) { - const [password, setPassword] = useState(''); - const [confirmPassword, setConfirmPassword] = useState(''); - const [isPasswordValid, setIsPasswordValid] = useState(false); - const [hasSpecialCharacter, setHasSpecialCharacter] = useState(false); - const [atLeastEightCharacters, setAtLeastEightCharacters] = useState(false); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(''); +function SetNewPasswordPage({ email = "asdf@asdf.com" }) { + const [serverErrors, setServerErrors] = useState([]); const navigate = useNavigate(); - const handleResetPassword = async (e) => { - e.preventDefault(); - setLoading(true); - setError(''); - try { - const response = await resetPassword({ email, password }); - setLoading(false); - console.log('Password Reset successful:', response); - navigate('/reset-password'); - } catch (error) { - setLoading(false); - console.error('Password Reset failed:', error); - if (error.response?.data?.error) { - setError(error.response.data.error); - } - else { - setError('An error occurred. Please try again.'); - } - } - }; - - - const handlePasswordChange = (e) => { - setPassword(e.target.value); - setHasSpecialCharacter(hasSpecialCharacterCheck(e.target.value)); - setAtLeastEightCharacters(atLeastEightCharactersCheck(e.target.value)); - setIsPasswordValid(validatePassword(e.target.value)); - }; - - const handleConfirmPasswordChange = (e) => { - setConfirmPassword(e.target.value); - }; - - const hasSpecialCharacterCheck = (password) => { - const regex = /[!@#$%^&*-_]/; - return regex.test(password); - }; - - const atLeastEightCharactersCheck = (password) => { - return password.length >= 8; - }; - - const validatePassword = (password) => { - return atLeastEightCharactersCheck(password) && hasSpecialCharacterCheck(password); - }; + const validationSchema = Yup.object({ + password: Yup.string() + .required("Password is required") + .min(8, "Password must be at least 8 characters") + .matches( + /[!@#$%^&*(),.?":{}|<>_\-=]/, + "Password must contain at least one special character" + ), + confirmPassword: Yup.string() + .required("Password is required") + .min(8, "Password must be at least 8 characters") + .matches( + /[!@#$%^&*(),.?":{}|<>_\-=]/, + "Password must contain at least one special character" + ), + }); return ( -
-
-

Set new Password

-

Your new password must be different to previously used passwords.

-
- -
-
- - {error &&
{error}
} -
+ { + setServerError([]); + try { + const respone = await resetPassword(email, values.password); + navigate("/reset-password"); + } catch (error) { + console.error("Password Reset failed:", error); + if (error.respone?.data?.errors) { + setServerErrors(error.respone?.data?.errors); + } else if (error.response?.data?.error) { + setServerErrors([error.response.data.error]); + } else { + setServerErrors(["An error occurred. Please try again."]); + } + } finally { + setSubmitting(false); + } + }} + > + {({ + isSubmitting, + touched, + errors, + handleChange, + handleBlur, + values, + }) => ( +
+ +

Set new Password

+

+ Your new password must be different to previously used passwords. +

+
+ +
+
+ + {serverErrors && ( +
{serverErrors}
+ )} +
-
- - Must be at least 8 characters -
-
- - Must contain one special character +
+ = 8 + ? "green" + : "var(--light-border-color)", + fontSize: "20px", + marginRight: "5px", + }} + /> + Must be at least 8 characters +
+
+ _\-=]/.test(values.password) + ? "green" + : "var(--light-border-color)", + fontSize: "20px", + marginRight: "5px", + }} + /> + Must contain one special character +
+ + +
- - - -
+ )} +
); } From a1e30b1b1dd84824b1267dbcb2f0065f76a4a719 Mon Sep 17 00:00:00 2001 From: Amaan Pathan Date: Thu, 14 Nov 2024 15:54:13 +0530 Subject: [PATCH 23/66] Added suggested edits --- .../src/controllers/popuplog.controller.js | 1 - backend/src/utils/auth.helper.js | 2 +- .../src/scenes/login/CreateAccountPage.jsx | 2 +- .../src/scenes/login/ForgotPasswordPage.jsx | 2 +- frontend/src/scenes/login/LoginPage.jsx | 12 ++++++----- frontend/src/scenes/login/SetNewPassword.jsx | 20 +++++++------------ 6 files changed, 17 insertions(+), 22 deletions(-) diff --git a/backend/src/controllers/popuplog.controller.js b/backend/src/controllers/popuplog.controller.js index cdf19d3f..01c1883a 100644 --- a/backend/src/controllers/popuplog.controller.js +++ b/backend/src/controllers/popuplog.controller.js @@ -1,6 +1,5 @@ const popupService = require("../service/popuplog.service.js"); const { internalServerError } = require("../utils/errors.helper.js"); -const {validationResult} = require('express-validator') const db = require("../models/index.js"); const PopupLog = db.PopupLog; diff --git a/backend/src/utils/auth.helper.js b/backend/src/utils/auth.helper.js index b5ddbcd8..c01d7756 100644 --- a/backend/src/utils/auth.helper.js +++ b/backend/src/utils/auth.helper.js @@ -13,7 +13,7 @@ const registerValidation = [ body("email").isEmail().withMessage("Invalid email address"), body("password") .isLength({ min: 8 }) - .withMessage("Must be atleast 8 characters") + .withMessage("Must be at least 8 characters") .matches(/[!@#$%^&*(),.?":{}|<>_\-=]/) .withMessage("Must contain one special character"), ]; diff --git a/frontend/src/scenes/login/CreateAccountPage.jsx b/frontend/src/scenes/login/CreateAccountPage.jsx index 7293d3f7..d15bfe23 100644 --- a/frontend/src/scenes/login/CreateAccountPage.jsx +++ b/frontend/src/scenes/login/CreateAccountPage.jsx @@ -56,7 +56,7 @@ function CreateAccountPage() { password: "", }} validationSchema={validationSchema} - validateOnMount={false} + validateonMount={false} validateonBlur={true} onSubmit={async (values, { setSubmitting }) => { setServerErrors([]); diff --git a/frontend/src/scenes/login/ForgotPasswordPage.jsx b/frontend/src/scenes/login/ForgotPasswordPage.jsx index 0721e993..c41d36fc 100644 --- a/frontend/src/scenes/login/ForgotPasswordPage.jsx +++ b/frontend/src/scenes/login/ForgotPasswordPage.jsx @@ -36,7 +36,7 @@ const ForgotPasswordPage = () => { const response = await forgotPassword(values); navigate("/check-email", { state: { values } }); } catch (error) { - setServerErrors(error.response.data.error); + setServerErrors(error.response?.data?.error); } finally { setSubmitting(false); } diff --git a/frontend/src/scenes/login/LoginPage.jsx b/frontend/src/scenes/login/LoginPage.jsx index 82f1d1f3..90c299af 100644 --- a/frontend/src/scenes/login/LoginPage.jsx +++ b/frontend/src/scenes/login/LoginPage.jsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { Formik, Form } from "formik"; +import { Formik, Form, Field } from "formik"; import * as Yup from "yup"; import styles from "./Login.module.css"; import CustomTextField from "../../components/TextFieldComponents/CustomTextField/CustomTextField"; @@ -20,6 +20,7 @@ const validationSchema = Yup.object({ ) .trim(), password: Yup.string().required("Password is required").trim(), + rememberMe: Yup.boolean() }); function LoginPage() { @@ -33,12 +34,14 @@ function LoginPage() { initialValues={{ email: "", password: "", + rememberMe: false }} validationSchema={validationSchema} validateOnChange={false} validateOnBlur={true} onSubmit={async (values, { setSubmitting }) => { setServerErrors([]); + console.log(values) try { const response = await login(values); handleAuthSuccess(response, loginAuth, navigate); @@ -115,10 +118,9 @@ function LoginPage() {
@@ -129,7 +131,7 @@ function LoginPage() {
From 234d093f784e69c470abc97f92e171d72573d385 Mon Sep 17 00:00:00 2001 From: Amaan Pathan Date: Sat, 16 Nov 2024 12:04:35 +0530 Subject: [PATCH 26/66] updated the auth tests and made minor changes to name regex --- backend/src/utils/auth.helper.js | 4 +- .../src/scenes/login/CreateAccountPage.jsx | 4 +- frontend/src/scenes/login/LoginPage.jsx | 8 +- frontend/src/scenes/login/SetNewPassword.jsx | 11 +- .../scenes/login/CreateAccountPage.test.jsx | 89 ++++------ .../src/tests/scenes/login/LoginPage.test.jsx | 60 +++++-- .../scenes/login/SetNewPassword.test.jsx | 155 +++++++++++------- 7 files changed, 193 insertions(+), 138 deletions(-) diff --git a/backend/src/utils/auth.helper.js b/backend/src/utils/auth.helper.js index c01d7756..917728b4 100644 --- a/backend/src/utils/auth.helper.js +++ b/backend/src/utils/auth.helper.js @@ -3,12 +3,12 @@ const registerValidation = [ body("name") .notEmpty() .withMessage("Name is required") - .matches(/^[A-Za-z'-]+$/) + .matches(/^[A-Za-z'\s-]+$/) .withMessage("Name can only contain letters, hyphens and apostrophes"), body("surname") .notEmpty() .withMessage("Surname is required") - .matches(/^[A-Za-z'-]+$/) + .matches(/^[A-Za-z'\s-]+$/) .withMessage("Name can only contain letters, hyphens and apostrophes"), body("email").isEmail().withMessage("Invalid email address"), body("password") diff --git a/frontend/src/scenes/login/CreateAccountPage.jsx b/frontend/src/scenes/login/CreateAccountPage.jsx index d15bfe23..431f0a96 100644 --- a/frontend/src/scenes/login/CreateAccountPage.jsx +++ b/frontend/src/scenes/login/CreateAccountPage.jsx @@ -16,14 +16,14 @@ const validationSchema = Yup.object().shape({ name: Yup.string() .required("Name is required") .matches( - /^[A-Za-z'-]+$/, + /^[A-Za-z'\s-]+$/, "Name can only contain letters, hyphens and apostrophes" ) .trim(), surname: Yup.string() .required("Surname is required") .matches( - /^[A-Za-z'-]+$/, + /^[A-Za-z'\s-]+$/, "Surname can only contain letters, hyphens and apostrophes" ) .trim(), diff --git a/frontend/src/scenes/login/LoginPage.jsx b/frontend/src/scenes/login/LoginPage.jsx index b9bd7ab2..1433d2d6 100644 --- a/frontend/src/scenes/login/LoginPage.jsx +++ b/frontend/src/scenes/login/LoginPage.jsx @@ -20,10 +20,10 @@ const validationSchema = Yup.object({ ) .trim(), password: Yup.string().required("Password is required").trim(), - rememberMe: Yup.boolean() }); function LoginPage() { + const [rememberMe, setRememberMe]=useState(false) const [serverErrors, setServerErrors] = useState([]); const { loginAuth } = useAuth(); const navigate = useNavigate(); @@ -33,7 +33,6 @@ function LoginPage() { initialValues={{ email: "", password: "", - rememberMe: false }} validationSchema={validationSchema} validateOnChange={false} @@ -116,9 +115,10 @@ function LoginPage() {
diff --git a/frontend/src/scenes/login/SetNewPassword.jsx b/frontend/src/scenes/login/SetNewPassword.jsx index 32c3de13..91537ad8 100644 --- a/frontend/src/scenes/login/SetNewPassword.jsx +++ b/frontend/src/scenes/login/SetNewPassword.jsx @@ -38,7 +38,10 @@ function SetNewPasswordPage({ email = "asdf@asdf.com" }) { onSubmit={async (values, { setSubmitting }) => { setServerErrors([]); try { - const respone = await resetPassword(email, values.password); + const response = await resetPassword({ + email: email, + password: values.password, + }); navigate("/reset-password"); } catch (error) { console.error("Password Reset failed:", error); @@ -83,6 +86,8 @@ function SetNewPasswordPage({ email = "asdf@asdf.com" }) { value={values.password} onChange={handleChange} onBlur={handleBlur} + error={Boolean(touched.password && errors.password)} + helperText={touched.password && errors.password} />
@@ -104,6 +109,10 @@ function SetNewPasswordPage({ email = "asdf@asdf.com" }) { value={values.confirmPassword} onChange={handleChange} onBlur={handleBlur} + error={Boolean( + touched.confirmPassword && errors.confirmPassword + )} + helperText={touched.confirmPassword && errors.confirmPassword} /> {serverErrors.length > 0 && (
diff --git a/frontend/src/tests/scenes/login/CreateAccountPage.test.jsx b/frontend/src/tests/scenes/login/CreateAccountPage.test.jsx index 816c2a2c..5bb75a3e 100644 --- a/frontend/src/tests/scenes/login/CreateAccountPage.test.jsx +++ b/frontend/src/tests/scenes/login/CreateAccountPage.test.jsx @@ -1,10 +1,11 @@ import { render, screen, fireEvent, act, waitFor } from '@testing-library/react'; import { describe, it, expect, vi } from 'vitest'; import { BrowserRouter as Router } from 'react-router-dom'; +import { AuthProvider } from '../../../services/authProvider'; import CreateAccountPage from '../../../scenes/login/CreateAccountPage'; import { signUp } from '../../../services/loginServices'; -import { AuthProvider } from '../../../services/authProvider'; +// Mock login services vi.mock('../../../services/loginServices', () => ({ signUp: vi.fn(), })); @@ -19,12 +20,12 @@ describe('CreateAccountPage', () => { ); - expect(screen.getByText('Create an account')).to.exist; - expect(screen.getByPlaceholderText('Enter your name')).to.exist; - expect(screen.getByPlaceholderText('Enter your surname')).to.exist; - expect(screen.getByPlaceholderText('Enter your email')).to.exist; - expect(screen.getByPlaceholderText('Create your password')).to.exist; - expect(screen.getByText('Get started')).to.exist; + expect(screen.getByText('Create an account')).toBeTruthy(); + expect(screen.getByPlaceholderText('Enter your name')).toBeTruthy(); + expect(screen.getByPlaceholderText('Enter your surname')).toBeTruthy(); + expect(screen.getByPlaceholderText('Enter your email')).toBeTruthy(); + expect(screen.getByPlaceholderText('Create your password')).toBeTruthy(); + expect(screen.getByText('Get started')).toBeTruthy(); }); it('validates name input', () => { @@ -36,10 +37,9 @@ describe('CreateAccountPage', () => { ); - const usernameInput = screen.getByPlaceholderText('Enter your name'); - fireEvent.change(usernameInput, { target: { value: 'testname' } }); - - expect(usernameInput.value).to.equal('testname'); + const nameInput = screen.getByPlaceholderText('Enter your name'); + fireEvent.change(nameInput, { target: { value: 'testname' } }); + expect(nameInput.value).toBe('testname'); }); it('validates surname input', () => { @@ -51,10 +51,9 @@ describe('CreateAccountPage', () => { ); - const usernameInput = screen.getByPlaceholderText('Enter your surname'); - fireEvent.change(usernameInput, { target: { value: 'testsurname' } }); - - expect(usernameInput.value).to.equal('testsurname'); + const surnameInput = screen.getByPlaceholderText('Enter your surname'); + fireEvent.change(surnameInput, { target: { value: 'testsurname' } }); + expect(surnameInput.value).toBe('testsurname'); }); it('validates email input', () => { @@ -68,8 +67,7 @@ describe('CreateAccountPage', () => { const emailInput = screen.getByPlaceholderText('Enter your email'); fireEvent.change(emailInput, { target: { value: 'test@example.com' } }); - - expect(emailInput.value).to.equal('test@example.com'); + expect(emailInput.value).toBe('test@example.com'); }); it('validates password input', () => { @@ -83,8 +81,7 @@ describe('CreateAccountPage', () => { const passwordInput = screen.getByPlaceholderText('Create your password'); fireEvent.change(passwordInput, { target: { value: 'Password1!' } }); - - expect(passwordInput.value).to.equal('Password1!'); + expect(passwordInput.value).toBe('Password1!'); }); it('handles sign up success', async () => { @@ -106,8 +103,13 @@ describe('CreateAccountPage', () => { fireEvent.click(screen.getByText('Get started')); }); - expect(signUp).toHaveBeenCalledWith({ name: 'testname', surname: 'testsurname', email: 'test@example.com', password: 'Password1!' }); - // Add more assertions as needed + expect(signUp).toHaveBeenCalledWith({ + name: 'testname', + surname: 'testsurname', + email: 'test@example.com', + password: 'Password1!' + }); + expect(screen.queryByText('An error occurred.')).toBeFalsy(); }); it('handles sign up failure with email already exists error', async () => { @@ -135,41 +137,16 @@ describe('CreateAccountPage', () => { }); await waitFor(() => { - expect(screen.getByText('Email already exists')).to.exist; + expect(screen.getByText('Email already exists')).toBeTruthy(); }); - expect(signUp).toHaveBeenCalledWith({ name: 'testname', surname: 'testsurname', email: 'test@example.com', password: 'Password1!' }); - }); - - it('handles sign up failure with other errors', async () => { - signUp.mockRejectedValueOnce({ - response: { - data: { error: 'Some other error' }, - status: 500, - }, + expect(signUp).toHaveBeenCalledWith({ + name: 'testname', + surname: 'testsurname', + email: 'test@example.com', + password: 'Password1!' }); - - render( - - - - - - ); - - await act(async () => { - fireEvent.change(screen.getByPlaceholderText('Enter your name'), { target: { value: 'testname' } }); - fireEvent.change(screen.getByPlaceholderText('Enter your surname'), { target: { value: 'testsurname' } }); - fireEvent.change(screen.getByPlaceholderText('Enter your email'), { target: { value: 'test@example.com' } }); - fireEvent.change(screen.getByPlaceholderText('Create your password'), { target: { value: 'Password1!' } }); - fireEvent.click(screen.getByText('Get started')); - }); - - await waitFor(() => { - expect(screen.getByText('An error occurred. Please try again.')).to.exist; - }); - - expect(signUp).toHaveBeenCalledWith({ name: 'testname', surname: 'testsurname', email: 'test@example.com', password: 'Password1!' }); + expect(screen.queryByText('An error occurred.')).toBeFalsy(); }); it('handles network errors gracefully', async () => { @@ -192,9 +169,7 @@ describe('CreateAccountPage', () => { }); await waitFor(() => { - expect(screen.getByText('An error occurred. Please check your network connection and try again.')).to.exist; + expect(screen.getByText('An error occurred. Please check your network connection and try again.')).toBeTruthy(); }); - - expect(signUp).toHaveBeenCalledWith({ name: 'testname', surname: 'testsurname', email: 'test@example.com', password: 'Password1!' }); }); -}); +}); \ No newline at end of file diff --git a/frontend/src/tests/scenes/login/LoginPage.test.jsx b/frontend/src/tests/scenes/login/LoginPage.test.jsx index 76bd470a..260eae0e 100644 --- a/frontend/src/tests/scenes/login/LoginPage.test.jsx +++ b/frontend/src/tests/scenes/login/LoginPage.test.jsx @@ -1,9 +1,9 @@ -import { render, screen, fireEvent, act } from '@testing-library/react'; +import { render, waitFor, screen, fireEvent, act } from '@testing-library/react'; import { describe, it, expect, vi } from 'vitest'; import { BrowserRouter as Router } from 'react-router-dom'; import LoginPage from '../../../scenes/login/LoginPage'; import * as loginServices from '../../../services/loginServices'; -import { AuthProvider } from '../../../services/authProvider'; // Import your AuthProvider +import { AuthProvider } from '../../../services/authProvider'; vi.mock('../../../services/loginServices'); @@ -17,10 +17,10 @@ describe('LoginPage', () => { ); - expect(screen.getByText('Log in to your account')).not.toBeNull(); - expect(screen.getByPlaceholderText('Enter email')).not.toBeNull(); - expect(screen.getByPlaceholderText('Enter password')).not.toBeNull(); - expect(screen.getByText("Don't have an account?")).not.toBeNull(); + expect(screen.getByText('Log in to your account')).toBeTruthy(); + expect(screen.getByPlaceholderText('Enter email')).toBeTruthy(); + expect(screen.getByPlaceholderText('Enter password')).toBeTruthy(); + expect(screen.getByText("Don't have an account?")).toBeTruthy(); }); it('handles login success', async () => { @@ -35,17 +35,25 @@ describe('LoginPage', () => { ); await act(async () => { - fireEvent.change(screen.getByPlaceholderText('Enter email'), { target: { value: 'test@example.com' } }); - fireEvent.change(screen.getByPlaceholderText('Enter password'), { target: { value: 'password' } }); + fireEvent.change(screen.getByPlaceholderText('Enter email'), + { target: { value: 'test@example.com' } } + ); + fireEvent.change(screen.getByPlaceholderText('Enter password'), + { target: { value: 'password' } } + ); fireEvent.click(screen.getByText('Sign In')); }); - expect(loginServices.login).toHaveBeenCalledWith('test@example.com', 'password'); - // Add more assertions as needed + expect(loginServices.login).toHaveBeenCalledWith({ + email: 'test@example.com', + password: 'password' + }); }); it('handles login failure', async () => { - loginServices.login.mockRejectedValueOnce({ response: { data: { error: 'Invalid credentials' } } }); + loginServices.login.mockRejectedValueOnce({ + response: { data: { error: 'Invalid credentials' } } + }); render( @@ -56,11 +64,33 @@ describe('LoginPage', () => { ); await act(async () => { - fireEvent.change(screen.getByPlaceholderText('Enter email'), { target: { value: 'test@example.com' } }); - fireEvent.change(screen.getByPlaceholderText('Enter password'), { target: { value: 'wrongpassword' } }); + fireEvent.change(screen.getByPlaceholderText('Enter email'), + { target: { value: 'test@example.com' } } + ); + fireEvent.change(screen.getByPlaceholderText('Enter password'), + { target: { value: 'wrongpassword' } } + ); fireEvent.click(screen.getByText('Sign In')); }); - expect(await screen.findByText('Invalid credentials')).not.toBeNull(); + await waitFor(() => { + expect(screen.getByText('Invalid credentials')).toBeTruthy(); + }); + }); + + it('handles remember me checkbox', () => { + render( + + + + + + ); + + const checkbox = screen.getByLabelText('Remember for 30 days'); + expect(checkbox.checked).toBe(false); + + fireEvent.click(checkbox); + expect(checkbox.checked).toBe(true); }); -}); +}); \ No newline at end of file diff --git a/frontend/src/tests/scenes/login/SetNewPassword.test.jsx b/frontend/src/tests/scenes/login/SetNewPassword.test.jsx index 89947a04..b4b04fee 100644 --- a/frontend/src/tests/scenes/login/SetNewPassword.test.jsx +++ b/frontend/src/tests/scenes/login/SetNewPassword.test.jsx @@ -1,69 +1,110 @@ -import { render, screen, fireEvent, act, waitFor } from '@testing-library/react'; -import { describe, it, expect, vi } from 'vitest'; -import { BrowserRouter as Router } from 'react-router-dom'; -import { AuthProvider } from '../../../services/authProvider'; // Import your AuthProvider -import SetNewPassword from '../../../scenes/login/SetNewPassword'; -import { resetPassword } from '../../../services/loginServices'; - -vi.mock('../../../services/loginServices', () => ({ - resetPassword: vi.fn(), +import { + render, + screen, + fireEvent, + act, + waitFor, +} from "@testing-library/react"; +import { describe, it, expect, vi } from "vitest"; +import { BrowserRouter as Router } from "react-router-dom"; +import { AuthProvider } from "../../../services/authProvider"; // Import your AuthProvider +import SetNewPassword from "../../../scenes/login/SetNewPassword"; +import { resetPassword } from "../../../services/loginServices"; + +vi.mock("../../../services/loginServices", () => ({ + resetPassword: vi.fn(), })); -describe('SetNewPasswordPage', () => { - it('renders the set new password reset page', () => { - render( - - - - - - ); - - expect(screen.getByText('Set new Password')).not.toBeNull(); - expect(screen.getByText('Your new password must be different to previously used passwords.')).not.toBeNull(); +describe("SetNewPasswordPage", () => { + it("renders the set new password reset page", () => { + render( + + + + + + ); + + expect(screen.getByText("Set new Password")).toBeTruthy(); + expect( + screen.getByText( + "Your new password must be different to previously used passwords." + ) + ).toBeTruthy(); + }); + + it("handles reset password success", async () => { + resetPassword.mockResolvedValueOnce({ data: { success: true } }); + + render( + + + + + + ); + + await act(async () => { + const validPassword = "Test123!@"; + + fireEvent.change(screen.getByPlaceholderText("Create your password"), { + target: { value: validPassword }, + }); + fireEvent.change(screen.getByPlaceholderText("Confirm your password"), { + target: { value: validPassword }, + }); + + fireEvent.blur(screen.getByPlaceholderText("Create your password")); + fireEvent.blur(screen.getByPlaceholderText("Confirm your password")); + + const resetButton = screen.getByText("Reset Password"); + fireEvent.click(resetButton); + }); + + expect(resetPassword).toHaveBeenCalledWith({ + email: "asdf@asdf.com", + password: "Test123!@", }); + }); - it('handles reset password success', async () => { - resetPassword.mockResolvedValueOnce({ data: { success: true } }); + it("handles reset password internal server error", async () => { + resetPassword.mockRejectedValueOnce({ + response: { + data: { error: "Internal Server Error" }, + }, + }); - render( - - - - - - ); + render( + + + + + + ); - await act(async () => { - fireEvent.change(screen.getByPlaceholderText('Create your password'), { target: { value: 'test123' } }); - fireEvent.change(screen.getByPlaceholderText('Confirm your password'), { target: { value: 'test123' } }); - fireEvent.click(screen.getByText('Reset Password')); - }) + await act(async () => { + const validPassword = "Test123!@"; - expect(resetPassword).toHaveBeenCalledWith({ email: 'asdf@asdf.com', password: 'test123' }); + fireEvent.change(screen.getByPlaceholderText("Create your password"), { + target: { value: validPassword }, + }); + fireEvent.change(screen.getByPlaceholderText("Confirm your password"), { + target: { value: validPassword }, + }); + + fireEvent.blur(screen.getByPlaceholderText("Create your password")); + fireEvent.blur(screen.getByPlaceholderText("Confirm your password")); + + fireEvent.click(screen.getByText("Reset Password")); + }); + await waitFor(() => { + expect(screen.getByText("Internal Server Error")).toBeTruthy(); }); - it('handles reset password internal server error', async () => { - resetPassword.mockRejectedValueOnce({ response: { data: { error: 'Internal Server Error' } } }); - - render( - - - - - - ); - await act(async () => { - fireEvent.change(screen.getByPlaceholderText('Create your password'), { target: { value: 'test123' } }); - fireEvent.change(screen.getByPlaceholderText('Confirm your password'), { target: { value: 'test123' } }); - fireEvent.click(screen.getByText('Reset Password')); - }) - - await waitFor(() => { - expect(screen.getByText('Internal Server Error')).to.exist; - }); - - expect(resetPassword).toHaveBeenCalledWith({ email: 'asdf@asdf.com', password: 'test123' }); + expect(resetPassword).toHaveBeenCalledWith({ + email: "asdf@asdf.com", + password: "Test123!@", }); + }); }); From 2b210b26abc20126daa14844f121d5776e7e665a Mon Sep 17 00:00:00 2001 From: erenfn Date: Sat, 16 Nov 2024 18:40:37 +0300 Subject: [PATCH 27/66] admin register routes --- backend/src/routes/team.routes.js | 2 +- docker-compose.yml | 46 +- frontend/package-lock.json | 4114 ++++------------- frontend/src/App.jsx | 20 +- .../src/scenes/login/CreateAccountPage.jsx | 100 +- frontend/src/scenes/login/LoginPage.jsx | 14 +- frontend/src/scenes/login/SetNewPassword.jsx | 1 + 7 files changed, 1118 insertions(+), 3179 deletions(-) diff --git a/backend/src/routes/team.routes.js b/backend/src/routes/team.routes.js index 7dbec25c..1cf82e20 100644 --- a/backend/src/routes/team.routes.js +++ b/backend/src/routes/team.routes.js @@ -20,7 +20,7 @@ const router = express.Router(); const teamPermissions = settings.team.permissions; router.get("/details", authenticateJWT, getTeamDetails); -router.get("/count", authenticateJWT, getTeamCount); +router.get("/count", getTeamCount); router.post("/set-organisation", authenticateJWT, accessGuard(teamPermissions.setOrg), setOrganisation); router.post("/invite", authenticateJWT, accessGuard(teamPermissions.invite), sendTeamInvite); diff --git a/docker-compose.yml b/docker-compose.yml index 0cf50674..bf2a2507 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,29 +57,29 @@ services: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data - frontend: - build: ./frontend - volumes: - - ./frontend:/app - - /app/node_modules - ports: - - "4173:4173" - develop: - watch: - - action: sync - path: ./frontend - target: /app - ignore: - - node_modules/ - environment: - - NODE_ENV=${NODE_ENV:-development} - command: > - bash -c " - if [ \"$NODE_ENV\" = \"development\" ]; then - npm run dev; - elif [ \"$NODE_ENV\" != \"development\" ]; then - npm run build && npm run preview; - fi" + # frontend: + # build: ./frontend + # volumes: + # - ./frontend:/app + # - /app/node_modules + # ports: + # - "4173:4173" + # develop: + # watch: + # - action: sync + # path: ./frontend + # target: /app + # ignore: + # - node_modules/ + # environment: + # - NODE_ENV=${NODE_ENV:-development} + # command: > + # bash -c " + # if [ \"$NODE_ENV\" = \"development\" ]; then + # npm run dev; + # elif [ \"$NODE_ENV\" != \"development\" ]; then + # npm run build && npm run preview; + # fi" mailhog: image: mailhog/mailhog ports: diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6cb1b1e7..98e2a948 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -59,8 +59,7 @@ }, "node_modules/@ampproject/remapping": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -71,8 +70,7 @@ }, "node_modules/@babel/code-frame": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", - "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "license": "MIT", "dependencies": { "@babel/highlight": "^7.25.7", "picocolors": "^1.0.0" @@ -83,16 +81,14 @@ }, "node_modules/@babel/compat-data": { "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", - "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", - "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.25.7", @@ -120,21 +116,18 @@ }, "node_modules/@babel/core/node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + "license": "MIT" }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", - "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", + "license": "MIT", "dependencies": { "@babel/types": "^7.25.7", "@jridgewell/gen-mapping": "^0.3.5", @@ -147,8 +140,7 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", - "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.25.7", "@babel/helper-validator-option": "^7.25.7", @@ -162,16 +154,14 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-module-imports": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", - "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.7", "@babel/types": "^7.25.7" @@ -182,8 +172,7 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", - "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.7", "@babel/helper-simple-access": "^7.25.7", @@ -199,8 +188,7 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", - "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", + "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.7", "@babel/types": "^7.25.7" @@ -211,32 +199,28 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", - "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", - "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", - "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", - "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", + "license": "MIT", "dependencies": { "@babel/template": "^7.25.7", "@babel/types": "^7.25.7" @@ -247,8 +231,7 @@ }, "node_modules/@babel/highlight": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", - "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", @@ -261,8 +244,7 @@ }, "node_modules/@babel/parser": { "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", - "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", + "license": "MIT", "dependencies": { "@babel/types": "^7.25.8" }, @@ -275,8 +257,7 @@ }, "node_modules/@babel/runtime": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", - "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -286,8 +267,7 @@ }, "node_modules/@babel/template": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", - "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.25.7", "@babel/parser": "^7.25.7", @@ -299,8 +279,7 @@ }, "node_modules/@babel/traverse": { "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", - "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.25.7", "@babel/generator": "^7.25.7", @@ -316,8 +295,7 @@ }, "node_modules/@babel/types": { "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", - "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", + "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.7", "@babel/helper-validator-identifier": "^7.25.7", @@ -329,28 +307,24 @@ }, "node_modules/@base2/pretty-print-object": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz", - "integrity": "sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/@bufbuild/protobuf": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.0.tgz", - "integrity": "sha512-+imAQkHf7U/Rwvu0wk1XWgsP3WnpCWmK7B48f0XqSNzgk64+grljTKC7pnO/xBiEMUziF7vKRfbBnOQhg126qQ==", - "devOptional": true + "devOptional": true, + "license": "(Apache-2.0 AND BSD-3-Clause)" }, "node_modules/@ctrl/tinycolor": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.1.0.tgz", - "integrity": "sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==", + "license": "MIT", "engines": { "node": ">=14" } }, "node_modules/@emotion/babel-plugin": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", - "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", @@ -367,8 +341,7 @@ }, "node_modules/@emotion/cache": { "version": "11.13.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", - "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0", "@emotion/sheet": "^1.4.0", @@ -379,26 +352,22 @@ }, "node_modules/@emotion/hash": { "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" + "license": "MIT" }, "node_modules/@emotion/is-prop-valid": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", - "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", "dependencies": { "@emotion/memoize": "^0.9.0" } }, "node_modules/@emotion/memoize": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + "license": "MIT" }, "node_modules/@emotion/react": { "version": "11.13.3", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", - "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.12.0", @@ -420,8 +389,7 @@ }, "node_modules/@emotion/serialize": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", - "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", + "license": "MIT", "dependencies": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", @@ -432,13 +400,11 @@ }, "node_modules/@emotion/sheet": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" + "license": "MIT" }, "node_modules/@emotion/styled": { "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", - "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.12.0", @@ -459,426 +425,30 @@ }, "node_modules/@emotion/unitless": { "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" + "license": "MIT" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", - "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "license": "MIT", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", - "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==" + "license": "MIT" }, "node_modules/@emotion/weak-memoize": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", - "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", - "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", - "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", - "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", - "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", - "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", - "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", - "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", - "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", - "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", - "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", - "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", - "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", - "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", - "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", - "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", - "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", - "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", - "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", - "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", - "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", - "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", - "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } + "license": "MIT" }, "node_modules/@esbuild/win32-x64": { "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", - "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -890,9 +460,8 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -905,18 +474,16 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -937,9 +504,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -952,9 +518,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -964,25 +529,22 @@ }, "node_modules/@eslint/js": { "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@floating-ui/core": { "version": "1.6.8", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", - "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.8" } }, "node_modules/@floating-ui/dom": { "version": "1.6.11", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", - "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", + "license": "MIT", "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.8" @@ -990,8 +552,7 @@ }, "node_modules/@floating-ui/react-dom": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", - "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -1002,15 +563,12 @@ }, "node_modules/@floating-ui/utils": { "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", - "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" + "license": "MIT" }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -1022,9 +580,8 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -1035,16 +592,13 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@jest/schemas": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -1054,9 +608,8 @@ }, "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.3.0.tgz", - "integrity": "sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==", "dev": true, + "license": "MIT", "dependencies": { "glob": "^7.2.0", "glob-promise": "^4.2.0", @@ -1075,9 +628,8 @@ }, "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/magic-string": { "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" }, @@ -1087,8 +639,7 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1100,25 +651,22 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -1126,13 +674,11 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1140,8 +686,7 @@ }, "node_modules/@mui/base": { "version": "5.0.0-beta.59", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.59.tgz", - "integrity": "sha512-LQZ2907rPMut/2Lq6qSnyP+nqOHLO3buMv91m7SdLpqp/lXU5+8vUXcf5oOwTNis6hfSvYGSQJ493Q00OzxDmQ==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@floating-ui/react-dom": "^2.1.1", @@ -1170,18 +715,16 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.4.tgz", - "integrity": "sha512-jCRsB9NDJJatVCHvwWSTfYUzuTQ7E0Km6tAQWz2Md1SLHIbVj5visC9yHbf/Cv2IDcG6XdHRv3e7Bt1rIburNw==", + "version": "6.1.5", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.4.tgz", - "integrity": "sha512-nhXBNSP3WkY0pz8dg25VIYIXJkhdRLRKZtD50f9OuHVQ1eh8b+enmvaZQF0o5M8cs1sR6wQHwZYwG34qDZeG0g==", + "version": "6.1.5", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7" }, @@ -1193,7 +736,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^6.1.4", + "@mui/material": "^6.1.5", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1205,8 +748,7 @@ }, "node_modules/@mui/lab": { "version": "6.0.0-beta.12", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.0-beta.12.tgz", - "integrity": "sha512-tcnCs2j3MsEjyvTSRWbFrlLqx65R1EQ+wh5RGRGscgwso+DVicF1eLGSgtTpJ5GhUvwXTgTNGxILSmZdobN+IA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/base": "5.0.0-beta.59", @@ -1248,15 +790,14 @@ } }, "node_modules/@mui/material": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.4.tgz", - "integrity": "sha512-mIVdjzDYU4U/XYzf8pPEz3zDZFS4Wbyr0cjfgeGiT/s60EvtEresXXQy8XUA0bpJDJjgic1Hl5AIRcqWDyi2eg==", + "version": "6.1.5", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", - "@mui/core-downloads-tracker": "^6.1.4", - "@mui/system": "^6.1.4", + "@mui/core-downloads-tracker": "^6.1.5", + "@mui/system": "^6.1.5", "@mui/types": "^7.2.18", - "@mui/utils": "^6.1.4", + "@mui/utils": "^6.1.5", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", @@ -1275,7 +816,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.1.4", + "@mui/material-pigment-css": "^6.1.5", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1296,12 +837,11 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.4.tgz", - "integrity": "sha512-FPa+W5BSrRM/1QI5Gf/GwJinJ2WsrKPpJB6xMmmXMXSUIp31YioIVT04i28DQUXFFB3yZY12ukcZi51iLvPljw==", + "version": "6.1.5", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", - "@mui/utils": "^6.1.4", + "@mui/utils": "^6.1.5", "prop-types": "^15.8.1" }, "engines": { @@ -1322,9 +862,8 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.4.tgz", - "integrity": "sha512-D+aiIDtJsU9OVJ7dgayhCDABJHT7jTlnz1FKyxa5mNVHsxjjeG1M4OpLsRQvx4dcvJfDywnU2cE+nFm4Ln2aFQ==", + "version": "6.1.5", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@emotion/cache": "^11.13.1", @@ -1355,15 +894,14 @@ } }, "node_modules/@mui/system": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.4.tgz", - "integrity": "sha512-lCveY/UtDhYwMg1WnLc3wEEuGymLi6YI79VOwFV9zfZT5Et+XEw/e1It26fiKwUZ+mB1+v1iTYMpJnwnsrn2aQ==", + "version": "6.1.5", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", - "@mui/private-theming": "^6.1.4", - "@mui/styled-engine": "^6.1.4", + "@mui/private-theming": "^6.1.5", + "@mui/styled-engine": "^6.1.5", "@mui/types": "^7.2.18", - "@mui/utils": "^6.1.4", + "@mui/utils": "^6.1.5", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1395,8 +933,7 @@ }, "node_modules/@mui/types": { "version": "7.2.18", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.18.tgz", - "integrity": "sha512-uvK9dWeyCJl/3ocVnTOS6nlji/Knj8/tVqVX03UVTpdmTJYu/s4jtDd9Kvv0nRGE0CUSNW1UYAci7PYypjealg==", + "license": "MIT", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1407,9 +944,8 @@ } }, "node_modules/@mui/utils": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.4.tgz", - "integrity": "sha512-v0wXkyh3/Hpw48ivlNvgs4ZT6M8BIEAMdLgvct59rQBggYFhoAVKyliKDzdj37CnIlYau3DYIn7x5bHlRYFBow==", + "version": "6.1.5", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/types": "^7.2.18", @@ -1436,13 +972,12 @@ } }, "node_modules/@mui/x-date-pickers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.20.0.tgz", - "integrity": "sha512-LnijrF8IF3r7c7sAVXRX4pDurozJSMUGAJdd5xuTT7ZPQIOp5ry0kDKqx79WAjXA/ZgjropLNt/nk15GE+6ZNw==", + "version": "7.21.0", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0", - "@mui/x-internals": "7.20.0", + "@mui/x-internals": "7.21.0", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -1501,15 +1036,14 @@ } }, "node_modules/@mui/x-date-pickers-pro": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers-pro/-/x-date-pickers-pro-7.20.0.tgz", - "integrity": "sha512-I9e5uubyQCgs/tu6Gb3iBv3DH1QWOtAIq7R3OxxobsGiqeGwFKNb/2INo8kOJ/vq/ikOtM2eXScVUDzdscm8Rg==", + "version": "7.21.0", + "license": "SEE LICENSE IN LICENSE", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0", - "@mui/x-date-pickers": "7.20.0", - "@mui/x-internals": "7.20.0", - "@mui/x-license": "7.20.0", + "@mui/x-date-pickers": "7.21.0", + "@mui/x-internals": "7.21.0", + "@mui/x-license": "7.21.0", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" @@ -1563,9 +1097,8 @@ } }, "node_modules/@mui/x-internals": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.20.0.tgz", - "integrity": "sha512-ScXdEwtnxmBEq9umeusnotfeVQnnhjOZcM2ddXyIupmzeGmgDDtEcXGyTgrS/GOc91J74g81s6eJ4UCrlYZ2sg==", + "version": "7.21.0", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0" @@ -1582,9 +1115,8 @@ } }, "node_modules/@mui/x-license": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@mui/x-license/-/x-license-7.20.0.tgz", - "integrity": "sha512-cJM40Ns+/Xny/+qCqdyvj8prDvEodSzbKceyirv1d3JcZXPrnI3ii62Ng1SARFdtiBBBnniw+1WOZDtDLJdW/g==", + "version": "7.21.0", + "license": "SEE LICENSE IN LICENSE", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/utils": "^5.16.6 || ^6.0.0" @@ -1598,9 +1130,8 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1610,257 +1141,70 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@remirror/core-constants": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", - "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==" - }, - "node_modules/@remix-run/router": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", - "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", - "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "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/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ] + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@popperjs/core": { + "version": "2.11.8", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "license": "MIT" }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ] + "node_modules/@remix-run/router": { + "version": "1.20.0", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ] + "node_modules/@rollup/pluginutils": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "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/@rollup/rollup-win32-x64-msvc": { "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -1868,17 +1212,15 @@ }, "node_modules/@sinclair/typebox": { "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 + "dev": true, + "license": "MIT" }, "node_modules/@storybook/builder-vite": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.3.5.tgz", - "integrity": "sha512-paGX8tEmAeAKFU5Cnwkq3RAi3LFCnmjAxMJikT09jUi6jDpNa0VzH8jbLxKdjsPMAsz0Wv3mrLvL2b8hyxLWAw==", + "version": "8.3.6", "dev": true, + "license": "MIT", "dependencies": { - "@storybook/csf-plugin": "8.3.5", + "@storybook/csf-plugin": "8.3.6", "@types/find-cache-dir": "^3.2.1", "browser-assert": "^1.2.1", "es-module-lexer": "^1.5.0", @@ -1894,7 +1236,7 @@ }, "peerDependencies": { "@preact/preset-vite": "*", - "storybook": "^8.3.5", + "storybook": "^8.3.6", "typescript": ">= 4.3.x", "vite": "^4.0.0 || ^5.0.0", "vite-plugin-glimmerx": "*" @@ -1912,23 +1254,21 @@ } }, "node_modules/@storybook/components": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.3.5.tgz", - "integrity": "sha512-Rq28YogakD3FO4F8KwAtGpo1g3t4V/gfCLqTQ8B6oQUFoxLqegkWk/DlwCzvoJndXuQJfdSyM6+r1JcA4Nql5A==", + "version": "8.3.6", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.3.5" + "storybook": "^8.3.6" } }, "node_modules/@storybook/core": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.3.5.tgz", - "integrity": "sha512-GOGfTvdioNa/n+Huwg4u/dsyYyBcM+gEcdxi3B7i5x4yJ3I912KoVshumQAOF2myKSRdI8h8aGWdx7nnjd0+5Q==", + "version": "8.3.6", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@storybook/csf": "^0.1.11", @@ -1952,9 +1292,8 @@ }, "node_modules/@storybook/core/node_modules/@storybook/csf": { "version": "0.1.11", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.11.tgz", - "integrity": "sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "type-fest": "^2.19.0" @@ -1962,18 +1301,16 @@ }, "node_modules/@storybook/csf": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", - "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.15" } }, "node_modules/@storybook/csf-plugin": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.3.5.tgz", - "integrity": "sha512-ODVqNXwJt90hG7QW8I9w/XUyOGlr0l7XltmIJgXwB/2cYDvaGu3JV5Ybg7O0fxPV8uXk7JlRuUD8ZYv5Low6pA==", + "version": "8.3.6", "dev": true, + "license": "MIT", "dependencies": { "unplugin": "^1.3.1" }, @@ -1982,53 +1319,49 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.3.5" + "storybook": "^8.3.6" } }, "node_modules/@storybook/global": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", - "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@storybook/manager-api": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.3.5.tgz", - "integrity": "sha512-fEQoKKi7h7pzh2z9RfuzatJxubrsfL/CB99fNXQ0wshMSY/7O4ckd18pK4fzG9ErnCtLAO9qsim4N/4eQC+/8Q==", + "version": "8.3.6", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.3.5" + "storybook": "^8.3.6" } }, "node_modules/@storybook/preview-api": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.3.5.tgz", - "integrity": "sha512-VPqpudE8pmjTLvdNJoW/2//nqElDgUOmIn3QxbbCmdZTHDg5tFtxuqwdlNfArF0TxvTSBDIulXt/Q6K56TAfTg==", + "version": "8.3.6", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.3.5" + "storybook": "^8.3.6" } }, "node_modules/@storybook/react": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.3.5.tgz", - "integrity": "sha512-kuBPe/wBin10SWr4EWPKxiTRGQ4RD2etGEVWVQLqVpOuJp/J2hVvXQHtCfZXU4TZT5x4PBbPRswbr58+XlF+kQ==", + "version": "8.3.6", "dev": true, + "license": "MIT", "dependencies": { - "@storybook/components": "^8.3.5", + "@storybook/components": "^8.3.6", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "^8.3.5", - "@storybook/preview-api": "^8.3.5", - "@storybook/react-dom-shim": "8.3.5", - "@storybook/theming": "^8.3.5", + "@storybook/manager-api": "^8.3.6", + "@storybook/preview-api": "^8.3.6", + "@storybook/react-dom-shim": "8.3.6", + "@storybook/theming": "^8.3.6", "@types/escodegen": "^0.0.6", "@types/estree": "^0.0.51", "@types/node": "^22.0.0", @@ -2052,10 +1385,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.3.5", + "@storybook/test": "8.3.6", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.3.5", + "storybook": "^8.3.6", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -2068,10 +1401,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.3.5.tgz", - "integrity": "sha512-Hf0UitJ/K0C7ajooooUK/PxOR4ihUWqsC7iCV1Gqth8U37dTeLMbaEO4PBwu0VQ+Ufg0N8BJLWfg7o6G4hrODw==", + "version": "8.3.6", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" @@ -2079,19 +1411,18 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.3.5" + "storybook": "^8.3.6" } }, "node_modules/@storybook/react-vite": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.3.5.tgz", - "integrity": "sha512-1pnN1JB7GrHUoTVn8VGkS240VNGhWkZBOMaaaRQnkgY1dCrFxAQv4YKFVuC250+rQzgp8X33J/pDAukgwzWYFQ==", + "version": "8.3.6", "dev": true, + "license": "MIT", "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "0.3.0", "@rollup/pluginutils": "^5.0.2", - "@storybook/builder-vite": "8.3.5", - "@storybook/react": "8.3.5", + "@storybook/builder-vite": "8.3.6", + "@storybook/react": "8.3.6", "find-up": "^5.0.0", "magic-string": "^0.30.0", "react-docgen": "^7.0.0", @@ -2108,33 +1439,30 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.3.5", + "storybook": "^8.3.6", "vite": "^4.0.0 || ^5.0.0" } }, "node_modules/@storybook/react/node_modules/@types/estree": { "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@storybook/theming": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.3.5.tgz", - "integrity": "sha512-9HmDDyC691oqfg4RziIM9ElsS2HITaxmH7n/yeUPtuirkPdAQzqOzhvH/Sa0qOhifzs8VjR+Gd/a/ZQ+S38r7w==", + "version": "8.3.6", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.3.5" + "storybook": "^8.3.6" } }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -2148,8 +1476,7 @@ }, "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -2163,8 +1490,7 @@ }, "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -2178,8 +1504,7 @@ }, "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -2193,8 +1518,7 @@ }, "node_modules/@svgr/babel-plugin-svg-dynamic-title": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -2208,8 +1532,7 @@ }, "node_modules/@svgr/babel-plugin-svg-em-dimensions": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -2223,8 +1546,7 @@ }, "node_modules/@svgr/babel-plugin-transform-react-native-svg": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -2238,8 +1560,7 @@ }, "node_modules/@svgr/babel-plugin-transform-svg-component": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -2253,8 +1574,7 @@ }, "node_modules/@svgr/babel-preset": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "license": "MIT", "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", @@ -2278,8 +1598,7 @@ }, "node_modules/@svgr/core": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -2297,8 +1616,7 @@ }, "node_modules/@svgr/core/node_modules/cosmiconfig": { "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "license": "MIT", "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", @@ -2322,8 +1640,7 @@ }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "license": "MIT", "dependencies": { "@babel/types": "^7.21.3", "entities": "^4.4.0" @@ -2338,8 +1655,7 @@ }, "node_modules/@svgr/plugin-jsx": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -2359,9 +1675,8 @@ }, "node_modules/@swc/core": { "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.36.tgz", - "integrity": "sha512-bu7ymMX+LCJOSSrKank25Jaq66ymLVA9fOUuy4ck3/6rbXdLw+pIJPnIDKQ9uNcxww8KDxOuJk9Ui9pqR+aGFw==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.13" @@ -2394,148 +1709,12 @@ } } }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.36.tgz", - "integrity": "sha512-8vDczXzCgv3ceTPhEivlpGprN44YlrCK1nbfU9g2TrhV/Aiqi09W/eM5zLesdoM1Z3mJl492gc/8nlTkpDdusw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.36.tgz", - "integrity": "sha512-Pa2Gao7+Wf5m3SsK4abKRtd48AtoUnJInvaC3d077swBfgZjbjUbQvcpdc2dOeQtWwo49rFqUZJonMsL0jnPgQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.36.tgz", - "integrity": "sha512-3YsMWd7V+WZEjbfBnLkkz/olcRBa8nyoK0iIOnNARJBMcYaJxjkJSMZpmSojCnIVwvjA1N83CPAbUL+W+fCnHg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.36.tgz", - "integrity": "sha512-lqM3aBB7kJazJYOwHeA5OGNLqXoQPZ/76b3dV+XcjN1GhD0CcXz6mW5PRYVin6OSN1eKrKBKJjtDA1mqADDEvw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.36.tgz", - "integrity": "sha512-bqei2YDzvUfG0pth5W2xJaj0eG4XWYk0d/NJ75vBX6bkIzK6dC8iuKQ41jOfUWonnrAs7rTDDJW0sTn/evvRdw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.36.tgz", - "integrity": "sha512-03maXTUyaBjeCxlDltmdzHje1ryQt1C4OWmmNgSSRXjLb+GNnAenwOJMSrcvHP/aNClD2pwsFCnYKDGy+sYE6w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.36.tgz", - "integrity": "sha512-XXysqLkvjtQnXm1zHqLhy00UYPv/gk5OtwR732X+piNisnEbcJBqI8Qp9O7YvLWllRcoP8IMBGDWLGdGLSpViA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.36.tgz", - "integrity": "sha512-k7+dmb13a/zPw+E4XYfPmLZFWJgcOcBRKIjYl9nQErtYsgsg3Ji6TBbsvJVETy23lNHyewZ17V5Vq6NzaG0hzg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.36.tgz", - "integrity": "sha512-ridD3ay6YM2PEYHZXXFN+edYEv0FOynaqOBP+NSnGNHA35azItIjoIe+KNi4WltGtAjpKCHSpjGCNfna12wdYQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/core-win32-x64-msvc": { "version": "1.7.36", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.36.tgz", - "integrity": "sha512-j1z2Z1Ln9d0E3dHsPkC1K9XDh0ojhRPwV+GfRTu4D61PE+aYhYLvbJC6xPvL4/204QrStRS7eDu3m+BcDp3rgQ==", "cpu": [ "x64" ], + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -2546,22 +1725,19 @@ }, "node_modules/@swc/counter": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" + "license": "Apache-2.0" }, "node_modules/@swc/types": { "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.13.tgz", - "integrity": "sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==", + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" } }, "node_modules/@testing-library/dom": { "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", - "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -2578,9 +1754,8 @@ }, "node_modules/@testing-library/dom/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" }, @@ -2593,9 +1768,8 @@ }, "node_modules/@testing-library/dom/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2609,9 +1783,8 @@ }, "node_modules/@testing-library/dom/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2621,24 +1794,21 @@ }, "node_modules/@testing-library/dom/node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@testing-library/dom/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@testing-library/dom/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -2648,9 +1818,8 @@ }, "node_modules/@testing-library/react": { "version": "15.0.7", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-15.0.7.tgz", - "integrity": "sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^10.0.0", @@ -2672,8 +1841,7 @@ }, "node_modules/@tiptap/core": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.8.0.tgz", - "integrity": "sha512-xsqDI4BNzYRWRtBq7+/38ThhqEr7uG9Njip1x+9/wgR3vWPBFnBkYJTz6jSxS35NRE6BSnERm4/B/vrLuY1Hdw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2684,8 +1852,7 @@ }, "node_modules/@tiptap/extension-blockquote": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.8.0.tgz", - "integrity": "sha512-m3CKrOIvV7fY1Ak2gYf5LkKiz6AHxHpg6wxfVaJvdBqXgLyVtHo552N+A4oSHOSRbB4AG9EBQ2NeBM8cdEQ4MA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2696,8 +1863,7 @@ }, "node_modules/@tiptap/extension-bold": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.8.0.tgz", - "integrity": "sha512-U1YkZBxDkSLNvPNiqxB5g42IeJHr27C7zDb/yGQN2xL4UBeg4O9xVhCFfe32f6tLwivSL0dar4ScElpaCJuqow==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2708,8 +1874,7 @@ }, "node_modules/@tiptap/extension-bubble-menu": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.8.0.tgz", - "integrity": "sha512-swg+myJPN60LduQvLMF4hVBqP5LOIN01INZBzBI8egz8QufqtSyRCgXl7Xcma0RT5xIXnZSG9XOqNFf2rtkjKA==", + "license": "MIT", "dependencies": { "tippy.js": "^6.3.7" }, @@ -2724,8 +1889,7 @@ }, "node_modules/@tiptap/extension-bullet-list": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.8.0.tgz", - "integrity": "sha512-H4O2X0ozbc/ce9/XF1H98sqWVUdtt7jzy7hMBunwmY8ZxI4dHtcRkeg81CZbpKTqOqRrMCLWjE3M2tgiDXrDkA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2738,8 +1902,7 @@ }, "node_modules/@tiptap/extension-code": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.8.0.tgz", - "integrity": "sha512-VSFn3sFF6qPpOGkXFhik8oYRH5iByVJpFEFd/duIEftmS0MdPzkbSItOpN3mc9xsJ5dCX80LYaResSj5hr5zkA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2750,8 +1913,7 @@ }, "node_modules/@tiptap/extension-code-block": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.8.0.tgz", - "integrity": "sha512-POuA5Igx+Dto0DTazoBFAQTj/M/FCdkqRVD9Uhsxhv49swPyANTJRr05vgbgtHB+NDDsZfCawVh7pI0IAD/O0w==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2763,8 +1925,7 @@ }, "node_modules/@tiptap/extension-document": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.8.0.tgz", - "integrity": "sha512-mp7Isx1sVc/ifeW4uW/PexGQ9exN3NRUOebSpnLfqXeWYk4y1RS1PA/3+IHkOPVetbnapgPjFx/DswlCP3XLjA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2775,8 +1936,7 @@ }, "node_modules/@tiptap/extension-dropcursor": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.8.0.tgz", - "integrity": "sha512-rAFvx44YuT6dtS1c+ALw0ROAGI16l5L1HxquL4hR1gtxDcTieST5xhw5bkshXlmrlfotZXPrhokzqA7qjhZtJw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2788,8 +1948,7 @@ }, "node_modules/@tiptap/extension-floating-menu": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.8.0.tgz", - "integrity": "sha512-H4QT61CrkLqisnGGC7zgiYmsl2jXPHl89yQCbdlkQN7aw11H7PltcJS2PJguL0OrRVJS/Mv/VTTUiMslmsEV5g==", + "license": "MIT", "dependencies": { "tippy.js": "^6.3.7" }, @@ -2804,8 +1963,7 @@ }, "node_modules/@tiptap/extension-gapcursor": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.8.0.tgz", - "integrity": "sha512-Be1LWCmvteQInOnNVN+HTqc1XWsj1bCl+Q7et8qqNjtGtTaCbdCp8ppcH1SKJxNTM/RLUtPyJ8FDgOTj51ixCA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2817,8 +1975,7 @@ }, "node_modules/@tiptap/extension-hard-break": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.8.0.tgz", - "integrity": "sha512-vqiIfviNiCmy/pJTHuDSCAGL2O4QDEdDmAvGJu8oRmElUrnlg8DbJUfKvn6DWQHNSQwRb+LDrwWlzAYj1K9u6A==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2829,8 +1986,7 @@ }, "node_modules/@tiptap/extension-heading": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.8.0.tgz", - "integrity": "sha512-4inWgrTPiqlivPmEHFOM5ck2UsmOsbKKPtqga6bALvWPmCv24S6/EBwFp8Jz4YABabXDnkviihmGu0LpP9D69w==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2841,8 +1997,7 @@ }, "node_modules/@tiptap/extension-history": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.8.0.tgz", - "integrity": "sha512-u5YS0J5Egsxt8TUWMMAC3QhPZaak+IzQeyHch4gtqxftx96tprItY7AD/A3pGDF2uCSnN+SZrk6yVexm6EncDw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2854,8 +2009,7 @@ }, "node_modules/@tiptap/extension-horizontal-rule": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.8.0.tgz", - "integrity": "sha512-Sn/MI8WVFBoIYSIHA9NJryJIyCEzZdRysau8pC5TFnfifre0QV1ksPz2bgF+DyCD69ozQiRdBBHDEwKe47ZbfQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2867,8 +2021,7 @@ }, "node_modules/@tiptap/extension-italic": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.8.0.tgz", - "integrity": "sha512-PwwSE2LTYiHI47NJnsfhBmPiLE8IXZYqaSoNPU6flPrk1KxEzqvRI1joKZBmD9wuqzmHJ93VFIeZcC+kfwi8ZA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2879,8 +2032,7 @@ }, "node_modules/@tiptap/extension-link": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.8.0.tgz", - "integrity": "sha512-p67hCG/pYCiOK/oCTPZnlkw9Ei7KJ7kCKFaluTcAmr5j8IBdYfDqSMDNCT4vGXBvKFh4X6xD7S7QvOqcH0Gn9A==", + "license": "MIT", "dependencies": { "linkifyjs": "^4.1.0" }, @@ -2895,8 +2047,7 @@ }, "node_modules/@tiptap/extension-list-item": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.8.0.tgz", - "integrity": "sha512-o7OGymGxB0B9x3x2prp3KBDYFuBYGc5sW69O672jk8G52DqhzzndgPnkk0qUn8nXAUKuDGbJmpmHVA2kagqnRg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2907,8 +2058,7 @@ }, "node_modules/@tiptap/extension-ordered-list": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.8.0.tgz", - "integrity": "sha512-sCvNbcTS1+5QTTXwUPFa10vf5I1pr8sGcOTIh0G+a5ZkS5+6FxT12k7VLzPt39QyNbOi+77U2o4Xr4XyaEkfSg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2921,8 +2071,7 @@ }, "node_modules/@tiptap/extension-paragraph": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.8.0.tgz", - "integrity": "sha512-XgxxNNbuBF48rAGwv7/s6as92/xjm/lTZIGTq9aG13ClUKFtgdel7C33SpUCcxg3cO2WkEyllXVyKUiauFZw/A==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2933,8 +2082,7 @@ }, "node_modules/@tiptap/extension-strike": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.8.0.tgz", - "integrity": "sha512-ezkDiXxQ3ME/dDMMM7tAMkKRi6UWw7tIu+Mx7Os0z8HCGpVBk1gFhLlhEd8I5rJaPZr4tK1wtSehMA9bscFGQw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2945,8 +2093,7 @@ }, "node_modules/@tiptap/extension-text": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.8.0.tgz", - "integrity": "sha512-EDAdFFzWOvQfVy7j3qkKhBpOeE5thkJaBemSWfXI93/gMVc0ZCdLi24mDvNNgUHlT+RjlIoQq908jZaaxLKN2A==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2957,8 +2104,7 @@ }, "node_modules/@tiptap/extension-text-style": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.8.0.tgz", - "integrity": "sha512-jJp0vcZ2Ty7RvIL0VU6dm1y+fTfXq1lN2GwtYzYM0ueFuESa+Qo8ticYOImyWZ3wGJGVrjn7OV9r0ReW0/NYkQ==", + "license": "MIT", "peer": true, "funding": { "type": "github", @@ -2970,8 +2116,7 @@ }, "node_modules/@tiptap/pm": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.8.0.tgz", - "integrity": "sha512-eMGpRooUMvKz/vOpnKKppApMSoNM325HxTdAJvTlVAmuHp5bOY5kyY1kfUlePRiVx1t1UlFcXs3kecFwkkBD3Q==", + "license": "MIT", "dependencies": { "prosemirror-changeset": "^2.2.1", "prosemirror-collab": "^1.3.1", @@ -2999,8 +2144,7 @@ }, "node_modules/@tiptap/react": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.8.0.tgz", - "integrity": "sha512-o/aSCjO5Nu4MsNpTF+N1SzYzVQvvBiclmTOZX2E6usZ8jre5zmKfXHDSZnjGSRTK6z6kw5KW8wpjRQha03f9mg==", + "license": "MIT", "dependencies": { "@tiptap/extension-bubble-menu": "^2.8.0", "@tiptap/extension-floating-menu": "^2.8.0", @@ -3021,8 +2165,7 @@ }, "node_modules/@tiptap/starter-kit": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.8.0.tgz", - "integrity": "sha512-r7UwaTrECkQoheWVZKFDqtL5tBx07x7IFT+prfgnsVlYFutGWskVVqzCDvD3BDmrg5PzeCWYZrQGlPaLib7tjg==", + "license": "MIT", "dependencies": { "@tiptap/core": "^2.8.0", "@tiptap/extension-blockquote": "^2.8.0", @@ -3052,15 +2195,13 @@ }, "node_modules/@types/aria-query": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -3071,18 +2212,16 @@ }, "node_modules/@types/babel__generator": { "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" @@ -3090,18 +2229,16 @@ }, "node_modules/@types/babel__traverse": { "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/connect": "*", @@ -3110,9 +2247,8 @@ }, "node_modules/@types/connect": { "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/node": "*" @@ -3120,26 +2256,22 @@ }, "node_modules/@types/doctrine": { "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", - "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/escodegen": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.6.tgz", - "integrity": "sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + "license": "MIT" }, "node_modules/@types/express": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/body-parser": "*", @@ -3150,9 +2282,8 @@ }, "node_modules/@types/express-serve-static-core": { "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/node": "*", @@ -3163,15 +2294,13 @@ }, "node_modules/@types/find-cache-dir": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/find-cache-dir/-/find-cache-dir-3.2.1.tgz", - "integrity": "sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/glob": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, + "license": "MIT", "dependencies": { "@types/minimatch": "*", "@types/node": "*" @@ -3181,6 +2310,7 @@ "version": "3.3.5", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "license": "MIT", "dependencies": { "@types/react": "*", "hoist-non-react-statics": "^3.3.0" @@ -3188,26 +2318,22 @@ }, "node_modules/@types/http-errors": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@types/json-schema": { "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/linkify-it": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==" + "license": "MIT" }, "node_modules/@types/markdown-it": { "version": "14.1.2", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", - "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -3215,59 +2341,50 @@ }, "node_modules/@types/mdurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==" + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@types/minimatch": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "22.7.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.6.tgz", - "integrity": "sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw==", "devOptional": true, + "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } }, "node_modules/@types/parse-json": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + "license": "MIT" }, "node_modules/@types/prop-types": { "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" + "license": "MIT" }, "node_modules/@types/qs": { "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@types/range-parser": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@types/react": { "version": "18.3.11", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", - "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", + "license": "MIT", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -3275,38 +2392,33 @@ }, "node_modules/@types/react-dom": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/react": "*" } }, "node_modules/@types/react-transition-group": { "version": "4.4.11", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", - "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", + "license": "MIT", "dependencies": { "@types/react": "*" } }, "node_modules/@types/resolve": { "version": "1.20.6", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", - "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/semver": { "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/send": { "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/mime": "^1", @@ -3315,9 +2427,8 @@ }, "node_modules/@types/serve-static": { "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/http-errors": "*", @@ -3327,14 +2438,12 @@ }, "node_modules/@types/use-sync-external-store": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", - "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==" + "license": "MIT" }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0" @@ -3349,9 +2458,8 @@ }, "node_modules/@typescript-eslint/types": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -3362,9 +2470,8 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0", @@ -3389,9 +2496,8 @@ }, "node_modules/@typescript-eslint/utils": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", @@ -3415,9 +2521,8 @@ }, "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -3428,18 +2533,16 @@ }, "node_modules/@typescript-eslint/utils/node_modules/estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/@typescript-eslint/visitor-keys": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" @@ -3454,14 +2557,12 @@ }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.1.tgz", - "integrity": "sha512-vgWOY0i1EROUK0Ctg1hwhtC3SdcDjZcdit4Ups4aPkDcB1jYhmo+RMYWY87cmXMhvtD5uf8lV89j2w16vkdSVg==", + "license": "MIT", "dependencies": { "@swc/core": "^1.7.26" }, @@ -3471,9 +2572,8 @@ }, "node_modules/@vitest/expect": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", "dev": true, + "license": "MIT", "dependencies": { "@vitest/spy": "1.6.0", "@vitest/utils": "1.6.0", @@ -3485,9 +2585,8 @@ }, "node_modules/@vitest/runner": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", - "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", "dev": true, + "license": "MIT", "dependencies": { "@vitest/utils": "1.6.0", "p-limit": "^5.0.0", @@ -3499,9 +2598,8 @@ }, "node_modules/@vitest/runner/node_modules/p-limit": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^1.0.0" }, @@ -3514,9 +2612,8 @@ }, "node_modules/@vitest/runner/node_modules/yocto-queue": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.20" }, @@ -3526,9 +2623,8 @@ }, "node_modules/@vitest/snapshot": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", - "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", "dev": true, + "license": "MIT", "dependencies": { "magic-string": "^0.30.5", "pathe": "^1.1.1", @@ -3540,9 +2636,8 @@ }, "node_modules/@vitest/snapshot/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" }, @@ -3552,9 +2647,8 @@ }, "node_modules/@vitest/snapshot/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -3566,9 +2660,8 @@ }, "node_modules/@vitest/spy": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", "dev": true, + "license": "MIT", "dependencies": { "tinyspy": "^2.2.0" }, @@ -3578,9 +2671,8 @@ }, "node_modules/@vitest/utils": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", "dev": true, + "license": "MIT", "dependencies": { "diff-sequences": "^29.6.3", "estree-walker": "^3.0.3", @@ -3593,9 +2685,8 @@ }, "node_modules/@vitest/utils/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" }, @@ -3605,18 +2696,16 @@ }, "node_modules/@vitest/utils/node_modules/estree-walker": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } }, "node_modules/@vitest/utils/node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -3628,9 +2717,8 @@ }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -3638,27 +2726,23 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -3667,15 +2751,13 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -3685,33 +2767,29 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -3725,9 +2803,8 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -3738,9 +2815,8 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -3750,9 +2826,8 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", @@ -3764,9 +2839,8 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" @@ -3774,21 +2848,18 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/accepts": { "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", "negotiator": "0.6.3" @@ -3799,9 +2870,8 @@ }, "node_modules/acorn": { "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3811,27 +2881,24 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -3841,9 +2908,8 @@ }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3857,26 +2923,23 @@ }, "node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -3886,23 +2949,20 @@ }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "license": "Python-2.0" }, "node_modules/aria-query": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, + "license": "Apache-2.0", "dependencies": { "dequal": "^2.0.3" } }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -3916,15 +2976,13 @@ }, "node_modules/array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/array-includes": { "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -3942,18 +3000,16 @@ }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/array.prototype.findlast": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -3971,9 +3027,8 @@ }, "node_modules/array.prototype.flat": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -3989,9 +3044,8 @@ }, "node_modules/array.prototype.flatmap": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -4007,9 +3061,8 @@ }, "node_modules/array.prototype.tosorted": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -4023,9 +3076,8 @@ }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -4045,18 +3097,16 @@ }, "node_modules/assertion-error": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/ast-types": { "version": "0.16.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", - "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "tslib": "^2.0.1" @@ -4067,22 +3117,19 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "license": "MIT" }, "node_modules/attr-accept": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.4.tgz", - "integrity": "sha512-2pA6xFIbdTUDCAwjN8nQwI+842VwzbDUXO2IYlpPXQIORgKnavorcr4Ce3rwh+zsNg9zK7QPsdvDj3Lum4WX4w==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/available-typed-arrays": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -4095,8 +3142,7 @@ }, "node_modules/axios": { "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -4105,8 +3151,7 @@ }, "node_modules/babel-plugin-macros": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -4119,15 +3164,13 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/better-opn": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", - "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "open": "^8.0.4" @@ -4138,9 +3181,8 @@ }, "node_modules/body-parser": { "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -4162,24 +3204,21 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4187,9 +3226,8 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -4199,14 +3237,10 @@ }, "node_modules/browser-assert": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz", - "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==", "dev": true }, "node_modules/browserslist": { "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "funding": [ { "type": "opencollective", @@ -4221,6 +3255,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001663", "electron-to-chromium": "^1.5.28", @@ -4236,39 +3271,34 @@ }, "node_modules/buffer-builder": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", - "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", - "devOptional": true + "devOptional": true, + "license": "MIT/X11" }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/cac": { "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/call-bind": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -4285,16 +3315,14 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -4304,8 +3332,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001669", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", - "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", "funding": [ { "type": "opencollective", @@ -4319,13 +3345,13 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chai": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, + "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -4341,8 +3367,7 @@ }, "node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -4354,17 +3379,15 @@ }, "node_modules/chalk/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/check-error": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" }, @@ -4374,49 +3397,42 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/classnames": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + "license": "MIT" }, "node_modules/clsx": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "license": "MIT" }, "node_modules/colorjs.io": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", - "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4426,33 +3442,28 @@ }, "node_modules/commander": { "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==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/commondir": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/confbox": { "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/content-disposition": { "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" }, @@ -4462,37 +3473,32 @@ }, "node_modules/content-type": { "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" } }, "node_modules/convert-source-map": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "license": "MIT" }, "node_modules/cookie": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cosmiconfig": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -4506,14 +3512,12 @@ }, "node_modules/crelt": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", - "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4525,9 +3529,8 @@ }, "node_modules/cssstyle": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", - "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "dev": true, + "license": "MIT", "dependencies": { "rrweb-cssom": "^0.7.1" }, @@ -4537,14 +3540,12 @@ }, "node_modules/csstype": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "license": "MIT" }, "node_modules/data-urls": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0" @@ -4555,9 +3556,8 @@ }, "node_modules/data-view-buffer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -4572,9 +3572,8 @@ }, "node_modules/data-view-byte-length": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -4589,9 +3588,8 @@ }, "node_modules/data-view-byte-offset": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -4606,8 +3604,7 @@ }, "node_modules/date-fns": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", - "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/kossnocorp" @@ -4615,8 +3612,7 @@ }, "node_modules/debug": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -4631,15 +3627,13 @@ }, "node_modules/decimal.js": { "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deep-eql": { "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, + "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, @@ -4649,23 +3643,22 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -4680,9 +3673,8 @@ }, "node_modules/define-lazy-prop": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=8" @@ -4690,9 +3682,8 @@ }, "node_modules/define-properties": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -4707,35 +3698,31 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "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" } }, "node_modules/dequal": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/destroy": { "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", "npm": "1.2.8000 || >= 1.4.16" @@ -4743,18 +3730,16 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -4764,9 +3749,8 @@ }, "node_modules/doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -4776,14 +3760,12 @@ }, "node_modules/dom-accessibility-api": { "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/dom-helpers": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" @@ -4791,13 +3773,11 @@ }, "node_modules/dompurify": { "version": "3.1.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz", - "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==" + "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/dot-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -4805,29 +3785,25 @@ }, "node_modules/ee-first": { "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 + "dev": true, + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.40", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.40.tgz", - "integrity": "sha512-LYm78o6if4zTasnYclgQzxEcgMoIcybWOhkATWepN95uwVVWV0/IW10v+2sIeHE+bIYWipLneTftVyQm45UY7g==" + "version": "1.5.41", + "license": "ISC" }, "node_modules/encodeurl": { "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" } }, "node_modules/enhanced-resolve": { "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -4838,8 +3814,7 @@ }, "node_modules/entities": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -4849,17 +3824,15 @@ }, "node_modules/error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-abstract": { "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -4917,9 +3890,8 @@ }, "node_modules/es-define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -4929,18 +3901,16 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-iterator-helpers": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", - "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -4963,15 +3933,13 @@ }, "node_modules/es-module-lexer": { "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -4981,9 +3949,8 @@ }, "node_modules/es-set-tostringtag": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -4995,18 +3962,16 @@ }, "node_modules/es-shim-unscopables": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -5021,10 +3986,9 @@ }, "node_modules/esbuild": { "version": "0.23.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", - "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "peer": true, "bin": { "esbuild": "bin/esbuild" @@ -5061,9 +4025,8 @@ }, "node_modules/esbuild-register": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", - "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "debug": "^4.3.4" @@ -5074,22 +4037,19 @@ }, "node_modules/escalade": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "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 + "dev": true, + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -5099,9 +4059,8 @@ }, "node_modules/escodegen": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -5120,9 +4079,8 @@ }, "node_modules/escodegen/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -5130,10 +4088,8 @@ }, "node_modules/eslint": { "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5186,9 +4142,8 @@ }, "node_modules/eslint-plugin-react": { "version": "7.37.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.1.tgz", - "integrity": "sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", @@ -5218,9 +4173,8 @@ }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5230,9 +4184,8 @@ }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -5242,9 +4195,8 @@ }, "node_modules/eslint-plugin-react/node_modules/resolve": { "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": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -5259,18 +4211,16 @@ }, "node_modules/eslint-plugin-react/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/eslint-plugin-storybook": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.8.0.tgz", - "integrity": "sha512-CZeVO5EzmPY7qghO2t64oaFM+8FTaD4uzOEjHKp516exyTKo+skKAL9GI3QALS2BXhyALJjNtwbmr1XinGE8bA==", "dev": true, + "license": "MIT", "dependencies": { "@storybook/csf": "^0.0.1", "@typescript-eslint/utils": "^5.62.0", @@ -5286,9 +4236,8 @@ }, "node_modules/eslint-scope": { "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -5302,9 +4251,8 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5314,9 +4262,8 @@ }, "node_modules/eslint/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" }, @@ -5329,9 +4276,8 @@ }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5345,9 +4291,8 @@ }, "node_modules/eslint/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -5357,15 +4302,13 @@ }, "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/eslint/node_modules/globals": { "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -5378,18 +4321,16 @@ }, "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5399,9 +4340,8 @@ }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -5411,9 +4351,8 @@ }, "node_modules/espree": { "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -5428,9 +4367,8 @@ }, "node_modules/espree/node_modules/acorn": { "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5440,9 +4378,8 @@ }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -5453,9 +4390,8 @@ }, "node_modules/esquery": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -5465,9 +4401,8 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -5477,50 +4412,44 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estree-walker": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/execa": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -5541,9 +4470,8 @@ }, "node_modules/express": { "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -5583,29 +4511,25 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5619,9 +4543,8 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -5631,30 +4554,26 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastq": { "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -5664,8 +4583,7 @@ }, "node_modules/file-selector": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", - "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", + "license": "MIT", "dependencies": { "tslib": "^2.4.0" }, @@ -5675,9 +4593,8 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5687,9 +4604,8 @@ }, "node_modules/finalhandler": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", @@ -5705,24 +4621,21 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/find-cache-dir": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, + "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -5737,14 +4650,12 @@ }, "node_modules/find-root": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + "license": "MIT" }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -5758,9 +4669,8 @@ }, "node_modules/flat-cache": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -5772,20 +4682,18 @@ }, "node_modules/flatted": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -5797,17 +4705,15 @@ }, "node_modules/for-each": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/form-data": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5827,6 +4733,7 @@ "url": "https://opencollective.com/formik" } ], + "license": "Apache-2.0", "dependencies": { "@types/hoist-non-react-statics": "^3.3.1", "deepmerge": "^2.1.1", @@ -5843,27 +4750,24 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "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" } }, "node_modules/fs-extra": { "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5875,36 +4779,20 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "dev": true, + "license": "ISC" }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function.prototype.name": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -5920,35 +4808,31 @@ }, "node_modules/functions-have-names": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/get-func-name": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/get-intrinsic": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -5965,9 +4849,8 @@ }, "node_modules/get-stream": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -5977,9 +4860,8 @@ }, "node_modules/get-symbol-description": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -5994,10 +4876,8 @@ }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6015,9 +4895,8 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -6027,9 +4906,8 @@ }, "node_modules/glob-promise": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", - "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", "dev": true, + "license": "MIT", "dependencies": { "@types/glob": "^7.1.3" }, @@ -6046,23 +4924,20 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/globals": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globalthis": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -6076,9 +4951,8 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -6096,9 +4970,8 @@ }, "node_modules/gopd": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -6108,38 +4981,33 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has-bigints": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -6149,9 +5017,8 @@ }, "node_modules/has-proto": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6161,9 +5028,8 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6173,9 +5039,8 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -6188,8 +5053,7 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -6199,22 +5063,19 @@ }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" } }, "node_modules/hoist-non-react-statics/node_modules/react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "license": "MIT" }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-encoding": "^3.1.1" }, @@ -6224,9 +5085,8 @@ }, "node_modules/html-tags": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -6236,9 +5096,8 @@ }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -6252,9 +5111,8 @@ }, "node_modules/http-proxy-agent": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -6265,9 +5123,8 @@ }, "node_modules/https-proxy-agent": { "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -6278,18 +5135,16 @@ }, "node_modules/human-signals": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } }, "node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -6299,23 +5154,20 @@ }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immutable": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6329,19 +5181,16 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6349,15 +5198,13 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/internal-slot": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -6369,18 +5216,16 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/is-arguments": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "call-bind": "^1.0.2", @@ -6395,9 +5240,8 @@ }, "node_modules/is-array-buffer": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -6411,14 +5255,12 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "license": "MIT" }, "node_modules/is-async-function": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6431,9 +5273,8 @@ }, "node_modules/is-bigint": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -6443,9 +5284,8 @@ }, "node_modules/is-boolean-object": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6459,9 +5299,8 @@ }, "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6471,8 +5310,7 @@ }, "node_modules/is-core-module": { "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", "dependencies": { "hasown": "^2.0.2" }, @@ -6485,9 +5323,8 @@ }, "node_modules/is-data-view": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, + "license": "MIT", "dependencies": { "is-typed-array": "^1.1.13" }, @@ -6500,9 +5337,8 @@ }, "node_modules/is-date-object": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6515,9 +5351,8 @@ }, "node_modules/is-docker": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, + "license": "MIT", "peer": true, "bin": { "is-docker": "cli.js" @@ -6531,18 +5366,16 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-finalizationregistry": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6552,9 +5385,8 @@ }, "node_modules/is-generator-function": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6567,9 +5399,8 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -6579,9 +5410,8 @@ }, "node_modules/is-map": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6591,9 +5421,8 @@ }, "node_modules/is-negative-zero": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6603,18 +5432,16 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-number-object": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6627,33 +5454,29 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-object": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-regex": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6667,9 +5490,8 @@ }, "node_modules/is-set": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6679,9 +5501,8 @@ }, "node_modules/is-shared-array-buffer": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7" }, @@ -6694,9 +5515,8 @@ }, "node_modules/is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -6706,9 +5526,8 @@ }, "node_modules/is-string": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6721,9 +5540,8 @@ }, "node_modules/is-symbol": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -6736,9 +5554,8 @@ }, "node_modules/is-typed-array": { "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, + "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" }, @@ -6751,9 +5568,8 @@ }, "node_modules/is-weakmap": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6763,9 +5579,8 @@ }, "node_modules/is-weakref": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6775,9 +5590,8 @@ }, "node_modules/is-weakset": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4" @@ -6791,9 +5605,8 @@ }, "node_modules/is-wsl": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "is-docker": "^2.0.0" @@ -6804,21 +5617,18 @@ }, "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/iterator.prototype": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", - "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "get-intrinsic": "^1.2.1", @@ -6832,9 +5642,8 @@ }, "node_modules/jest-worker": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -6846,18 +5655,16 @@ }, "node_modules/jest-worker/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -6870,21 +5677,18 @@ }, "node_modules/js-cookie": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "license": "MIT", "engines": { "node": ">=14" } }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -6894,9 +5698,8 @@ }, "node_modules/jsdoc-type-pratt-parser": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", - "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=12.0.0" @@ -6904,9 +5707,8 @@ }, "node_modules/jsdom": { "version": "24.1.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.3.tgz", - "integrity": "sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==", "dev": true, + "license": "MIT", "dependencies": { "cssstyle": "^4.0.1", "data-urls": "^5.0.0", @@ -6944,8 +5746,7 @@ }, "node_modules/jsesc": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -6955,31 +5756,26 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -6989,9 +5785,8 @@ }, "node_modules/jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -7001,9 +5796,8 @@ }, "node_modules/jsx-ast-utils": { "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", @@ -7016,18 +5810,16 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -7038,36 +5830,31 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "license": "MIT" }, "node_modules/linkify-it": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", "dependencies": { "uc.micro": "^2.0.0" } }, "node_modules/linkifyjs": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.1.3.tgz", - "integrity": "sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==" + "license": "MIT" }, "node_modules/loader-runner": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.11.5" } }, "node_modules/local-pkg": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", "dev": true, + "license": "MIT", "dependencies": { "mlly": "^1.4.2", "pkg-types": "^1.0.3" @@ -7081,9 +5868,8 @@ }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -7096,24 +5882,22 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "license": "MIT" }, "node_modules/lodash-es": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -7123,52 +5907,46 @@ }, "node_modules/loupe": { "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } }, "node_modules/lower-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/lz-string": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, + "license": "MIT", "bin": { "lz-string": "bin/bin.js" } }, "node_modules/magic-string": { "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/make-dir": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -7181,17 +5959,15 @@ }, "node_modules/make-dir/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/markdown-it": { "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -7206,56 +5982,49 @@ }, "node_modules/mdurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" + "license": "MIT" }, "node_modules/media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/merge-descriptors": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -7266,9 +6035,8 @@ }, "node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -7278,16 +6046,14 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -7297,9 +6063,8 @@ }, "node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7309,18 +6074,16 @@ }, "node_modules/min-indent": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7330,18 +6093,16 @@ }, "node_modules/minimist": { "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" } }, "node_modules/mlly": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", - "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.12.1", "pathe": "^1.1.2", @@ -7351,9 +6112,8 @@ }, "node_modules/mlly/node_modules/acorn": { "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -7363,14 +6123,12 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "license": "MIT" }, "node_modules/mui-color-input": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mui-color-input/-/mui-color-input-4.0.1.tgz", - "integrity": "sha512-Edc3sCa39zUoSL3XR9vjVnhMnLOBgd3mfszVfQc8stFqNMVaOujK2aThMtCOLiuLIyIxGcTa6dKV1qD5MmHPDw==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "@ctrl/tinycolor": "^4.1.0" }, @@ -7390,14 +6148,13 @@ }, "node_modules/nanoid": { "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7407,29 +6164,25 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "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" } }, "node_modules/neo-async": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/no-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" @@ -7437,14 +6190,12 @@ }, "node_modules/node-releases": { "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + "license": "MIT" }, "node_modules/npm-run-path": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -7457,9 +6208,8 @@ }, "node_modules/npm-run-path/node_modules/path-key": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7469,23 +6219,20 @@ }, "node_modules/nwsapi": { "version": "2.2.13", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.13.tgz", - "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7495,18 +6242,16 @@ }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -7522,9 +6267,8 @@ }, "node_modules/object.entries": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -7536,9 +6280,8 @@ }, "node_modules/object.fromentries": { "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -7554,9 +6297,8 @@ }, "node_modules/object.values": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -7571,9 +6313,8 @@ }, "node_modules/on-finished": { "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" }, @@ -7583,18 +6324,16 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -7607,9 +6346,8 @@ }, "node_modules/open": { "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "define-lazy-prop": "^2.0.0", @@ -7625,9 +6363,8 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -7642,14 +6379,12 @@ }, "node_modules/orderedmap": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", - "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" + "license": "MIT" }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7662,9 +6397,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -7677,17 +6411,15 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -7697,8 +6429,7 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -7714,9 +6445,8 @@ }, "node_modules/parse5": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.0.tgz", - "integrity": "sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==", "dev": true, + "license": "MIT", "dependencies": { "entities": "^4.5.0" }, @@ -7726,83 +6456,72 @@ }, "node_modules/parseurl": { "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" } }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "license": "MIT" }, "node_modules/path-to-regexp": { "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pathe": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pathval": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } }, "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -7812,9 +6531,8 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -7824,9 +6542,8 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -7837,9 +6554,8 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -7849,9 +6565,8 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -7864,9 +6579,8 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -7876,9 +6590,8 @@ }, "node_modules/pkg-types": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", - "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", "dev": true, + "license": "MIT", "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.2", @@ -7887,17 +6600,14 @@ }, "node_modules/possible-typed-array-names": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/postcss": { "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "funding": [ { "type": "opencollective", @@ -7912,6 +6622,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", @@ -7923,18 +6634,16 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/pretty-format": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -7946,9 +6655,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", "engines": { "node": ">=10" }, @@ -7958,15 +6666,13 @@ }, "node_modules/pretty-format/node_modules/react-is": { "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">= 0.6.0" @@ -7974,8 +6680,7 @@ }, "node_modules/prop-types": { "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -7984,34 +6689,29 @@ }, "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "license": "MIT" }, "node_modules/property-expr": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", - "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" + "license": "MIT" }, "node_modules/prosemirror-changeset": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", - "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", + "license": "MIT", "dependencies": { "prosemirror-transform": "^1.0.0" } }, "node_modules/prosemirror-collab": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", - "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "license": "MIT", "dependencies": { "prosemirror-state": "^1.0.0" } }, "node_modules/prosemirror-commands": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.1.tgz", - "integrity": "sha512-tNy4uaGWzvuUYXDke7B28krndIrdQJhSh0OLpubtwtEwFbjItOj/eoAfPvstBJyyV0S2+b5t4G+4XPXdxar6pg==", + "license": "MIT", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -8020,8 +6720,7 @@ }, "node_modules/prosemirror-dropcursor": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", - "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", + "license": "MIT", "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0", @@ -8030,8 +6729,7 @@ }, "node_modules/prosemirror-gapcursor": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", - "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", + "license": "MIT", "dependencies": { "prosemirror-keymap": "^1.0.0", "prosemirror-model": "^1.0.0", @@ -8041,8 +6739,7 @@ }, "node_modules/prosemirror-history": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", - "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", + "license": "MIT", "dependencies": { "prosemirror-state": "^1.2.2", "prosemirror-transform": "^1.0.0", @@ -8052,8 +6749,7 @@ }, "node_modules/prosemirror-inputrules": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", - "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", + "license": "MIT", "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.0.0" @@ -8061,8 +6757,7 @@ }, "node_modules/prosemirror-keymap": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", - "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", + "license": "MIT", "dependencies": { "prosemirror-state": "^1.0.0", "w3c-keyname": "^2.2.0" @@ -8070,8 +6765,7 @@ }, "node_modules/prosemirror-markdown": { "version": "1.13.1", - "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz", - "integrity": "sha512-Sl+oMfMtAjWtlcZoj/5L/Q39MpEnVZ840Xo330WJWUvgyhNmLBLN7MsHn07s53nG/KImevWHSE6fEj4q/GihHw==", + "license": "MIT", "dependencies": { "@types/markdown-it": "^14.0.0", "markdown-it": "^14.0.0", @@ -8080,8 +6774,7 @@ }, "node_modules/prosemirror-menu": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", - "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", + "license": "MIT", "dependencies": { "crelt": "^1.0.0", "prosemirror-commands": "^1.0.0", @@ -8091,24 +6784,21 @@ }, "node_modules/prosemirror-model": { "version": "1.23.0", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.23.0.tgz", - "integrity": "sha512-Q/fgsgl/dlOAW9ILu4OOhYWQbc7TQd4BwKH/RwmUjyVf8682Be4zj3rOYdLnYEcGzyg8LL9Q5IWYKD8tdToreQ==", + "license": "MIT", "dependencies": { "orderedmap": "^2.0.0" } }, "node_modules/prosemirror-schema-basic": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz", - "integrity": "sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==", + "license": "MIT", "dependencies": { "prosemirror-model": "^1.19.0" } }, "node_modules/prosemirror-schema-list": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.1.tgz", - "integrity": "sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==", + "license": "MIT", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -8117,8 +6807,7 @@ }, "node_modules/prosemirror-state": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", - "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "license": "MIT", "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0", @@ -8127,8 +6816,7 @@ }, "node_modules/prosemirror-tables": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.5.0.tgz", - "integrity": "sha512-VMx4zlYWm7aBlZ5xtfJHpqa3Xgu3b7srV54fXYnXgsAcIGRqKSrhiK3f89omzzgaAgAtDOV4ImXnLKhVfheVNQ==", + "license": "MIT", "dependencies": { "prosemirror-keymap": "^1.1.2", "prosemirror-model": "^1.8.1", @@ -8139,8 +6827,7 @@ }, "node_modules/prosemirror-trailing-node": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", - "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "license": "MIT", "dependencies": { "@remirror/core-constants": "3.0.0", "escape-string-regexp": "^4.0.0" @@ -8153,16 +6840,14 @@ }, "node_modules/prosemirror-transform": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.2.tgz", - "integrity": "sha512-2iUq0wv2iRoJO/zj5mv8uDUriOHWzXRnOTVgCzSXnktS/2iQRa3UUQwVlkBlYZFtygw6Nh1+X4mGqoYBINn5KQ==", + "license": "MIT", "dependencies": { "prosemirror-model": "^1.21.0" } }, "node_modules/prosemirror-view": { "version": "1.34.3", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.34.3.tgz", - "integrity": "sha512-mKZ54PrX19sSaQye+sef+YjBbNu2voNwLS1ivb6aD2IRmxRGW64HU9B644+7OfJStGLyxvOreKqEgfvXa91WIA==", + "license": "MIT", "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -8171,9 +6856,8 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -8184,37 +6868,32 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "license": "MIT" }, "node_modules/psl": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/punycode.js": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/qs": { "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -8227,14 +6906,11 @@ }, "node_modules/querystringify": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -8249,31 +6925,29 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -8286,8 +6960,7 @@ }, "node_modules/react": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -8297,9 +6970,8 @@ }, "node_modules/react-docgen": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.0.3.tgz", - "integrity": "sha512-i8aF1nyKInZnANZ4uZrH49qn1paRgBZ7wZiCNBMnenlPzEv0mRl+ShpTVEI6wZNl8sSc79xZkivtgLKQArcanQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.18.9", "@babel/traverse": "^7.18.9", @@ -8318,17 +6990,15 @@ }, "node_modules/react-docgen-typescript": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz", - "integrity": "sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==", "dev": true, + "license": "MIT", "peerDependencies": { "typescript": ">= 4.3.x" } }, "node_modules/react-dom": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -8339,8 +7009,7 @@ }, "node_modules/react-dropzone": { "version": "14.2.9", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.9.tgz", - "integrity": "sha512-jRZsMC7h48WONsOLHcmhyn3cRWJoIPQjPApvt/sJVfnYaB3Qltn025AoRTTJaj4WdmmgmLl6tUQg1s0wOhpodQ==", + "license": "MIT", "dependencies": { "attr-accept": "^2.2.2", "file-selector": "^0.6.0", @@ -8355,9 +7024,8 @@ }, "node_modules/react-element-to-jsx-string": { "version": "15.0.0", - "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz", - "integrity": "sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==", "dev": true, + "license": "MIT", "dependencies": { "@base2/pretty-print-object": "1.0.1", "is-plain-object": "5.0.0", @@ -8370,32 +7038,29 @@ }, "node_modules/react-element-to-jsx-string/node_modules/react-is": { "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/react-fast-compare": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", - "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==", + "license": "MIT" }, "node_modules/react-icons": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", - "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "license": "MIT", "peerDependencies": { "react": "*" } }, "node_modules/react-is": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + "license": "MIT" }, "node_modules/react-redux": { "version": "9.1.2", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", - "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", + "license": "MIT", "dependencies": { "@types/use-sync-external-store": "^0.0.3", "use-sync-external-store": "^1.0.0" @@ -8416,13 +7081,11 @@ }, "node_modules/react-redux/node_modules/@types/use-sync-external-store": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", - "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + "license": "MIT" }, "node_modules/react-router": { "version": "6.27.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", - "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", + "license": "MIT", "dependencies": { "@remix-run/router": "1.20.0" }, @@ -8435,8 +7098,7 @@ }, "node_modules/react-router-dom": { "version": "6.27.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", - "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", + "license": "MIT", "dependencies": { "@remix-run/router": "1.20.0", "react-router": "6.27.0" @@ -8451,8 +7113,7 @@ }, "node_modules/react-transition-group": { "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -8466,9 +7127,8 @@ }, "node_modules/recast": { "version": "0.23.9", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", - "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "ast-types": "^0.16.1", @@ -8483,9 +7143,8 @@ }, "node_modules/recast/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "peer": true, "engines": { "node": ">=0.10.0" @@ -8493,14 +7152,12 @@ }, "node_modules/redux": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", - "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + "license": "MIT" }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8519,14 +7176,12 @@ }, "node_modules/regenerator-runtime": { "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "license": "MIT" }, "node_modules/regexp.prototype.flags": { "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8542,23 +7197,20 @@ }, "node_modules/requireindex": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.5" } }, "node_modules/requires-port": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "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", @@ -8573,17 +7225,15 @@ }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -8591,10 +7241,8 @@ }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -8607,8 +7255,7 @@ }, "node_modules/rollup": { "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "license": "MIT", "dependencies": { "@types/estree": "1.0.6" }, @@ -8641,19 +7288,15 @@ }, "node_modules/rope-sequence": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", - "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==" + "license": "MIT" }, "node_modules/rrweb-cssom": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -8669,24 +7312,23 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/rxjs": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "devOptional": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/safe-array-concat": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -8702,8 +7344,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -8718,13 +7358,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-regex-test": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -8739,15 +7379,13 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/sass-embedded": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.80.1.tgz", - "integrity": "sha512-FQiaiA2Bc1a3/nXdl9cAz19cKKcW5uU+k1JUWx5Tt1UcSYmV0B+5V0GDHwtyF7UeCuoBMRl3B3LxQ6n317HLYQ==", + "version": "1.80.2", "devOptional": true, + "license": "MIT", "dependencies": { "@bufbuild/protobuf": "^2.0.0", "buffer-builder": "^0.2.0", @@ -8764,320 +7402,34 @@ "node": ">=16.0.0" }, "optionalDependencies": { - "sass-embedded-android-arm": "1.80.1", - "sass-embedded-android-arm64": "1.80.1", - "sass-embedded-android-ia32": "1.80.1", - "sass-embedded-android-riscv64": "1.80.1", - "sass-embedded-android-x64": "1.80.1", - "sass-embedded-darwin-arm64": "1.80.1", - "sass-embedded-darwin-x64": "1.80.1", - "sass-embedded-linux-arm": "1.80.1", - "sass-embedded-linux-arm64": "1.80.1", - "sass-embedded-linux-ia32": "1.80.1", - "sass-embedded-linux-musl-arm": "1.80.1", - "sass-embedded-linux-musl-arm64": "1.80.1", - "sass-embedded-linux-musl-ia32": "1.80.1", - "sass-embedded-linux-musl-riscv64": "1.80.1", - "sass-embedded-linux-musl-x64": "1.80.1", - "sass-embedded-linux-riscv64": "1.80.1", - "sass-embedded-linux-x64": "1.80.1", - "sass-embedded-win32-arm64": "1.80.1", - "sass-embedded-win32-ia32": "1.80.1", - "sass-embedded-win32-x64": "1.80.1" - } - }, - "node_modules/sass-embedded-android-arm": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.80.1.tgz", - "integrity": "sha512-XvUHgUN98IZFu7tb1xc15Q/VdtaYXUnkse1n4xHQSohIOzm0TytJDmUpSkMAEFFd+iBQBxyWc40rj6IPXQH/RA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-android-arm64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.80.1.tgz", - "integrity": "sha512-AjWjEtyvOLs9fIVvR2mHtRy2/OB/IzUGBYjOqGozU2BUC6acnuRmqLrKwprmZxTL7DDgQRoT/gtoo9wdtHHoEg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-android-ia32": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.80.1.tgz", - "integrity": "sha512-gzrlN2juF8F09zS3JqTBnc7Fq7ydIkXHeR8z4XVVpy2PTDLqOM0+HyVTJGOdRgJFWmMkl7BzD5c+pl8pW/EI7Q==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-android-riscv64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.80.1.tgz", - "integrity": "sha512-pFivqYfibQlno2Uc6I/YVeCFDpr4ltvv1mcIHQ0IL0u4+PqxKJXONGBOcRMAPFEQKDEiIUDml40HB+i5q9PUhg==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-android-x64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.80.1.tgz", - "integrity": "sha512-v4wHQ/bNV/s/ZWe3eYkkW8cEUao0woW5EBIzRZLtY0MOdIPnomum8uH+rRP3YGOQrawegjiDP8O9Fb+nhWYXVw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-darwin-arm64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.80.1.tgz", - "integrity": "sha512-CcY0FfzrnEkmWWevTEaEfZTRzWGHpz3aGFqNoRmkqrWrZYdiRqnr6PFHQJLugM76IoX1SfU2r8lXz25WKOzEBw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-darwin-x64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.80.1.tgz", - "integrity": "sha512-kaoww70nI8/7dCGRY4JTMEZYGTxBvqGZni1CWhBOZBTE/w1GH+1z6XGw7klVzGyw0Ysxms+abAMd8fVdCzUTzg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-arm": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.80.1.tgz", - "integrity": "sha512-6WGgcO/3bw8s2yB0TP6V4S3tCTq94bhGiSM93Xw8mr0cVPxR/VoUBeIvGdAmRKBmJiGlcJcdAbNcLGtyr7eF6w==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-arm64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.80.1.tgz", - "integrity": "sha512-jEn24I5MaVMgj6Tb3EzkIxIoKVvTE1lr0021N5Tv5zeG7cZCPrRO5+JplQnmwMm3i22PqYvJjhSCJ18URJPqrQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-ia32": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.80.1.tgz", - "integrity": "sha512-EXjSErbGxlpRWfro1fjqTACA6y/AN39LeqyL9FdM7ImGozpHbTllMkciM7wj8mZ0Rk8XLDMnvB53kYfgnjtzRA==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-musl-arm": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.80.1.tgz", - "integrity": "sha512-XR75p54m/NLKEcFMfUacqDTcbjr0gB1KaVwCoTsk3knbtcDfQDJNVnp5A48gu32yZXcDpGjNX+g8pUzQrKof3g==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-musl-arm64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.80.1.tgz", - "integrity": "sha512-uONMRDG1VgZYoyezncPw8i8T93qUyIoNAGoKGO2ZnuAtXwjBGWtEAdN5Xf2LnmJTyTFlLHDUZs8OHLTA958oVg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-musl-ia32": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.80.1.tgz", - "integrity": "sha512-4/2UUcSXxmvlr/HlOwa9m/DcljNFs1pcuoIAlY53f1WCd1JYGrqPUqlqGYGHCV9wuRHs1Pi1FHSBXAezyg3++w==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-musl-riscv64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.80.1.tgz", - "integrity": "sha512-wrh98HrCQQIVI12P3NkeGFTRrK6SuIDUHsYrumK3yCR8GdYIjbt8/Ij3nvrkTTrh03/1dNJIAYi/2svAFenJoQ==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-musl-x64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.80.1.tgz", - "integrity": "sha512-JOF/SjJYY5rEjyozS0sTRiIqIDZKFaZiBfJYP/z9yU7VHT9cd6XAxQ2iOkGSNO7cWInSFSit1kmSK50k3Ghm9A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-riscv64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.80.1.tgz", - "integrity": "sha512-DSX54EubX7Jh00J/hQO8L3WXQ1ynTm0K06GE/iildyy7nxjvF2KUkWKZDLKv56pLwevcRZR1iLXkdJUG92GWyg==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-linux-x64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.80.1.tgz", - "integrity": "sha512-v/5UDLV7+g1x8EwfIMYAADfWL5aiuxjP+4hW/arMEU9DaXPofymvZOnpLhylYyVduIDAMsj4BgIn9g0vA5ErQw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-win32-arm64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.80.1.tgz", - "integrity": "sha512-81f+X4sIsiQS8ynpYH0sARA0st1LzTuM88OU18Th19oNblSWcaXSQ8lxljwzNPvHcWx/FLPdgIoGW1Wzx3MeoA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/sass-embedded-win32-ia32": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.80.1.tgz", - "integrity": "sha512-VYSQyySBj3excFUytRBXjAHww75810+dOYFcBkSRupx04nCQwQm0avYqcjQfYl+eNzS4oNeEAQvhTRk8HHNDGg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.0.0" + "sass-embedded-android-arm": "1.80.2", + "sass-embedded-android-arm64": "1.80.2", + "sass-embedded-android-ia32": "1.80.2", + "sass-embedded-android-riscv64": "1.80.2", + "sass-embedded-android-x64": "1.80.2", + "sass-embedded-darwin-arm64": "1.80.2", + "sass-embedded-darwin-x64": "1.80.2", + "sass-embedded-linux-arm": "1.80.2", + "sass-embedded-linux-arm64": "1.80.2", + "sass-embedded-linux-ia32": "1.80.2", + "sass-embedded-linux-musl-arm": "1.80.2", + "sass-embedded-linux-musl-arm64": "1.80.2", + "sass-embedded-linux-musl-ia32": "1.80.2", + "sass-embedded-linux-musl-riscv64": "1.80.2", + "sass-embedded-linux-musl-x64": "1.80.2", + "sass-embedded-linux-riscv64": "1.80.2", + "sass-embedded-linux-x64": "1.80.2", + "sass-embedded-win32-arm64": "1.80.2", + "sass-embedded-win32-ia32": "1.80.2", + "sass-embedded-win32-x64": "1.80.2" } }, "node_modules/sass-embedded-win32-x64": { - "version": "1.80.1", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.80.1.tgz", - "integrity": "sha512-EtrqZckPgVSGH/rQxY7jdcX3wqltS1uzp2YEV7VAn27iwoDwThTmslQgpfWUFLVyaIjqgUjx58GJkHu020J19g==", + "version": "1.80.2", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -9088,18 +7440,16 @@ }, "node_modules/sass-embedded/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/sass-embedded/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "devOptional": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -9112,9 +7462,8 @@ }, "node_modules/saxes": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, + "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" }, @@ -9124,17 +7473,15 @@ }, "node_modules/scheduler": { "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -9150,9 +7497,8 @@ }, "node_modules/semver": { "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -9162,9 +7508,8 @@ }, "node_modules/send": { "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -9186,42 +7531,37 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/serialize-javascript": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-static": { "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, + "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", @@ -9234,9 +7574,8 @@ }, "node_modules/set-function-length": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9251,9 +7590,8 @@ }, "node_modules/set-function-name": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9266,15 +7604,13 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -9284,18 +7620,16 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -9311,15 +7645,13 @@ }, "node_modules/siginfo": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -9329,17 +7661,15 @@ }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/snake-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -9347,25 +7677,22 @@ }, "node_modules/source-map": { "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-js": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-support": { "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==", "devOptional": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -9373,42 +7700,37 @@ }, "node_modules/source-map-support/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "devOptional": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/stackback": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/std-env": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/storybook": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.3.5.tgz", - "integrity": "sha512-hYQVtP2l+3kO8oKDn4fjXXQYxgTRsj/LaV6lUMJH0zt+OhVmDXKJLxmdUP4ieTm0T8wEbSYosFavgPcQZlxRfw==", + "version": "8.3.6", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@storybook/core": "8.3.5" + "@storybook/core": "8.3.6" }, "bin": { "getstorybook": "bin/index.cjs", @@ -9422,9 +7744,8 @@ }, "node_modules/string.prototype.matchall": { "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9448,9 +7769,8 @@ }, "node_modules/string.prototype.repeat": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" @@ -9458,9 +7778,8 @@ }, "node_modules/string.prototype.trim": { "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9476,9 +7795,8 @@ }, "node_modules/string.prototype.trimend": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9490,9 +7808,8 @@ }, "node_modules/string.prototype.trimstart": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -9507,9 +7824,8 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9519,18 +7835,16 @@ }, "node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/strip-final-newline": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -9540,9 +7854,8 @@ }, "node_modules/strip-indent": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", - "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", "dev": true, + "license": "MIT", "dependencies": { "min-indent": "^1.0.1" }, @@ -9555,9 +7868,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -9567,9 +7879,8 @@ }, "node_modules/strip-literal": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", - "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", "dev": true, + "license": "MIT", "dependencies": { "js-tokens": "^9.0.0" }, @@ -9579,19 +7890,16 @@ }, "node_modules/strip-literal/node_modules/js-tokens": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", - "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/stylis": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + "license": "MIT" }, "node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -9601,8 +7909,7 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9612,29 +7919,25 @@ }, "node_modules/svg-parser": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + "license": "MIT" }, "node_modules/symbol-tree": { "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tapable": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/terser": { "version": "5.36.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", - "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", "devOptional": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -9650,9 +7953,8 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -9684,9 +7986,8 @@ }, "node_modules/terser/node_modules/acorn": { "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "devOptional": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -9696,72 +7997,64 @@ }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tiny-case": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", - "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" + "license": "MIT" }, "node_modules/tiny-invariant": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" }, "node_modules/tinybench": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tinypool": { "version": "0.8.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", - "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/tinyspy": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/tippy.js": { "version": "6.3.7", - "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", - "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "license": "MIT", "dependencies": { "@popperjs/core": "^2.9.0" } }, "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -9771,23 +8064,20 @@ }, "node_modules/toidentifier": { "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" } }, "node_modules/toposort": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", - "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + "license": "MIT" }, "node_modules/tough-cookie": { "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -9800,18 +8090,16 @@ }, "node_modules/tough-cookie/node_modules/universalify": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/tr46": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", "dev": true, + "license": "MIT", "dependencies": { "punycode": "^2.3.1" }, @@ -9821,18 +8109,16 @@ }, "node_modules/ts-dedent": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.10" } }, "node_modules/tsconfig-paths": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, + "license": "MIT", "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -9844,14 +8130,12 @@ }, "node_modules/tslib": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -9864,15 +8148,13 @@ }, "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -9882,17 +8164,15 @@ }, "node_modules/type-detect": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -9902,9 +8182,8 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -9915,9 +8194,8 @@ }, "node_modules/typed-array-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -9929,9 +8207,8 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -9948,9 +8225,8 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -9968,9 +8244,8 @@ }, "node_modules/typed-array-length": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -9988,9 +8263,8 @@ }, "node_modules/typescript": { "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "devOptional": true, + "license": "Apache-2.0", "peer": true, "bin": { "tsc": "bin/tsc", @@ -10002,20 +8276,17 @@ }, "node_modules/uc.micro": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" + "license": "MIT" }, "node_modules/ufo": { "version": "1.5.4", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", - "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/unbox-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -10028,33 +8299,29 @@ }, "node_modules/undici-types": { "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/unplugin": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.14.1.tgz", - "integrity": "sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.12.1", "webpack-virtual-modules": "^0.6.2" @@ -10073,9 +8340,8 @@ }, "node_modules/unplugin/node_modules/acorn": { "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -10085,8 +8351,6 @@ }, "node_modules/update-browserslist-db": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -10101,6 +8365,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.0" @@ -10114,18 +8379,16 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/url-parse": { "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -10133,17 +8396,15 @@ }, "node_modules/use-sync-external-store": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/util": { "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "inherits": "^2.0.3", @@ -10155,38 +8416,33 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/varint": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", - "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/vite": { - "version": "5.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", - "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", + "version": "5.4.10", + "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -10243,9 +8499,8 @@ }, "node_modules/vite-node": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", - "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", "dev": true, + "license": "MIT", "dependencies": { "cac": "^6.7.14", "debug": "^4.3.4", @@ -10265,8 +8520,7 @@ }, "node_modules/vite-plugin-svgr": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.2.0.tgz", - "integrity": "sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==", + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.5", "@svgr/core": "^8.1.0", @@ -10276,343 +8530,12 @@ "vite": "^2.6.0 || 3 || 4 || 5" } }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/vite/node_modules/@esbuild/win32-x64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -10623,9 +8546,8 @@ }, "node_modules/vite/node_modules/esbuild": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -10660,9 +8582,8 @@ }, "node_modules/vitest": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", - "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", "dev": true, + "license": "MIT", "dependencies": { "@vitest/expect": "1.6.0", "@vitest/runner": "1.6.0", @@ -10725,9 +8646,8 @@ }, "node_modules/vitest/node_modules/acorn": { "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -10737,9 +8657,8 @@ }, "node_modules/vitest/node_modules/acorn-walk": { "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.11.0" }, @@ -10749,14 +8668,12 @@ }, "node_modules/w3c-keyname": { "version": "2.2.8", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + "license": "MIT" }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, + "license": "MIT", "dependencies": { "xml-name-validator": "^5.0.0" }, @@ -10766,9 +8683,8 @@ }, "node_modules/watchpack": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -10779,23 +8695,20 @@ }, "node_modules/web-vitals": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", - "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" + "license": "Apache-2.0" }, "node_modules/webidl-conversions": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=12" } }, "node_modules/webpack": { "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", @@ -10839,24 +8752,21 @@ }, "node_modules/webpack-sources": { "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/webpack-virtual-modules": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", - "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/acorn": { "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -10866,18 +8776,16 @@ }, "node_modules/webpack/node_modules/acorn-import-attributes": { "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^8" } }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -10888,18 +8796,16 @@ }, "node_modules/webpack/node_modules/estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/whatwg-encoding": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dev": true, + "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" }, @@ -10909,9 +8815,8 @@ }, "node_modules/whatwg-encoding/node_modules/iconv-lite": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -10921,18 +8826,16 @@ }, "node_modules/whatwg-mimetype": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/whatwg-url": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", "dev": true, + "license": "MIT", "dependencies": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" @@ -10943,9 +8846,8 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -10958,9 +8860,8 @@ }, "node_modules/which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -10974,9 +8875,8 @@ }, "node_modules/which-builtin-type": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", - "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", "dev": true, + "license": "MIT", "dependencies": { "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", @@ -11000,9 +8900,8 @@ }, "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, + "license": "MIT", "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", @@ -11018,9 +8917,8 @@ }, "node_modules/which-typed-array": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -11037,9 +8935,8 @@ }, "node_modules/why-is-node-running": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, + "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" @@ -11053,24 +8950,21 @@ }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ws": { "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -11089,37 +8983,32 @@ }, "node_modules/xml-name-validator": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18" } }, "node_modules/xmlchars": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", "engines": { "node": ">= 6" } }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -11129,8 +9018,7 @@ }, "node_modules/yup": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/yup/-/yup-1.4.0.tgz", - "integrity": "sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==", + "license": "MIT", "dependencies": { "property-expr": "^2.0.5", "tiny-case": "^1.0.3", diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 10abbdb6..617a5efb 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -21,8 +21,23 @@ import { Error404 } from "./scenes/errors/404"; import { Error403 } from "./scenes/errors/403"; import HomePageTemplate from "./templates/HomePageTemplate/HomePageTemplate"; +import { useEffect, useState } from "react"; +import { getTeamCount } from "./services/teamServices"; + const App = () => { + const [isAdminLogin, setIsAdminLogin] = useState(false); + useEffect(() => { + const fetchTeamCount = async () => { + try { + const { teamExists } = await getTeamCount(); + setIsAdminLogin(!teamExists); + } catch (err) { + } + } + fetchTeamCount(); + }, []); + return ( <> @@ -39,14 +54,13 @@ const App = () => { } /> - } /> - } /> + } /> + } /> } /> } /> } /> } /> - } /> } /> } /> diff --git a/frontend/src/scenes/login/CreateAccountPage.jsx b/frontend/src/scenes/login/CreateAccountPage.jsx index 431f0a96..b6c6f4d9 100644 --- a/frontend/src/scenes/login/CreateAccountPage.jsx +++ b/frontend/src/scenes/login/CreateAccountPage.jsx @@ -12,41 +12,47 @@ import Logo from "../../components/Logo/Logo"; import * as Yup from "yup"; import { Form, Formik } from "formik"; -const validationSchema = Yup.object().shape({ - name: Yup.string() - .required("Name is required") - .matches( - /^[A-Za-z'\s-]+$/, - "Name can only contain letters, hyphens and apostrophes" - ) - .trim(), - surname: Yup.string() - .required("Surname is required") - .matches( - /^[A-Za-z'\s-]+$/, - "Surname can only contain letters, hyphens and apostrophes" - ) - .trim(), - email: Yup.string() - .matches( - /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, - "Enter a valid email address" - ) - .required("Email is required") - .trim(), - password: Yup.string() - .required("Password is required") - .min(8, "Password must be at least 8 characters") - .matches( - /[!@#$%^&*(),.?":{}|<>_\-=]/, - "Password must contain at least one special character" - ), -}); - -function CreateAccountPage() { +function CreateAccountPage({ isAdmin = false, setIsAdmin}) { const { loginAuth } = useAuth(); const navigate = useNavigate(); const [serverErrors, setServerErrors] = useState([]); + + const validationSchema = Yup.object().shape({ + name: Yup.string() + .required("Name is required") + .matches( + /^[A-Za-z'\s-]+$/, + "Name can only contain letters, hyphens and apostrophes" + ) + .trim(), + surname: Yup.string() + .required("Surname is required") + .matches( + /^[A-Za-z'\s-]+$/, + "Surname can only contain letters, hyphens and apostrophes" + ) + .trim(), + email: Yup.string() + .matches( + /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, + "Enter a valid email address" + ) + .required("Email is required") + .trim(), + password: Yup.string() + .required("Password is required") + .min(8, "Password must be at least 8 characters") + .matches( + /[!@#$%^&*(),.?":{}|<>_\-=]/, + "Password must contain at least one special character" + ), + ...(isAdmin && { + confirmPassword: Yup.string() + .required("Confirm Password is required") + .oneOf([Yup.ref('password'), null], "Passwords must match"), + }), + }); + return ( (
-

Create an account

- + {isAdmin ?

Create admin account

:

Create an account

}
+ { + isAdmin && +
+ +
+ }
- Already have an account? + Already have an account?
)} diff --git a/frontend/src/scenes/login/LoginPage.jsx b/frontend/src/scenes/login/LoginPage.jsx index 1433d2d6..5f4479c6 100644 --- a/frontend/src/scenes/login/LoginPage.jsx +++ b/frontend/src/scenes/login/LoginPage.jsx @@ -1,5 +1,5 @@ -import React, { useState } from "react"; -import { Formik, Form, Field } from "formik"; +import React, { useState, useEffect} from "react"; +import { Formik, Form } from "formik"; import * as Yup from "yup"; import styles from "./Login.module.css"; import CustomTextField from "../../components/TextFieldComponents/CustomTextField/CustomTextField"; @@ -22,13 +22,19 @@ const validationSchema = Yup.object({ password: Yup.string().required("Password is required").trim(), }); -function LoginPage() { +function LoginPage({isAdmin=false}) { const [rememberMe, setRememberMe]=useState(false) const [serverErrors, setServerErrors] = useState([]); const { loginAuth } = useAuth(); - const navigate = useNavigate(); + const navigate = useNavigate(); + useEffect(() => { + if (isAdmin) { + navigate('/signup'); + } + }, [isAdmin]); return ( + Date: Sat, 16 Nov 2024 19:02:46 +0300 Subject: [PATCH 28/66] Update docker-compose.yml --- docker-compose.yml | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index bf2a2507..0cf50674 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,29 +57,29 @@ services: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data - # frontend: - # build: ./frontend - # volumes: - # - ./frontend:/app - # - /app/node_modules - # ports: - # - "4173:4173" - # develop: - # watch: - # - action: sync - # path: ./frontend - # target: /app - # ignore: - # - node_modules/ - # environment: - # - NODE_ENV=${NODE_ENV:-development} - # command: > - # bash -c " - # if [ \"$NODE_ENV\" = \"development\" ]; then - # npm run dev; - # elif [ \"$NODE_ENV\" != \"development\" ]; then - # npm run build && npm run preview; - # fi" + frontend: + build: ./frontend + volumes: + - ./frontend:/app + - /app/node_modules + ports: + - "4173:4173" + develop: + watch: + - action: sync + path: ./frontend + target: /app + ignore: + - node_modules/ + environment: + - NODE_ENV=${NODE_ENV:-development} + command: > + bash -c " + if [ \"$NODE_ENV\" = \"development\" ]; then + npm run dev; + elif [ \"$NODE_ENV\" != \"development\" ]; then + npm run build && npm run preview; + fi" mailhog: image: mailhog/mailhog ports: From afde799866fb10468996d1f12300368f99c3b73f Mon Sep 17 00:00:00 2001 From: d02ev Date: Fri, 29 Nov 2024 22:33:28 +0530 Subject: [PATCH 29/66] update error toast and added config fetch --- backend/src/controllers/team.controller.js | 22 +++++++++++++++++-- backend/src/routes/team.routes.js | 2 ++ backend/src/service/team.service.js | 13 +++++++++++ .../src/scenes/settings/CodeTab/CodeTab.jsx | 21 ++++++++++++++---- frontend/src/services/teamServices.js | 10 +++++++++ 5 files changed, 62 insertions(+), 6 deletions(-) diff --git a/backend/src/controllers/team.controller.js b/backend/src/controllers/team.controller.js index ce381a32..a49864d2 100644 --- a/backend/src/controllers/team.controller.js +++ b/backend/src/controllers/team.controller.js @@ -3,7 +3,7 @@ const TeamService = require("../service/team.service"); const { internalServerError } = require("../utils/errors.helper"); const { MAX_ORG_NAME_LENGTH, ORG_NAME_REGEX } = require('../utils/constants.helper'); const db = require("../models"); -const { encryptApiKey } = require("../utils/team.helper"); +const { encryptApiKey, decryptApiKey } = require("../utils/team.helper"); const Team = db.Team; const teamService = new TeamService(); @@ -62,6 +62,24 @@ const getTeamCount = async (req, res) => { } }; +const getServerUrlAndApiKey = async (req, res) => { + try { + let { serverUrl, apiKey } = await teamService.fetchServerUrlAndApiKey(); + apiKey = decryptApiKey(apiKey); + const data = { + serverUrl, + apiKey + } + return res.status(200).json(data); + } catch (err) { + const { statusCode, payload } = internalServerError( + "GET_SERVER_URL_AND_API_KEY_ERROR", + err.message + ); + res.status(statusCode).json(payload); + } +}; + const getTeamDetails = async (req, res) => { try { const data = await teamService.getTeam(); @@ -168,4 +186,4 @@ const changeRole = async (req, res) => { } } -module.exports = { setOrganisation, getTeamDetails, updateTeamDetails, removeMember, changeRole, getTeamCount, setConfig }; +module.exports = { setOrganisation, getTeamDetails, getServerUrlAndApiKey, updateTeamDetails, removeMember, changeRole, getTeamCount, setConfig }; diff --git a/backend/src/routes/team.routes.js b/backend/src/routes/team.routes.js index 1cf82e20..7cc0474d 100644 --- a/backend/src/routes/team.routes.js +++ b/backend/src/routes/team.routes.js @@ -3,6 +3,7 @@ const { setOrganisation, setConfig, getTeamDetails, + getServerUrlAndApiKey, getTeamCount, updateTeamDetails, removeMember, @@ -20,6 +21,7 @@ const router = express.Router(); const teamPermissions = settings.team.permissions; router.get("/details", authenticateJWT, getTeamDetails); +router.get('/get-config', authenticateJWT, accessGuard(teamPermissions.serverUrlAndApiKey), getServerUrlAndApiKey); router.get("/count", getTeamCount); router.post("/set-organisation", authenticateJWT, accessGuard(teamPermissions.setOrg), setOrganisation); diff --git a/backend/src/service/team.service.js b/backend/src/service/team.service.js index f62a2134..c5f42eb0 100644 --- a/backend/src/service/team.service.js +++ b/backend/src/service/team.service.js @@ -146,6 +146,19 @@ class TeamService { throw new Error("Failed to add server url and api key"); } } + + async fetchServerUrlAndApiKey() { + try { + const team = await Team.findOne({ + limit: 1, + + }); + const { serverUrl, apiKey } = team; + return { serverUrl, apiKey }; + } catch (err) { + throw new Error("Failed to fetch server url and api key"); + } + } } module.exports = TeamService; diff --git a/frontend/src/scenes/settings/CodeTab/CodeTab.jsx b/frontend/src/scenes/settings/CodeTab/CodeTab.jsx index ef88ed0e..325f3441 100644 --- a/frontend/src/scenes/settings/CodeTab/CodeTab.jsx +++ b/frontend/src/scenes/settings/CodeTab/CodeTab.jsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import styles from "./CodeTab.module.css"; import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; import DeleteOutlinedIcon from '@mui/icons-material/DeleteOutlined'; @@ -6,7 +6,7 @@ import Button from "@components/Button/Button"; import ContentCopyOutlinedIcon from '@mui/icons-material/ContentCopyOutlined'; import { generateApiKey } from "../../../utils/generalHelper"; import { emitToastError } from "../../../utils/guideHelper"; -import { setConfig } from '../../../services/teamServices'; +import { setConfig, getConfig } from '../../../services/teamServices'; import toastEmitter, { TOAST_EMITTER_KEY } from "../../../utils/toastEmitter"; const CodeTab = () => { @@ -14,6 +14,19 @@ const CodeTab = () => { const [serverUrl, setServerUrl] = useState('') const [isLoading, setIsLoading] = useState(false); + useEffect(() => { + const getServerUrlAndApiKey = async () => { + try { + const { serverUrl, apiKey } = await getConfig(); + setServerUrl(serverUrl); + setApiKey(apiKey); + } catch (err) { + console.error('Error fetching server url and api key: ', err); + } + } + getServerUrlAndApiKey(); + }, []) + const handleUrlChange = (e) => { setServerUrl(e.target.value); }; @@ -35,11 +48,11 @@ const CodeTab = () => { try { const url = new URL(serverUrl); if (!['http:', 'https:'].includes(url.protocol)) { - toastEmitter.emit(TOAST_EMITTER_KEY, 'Invalid URL protocol'); + toastEmitter.emit(TOAST_EMITTER_KEY, 'Invalid URL protocol must be http or https'); return; } } catch { - toastEmitter.emit(TOAST_EMITTER_KEY, 'Server URL must start with http:// or https://'); + toastEmitter.emit(TOAST_EMITTER_KEY, 'Invalid server URL'); return; } diff --git a/frontend/src/services/teamServices.js b/frontend/src/services/teamServices.js index f4193fe6..6f8c9190 100644 --- a/frontend/src/services/teamServices.js +++ b/frontend/src/services/teamServices.js @@ -32,4 +32,14 @@ export const setConfig = async (serverUrl, apiKey) => { console.error('Error setting Server URL and API Key: ', err); throw err; } +} + +export const getConfig = async () => { + try { + const response = await apiClient.get(`${baseEndpoint}/get-config`); + return response.data; + } catch (err) { + console.error('Error getting Server URL and API Key: ', err); + throw err; + } } \ No newline at end of file From 19553c141ec1f2f695c4172b279f70c56bbe57b9 Mon Sep 17 00:00:00 2001 From: d02ev Date: Tue, 3 Dec 2024 23:46:22 +0530 Subject: [PATCH 30/66] BE refactors --- backend/src/controllers/team.controller.js | 69 +++++++++++----------- backend/src/utils/constants.helper.js | 8 ++- backend/src/utils/team.helper.js | 31 +++++++++- frontend/src/utils/constants.js | 5 +- 4 files changed, 74 insertions(+), 39 deletions(-) diff --git a/backend/src/controllers/team.controller.js b/backend/src/controllers/team.controller.js index a49864d2..4d05e250 100644 --- a/backend/src/controllers/team.controller.js +++ b/backend/src/controllers/team.controller.js @@ -1,9 +1,9 @@ const settings = require("../../config/settings"); const TeamService = require("../service/team.service"); const { internalServerError } = require("../utils/errors.helper"); -const { MAX_ORG_NAME_LENGTH, ORG_NAME_REGEX } = require('../utils/constants.helper'); +const { MAX_ORG_NAME_LENGTH, ORG_NAME_REGEX, VALID_URL_REGEX } = require('../utils/constants.helper'); const db = require("../models"); -const { encryptApiKey, decryptApiKey } = require("../utils/team.helper"); +const { encryptApiKey, decryptApiKey, validateServerUrl } = require("../utils/team.helper"); const Team = db.Team; const teamService = new TeamService(); @@ -87,14 +87,14 @@ const getTeamDetails = async (req, res) => { throw new Error("Team data not found"); } const result = { - name: data.team.name, - users: data.users.map((user)=> ({ - id: user.id, - name: user.name, - email: user.email, - role: settings.user.roleName[user.role], - createdAt: new Intl.DateTimeFormat('en-US').format(user.createdAt) - })), + name: data.team.name, + users: data.users.map((user) => ({ + id: user.id, + name: user.name, + email: user.email, + role: settings.user.roleName[user.role], + createdAt: new Intl.DateTimeFormat('en-US').format(user.createdAt) + })), } return res.status(200).json(result); } catch (err) { @@ -107,42 +107,43 @@ const getTeamDetails = async (req, res) => { }; const updateTeamDetails = async (req, res) => { - const { name } = req.body; - try { - await teamService.updateTeam(name); - return res.status(200).json({ message: "Team Details Updated Successfully" }); - } catch (err) { - const { statusCode, payload } = internalServerError( - "UPDATE_TEAM_ERROR", - err.message, - ); - res.status(statusCode).json(payload); - } + const { name } = req.body; + try { + await teamService.updateTeam(name); + return res.status(200).json({ message: "Team Details Updated Successfully" }); + } catch (err) { + const { statusCode, payload } = internalServerError( + "UPDATE_TEAM_ERROR", + err.message, + ); + res.status(statusCode).json(payload); + } }; const setConfig = async (req, res) => { let { serverUrl, apiKey } = req.body; - if (!serverUrl || typeof serverUrl !== 'string' || serverUrl.trim().length === 0) { - return res.status(400).json({ message: 'Server URL is required and should be a non-empty string' }); - } if (!apiKey || typeof apiKey !== "string" || apiKey.trim().length === 0) { return res.status(400).json({ message: 'API Key is required and should be a non-empty string' }); } - serverUrl = serverUrl.trim(); + serverUrl = serverUrl && serverUrl !== "" ? serverUrl.trim() : serverUrl; apiKey = apiKey.trim(); const encryptedApiKey = encryptApiKey(apiKey); + const result = validateServerUrl(serverUrl); - try { - const url = new URL(serverUrl); - if (!['http:', 'https:'].includes(url.protocol)) { - throw new Error('Invalid protocol'); - } - if (url.username || url.password) { - throw new Error('URL cannt contain credentials'); + if (!result.valid) { + return res.status(400).json({ message: result.errors }); + } + + if (serverUrl !== "") { + try { + const url = new URL(serverUrl); + if (url.username || url.password) { + throw new Error('URL cannot contain credentials'); + } + } catch (err) { + return res.status(400).json({ message: 'Invalid server URL format.' }); } - } catch (err) { - return res.status(400).json({ message: 'Invalid server URL format. Only HTTP/HTTPS protocols are allowed.' }); } try { diff --git a/backend/src/utils/constants.helper.js b/backend/src/utils/constants.helper.js index a9f315cb..c94c884b 100644 --- a/backend/src/utils/constants.helper.js +++ b/backend/src/utils/constants.helper.js @@ -2,8 +2,8 @@ module.exports = Object.freeze({ JWT_EXPIRES_IN_1H: '1h', JWT_EXPIRES_IN_20M: '20m', TOKEN_LIFESPAN: 3600 * 1000, - // API_BASE_URL: 'https://onboarding-demo.bluewavelabs.ca/api/', - API_BASE_URL: 'localhost:3000/api/', + API_BASE_URL: 'https://onboarding-demo.bluewavelabs.ca/api/', + // API_BASE_URL: 'localhost:3000/api/', MAX_FILE_SIZE: 3 * 1024 * 1024, ROLE: { ADMIN: '1', @@ -11,5 +11,9 @@ module.exports = Object.freeze({ }, MAX_ORG_NAME_LENGTH: 100, ORG_NAME_REGEX: /^[a-zA-Z0-9\s\-_&.]+$/, + URL_PROTOCOL_REGEX: /^(https?:\/\/)/, + URL_DOMAIN_REGEX: /^https?:\/\/([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/, + URL_PORT_REGEX: /^https?:\/\/[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(:[0-9]{1,5})?/, + URL_PATH_REGEX: /^https?:\/\/[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\/[^\s]*)?$/ }); \ No newline at end of file diff --git a/backend/src/utils/team.helper.js b/backend/src/utils/team.helper.js index 9d1a1cc3..46cc99fe 100644 --- a/backend/src/utils/team.helper.js +++ b/backend/src/utils/team.helper.js @@ -1,4 +1,5 @@ const jwt = require('jsonwebtoken'); +const { URL_PROTOCOL_REGEX, URL_DOMAIN_REGEX } = require('./constants.helper'); require('dotenv').config(); @@ -14,4 +15,32 @@ const decryptApiKey = (apiKey) => { } } -module.exports = { encryptApiKey, decryptApiKey }; \ No newline at end of file +const validateServerUrl = url => { + const errors = []; + + if (url === "") { + return { valid: true, error: null } + } + + if (!URL_PROTOCOL_REGEX.test(url)) { + errors.push("Invalid or missing protocol (must be 'http://' or 'https://').") + } + + const domainMatch = url.match(URL_DOMAIN_REGEX); + if (!domainMatch) { + errors.push("Invalid domain name (must include a valid top-level domain like '.com')."); + } else { + const domain = domainMatch[1]; + if (!/^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(domain)) { + errors.push(`Malformed domain: '${domain}'.`); + } + } + + if (errors.length === 0) { + return { valid: true, errors: null } + } + + return { valid: false, errors } +}; + +module.exports = { encryptApiKey, decryptApiKey, validateServerUrl }; \ No newline at end of file diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index ae38e4a2..9927b6ce 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -1,9 +1,10 @@ // API constants //local environment -//export const API_BASE_URL = 'http://localhost:3000/api/'; +// export const API_BASE_URL = 'http://localhost:3000/api/'; //staging environment -export const API_BASE_URL = 'http://localhost:3000/api/'; +export const API_BASE_URL = 'https://onboarding-demo.bluewavelabs.ca/api/'; +// export const API_BASE_URL = 'http://localhost:3000/api/'; // Other constants export const APP_TITLE = 'Bluewave Onboarding'; export const SUPPORT_EMAIL = 'support@bluewave.com'; From eeb97c31c21913e434af788e0aaf132f926ae172 Mon Sep 17 00:00:00 2001 From: d02ev Date: Sat, 7 Dec 2024 20:28:53 +0530 Subject: [PATCH 31/66] resolved merge conflict --- backend/config/settings.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/backend/config/settings.js b/backend/config/settings.js index 5417ebe2..2bb3415b 100644 --- a/backend/config/settings.js +++ b/backend/config/settings.js @@ -23,12 +23,9 @@ module.exports = { popups: [userRole.ADMIN], hints: [userRole.ADMIN], banners: [userRole.ADMIN], -<<<<<<< HEAD - serverUrlAndApiKey: [userRole.ADMIN] -======= + serverUrlAndApiKey: [userRole.ADMIN], links: [userRole.ADMIN], tours: [userRole.ADMIN], ->>>>>>> develop } } }; From 55c9865d5e8309f4c2ac290abb054d4808dc99c0 Mon Sep 17 00:00:00 2001 From: d02ev Date: Sat, 7 Dec 2024 20:58:01 +0530 Subject: [PATCH 32/66] comment resolution --- backend/src/controllers/team.controller.js | 13 ++++++++----- backend/src/utils/constants.helper.js | 4 ++-- frontend/src/utils/constants.js | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/backend/src/controllers/team.controller.js b/backend/src/controllers/team.controller.js index 4d05e250..3099e4a1 100644 --- a/backend/src/controllers/team.controller.js +++ b/backend/src/controllers/team.controller.js @@ -129,13 +129,16 @@ const setConfig = async (req, res) => { serverUrl = serverUrl && serverUrl !== "" ? serverUrl.trim() : serverUrl; apiKey = apiKey.trim(); const encryptedApiKey = encryptApiKey(apiKey); - const result = validateServerUrl(serverUrl); - if (!result.valid) { - return res.status(400).json({ message: result.errors }); - } + if (serverUrl) { + const result = validateServerUrl(serverUrl); - if (serverUrl !== "") { + if (!result.valid) { + return res.status(400).json({ message: result.errors }); + } + } + + if (serverUrl && serverUrl !== "") { try { const url = new URL(serverUrl); if (url.username || url.password) { diff --git a/backend/src/utils/constants.helper.js b/backend/src/utils/constants.helper.js index c94c884b..4b5b71ed 100644 --- a/backend/src/utils/constants.helper.js +++ b/backend/src/utils/constants.helper.js @@ -2,8 +2,8 @@ module.exports = Object.freeze({ JWT_EXPIRES_IN_1H: '1h', JWT_EXPIRES_IN_20M: '20m', TOKEN_LIFESPAN: 3600 * 1000, - API_BASE_URL: 'https://onboarding-demo.bluewavelabs.ca/api/', - // API_BASE_URL: 'localhost:3000/api/', + // API_BASE_URL: 'https://onboarding-demo.bluewavelabs.ca/api/', + API_BASE_URL: 'localhost:3000/api/', MAX_FILE_SIZE: 3 * 1024 * 1024, ROLE: { ADMIN: '1', diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 9927b6ce..54add205 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -4,7 +4,7 @@ //staging environment export const API_BASE_URL = 'https://onboarding-demo.bluewavelabs.ca/api/'; -// export const API_BASE_URL = 'http://localhost:3000/api/'; + // Other constants export const APP_TITLE = 'Bluewave Onboarding'; export const SUPPORT_EMAIL = 'support@bluewave.com'; From df26b0c673c8c0c33acaf8a49ec411b35eca9922 Mon Sep 17 00:00:00 2001 From: d02ev Date: Sat, 14 Dec 2024 23:57:35 +0530 Subject: [PATCH 33/66] updated setConfig validations --- backend/src/controllers/team.controller.js | 36 ++++++---------------- backend/src/routes/team.routes.js | 3 +- backend/src/utils/constants.helper.js | 2 -- backend/src/utils/team.helper.js | 27 +++++++++++++--- 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/backend/src/controllers/team.controller.js b/backend/src/controllers/team.controller.js index 3099e4a1..8d25b84d 100644 --- a/backend/src/controllers/team.controller.js +++ b/backend/src/controllers/team.controller.js @@ -3,7 +3,8 @@ const TeamService = require("../service/team.service"); const { internalServerError } = require("../utils/errors.helper"); const { MAX_ORG_NAME_LENGTH, ORG_NAME_REGEX, VALID_URL_REGEX } = require('../utils/constants.helper'); const db = require("../models"); -const { encryptApiKey, decryptApiKey, validateServerUrl } = require("../utils/team.helper"); +const { decryptApiKey, encryptApiKey } = require("../utils/team.helper"); +const { validationResult } = require("express-validator"); const Team = db.Team; const teamService = new TeamService(); @@ -121,35 +122,16 @@ const updateTeamDetails = async (req, res) => { }; const setConfig = async (req, res) => { - let { serverUrl, apiKey } = req.body; - if (!apiKey || typeof apiKey !== "string" || apiKey.trim().length === 0) { - return res.status(400).json({ message: 'API Key is required and should be a non-empty string' }); - } - - serverUrl = serverUrl && serverUrl !== "" ? serverUrl.trim() : serverUrl; - apiKey = apiKey.trim(); - const encryptedApiKey = encryptApiKey(apiKey); - - if (serverUrl) { - const result = validateServerUrl(serverUrl); - - if (!result.valid) { - return res.status(400).json({ message: result.errors }); - } - } + const validationErrors = validationResult(req); - if (serverUrl && serverUrl !== "") { - try { - const url = new URL(serverUrl); - if (url.username || url.password) { - throw new Error('URL cannot contain credentials'); - } - } catch (err) { - return res.status(400).json({ message: 'Invalid server URL format.' }); - } + if (!validationErrors.isEmpty()) { + return res.status(400).json({ errors: validationErrors.array() }); } try { + const { serverUrl, apiKey } = req.body; + const encryptedApiKey = encryptApiKey(apiKey); + await teamService.addServerUrlAndApiKey(serverUrl, encryptedApiKey); return res.status(200).json({ message: "Server URL and API Key Set Successfully" }); } catch (err) { @@ -190,4 +172,4 @@ const changeRole = async (req, res) => { } } -module.exports = { setOrganisation, getTeamDetails, getServerUrlAndApiKey, updateTeamDetails, removeMember, changeRole, getTeamCount, setConfig }; +module.exports = { setOrganisation, getTeamDetails, getServerUrlAndApiKey, updateTeamDetails, removeMember, changeRole, getTeamCount, setConfig, teamService }; diff --git a/backend/src/routes/team.routes.js b/backend/src/routes/team.routes.js index 7cc0474d..32db24ba 100644 --- a/backend/src/routes/team.routes.js +++ b/backend/src/routes/team.routes.js @@ -16,6 +16,7 @@ const { const authenticateJWT = require("../middleware/auth.middleware"); const accessGuard = require("../middleware/accessGuard.middleware"); const settings = require("../../config/settings"); +const { validateSetConfig } = require("../utils/team.helper"); const router = express.Router(); const teamPermissions = settings.team.permissions; @@ -28,7 +29,7 @@ router.post("/set-organisation", authenticateJWT, accessGuard(teamPermissions.se router.post("/invite", authenticateJWT, accessGuard(teamPermissions.invite), sendTeamInvite); router.put("/update", authenticateJWT, accessGuard(teamPermissions.update), updateTeamDetails); router.put("/change-role", authenticateJWT, accessGuard(teamPermissions.changeRole), changeRole); -router.put('/set-config', authenticateJWT, accessGuard(teamPermissions.serverUrlAndApiKey), setConfig); +router.put('/set-config', authenticateJWT, accessGuard(teamPermissions.serverUrlAndApiKey), validateSetConfig, setConfig); router.delete("/remove/:memberId", authenticateJWT, accessGuard(teamPermissions.removeUser), removeMember); router.get('/get-all-invites', authenticateJWT, accessGuard(teamPermissions.removeUser), getAllInvites); diff --git a/backend/src/utils/constants.helper.js b/backend/src/utils/constants.helper.js index 4b5b71ed..b3d04bbc 100644 --- a/backend/src/utils/constants.helper.js +++ b/backend/src/utils/constants.helper.js @@ -13,7 +13,5 @@ module.exports = Object.freeze({ ORG_NAME_REGEX: /^[a-zA-Z0-9\s\-_&.]+$/, URL_PROTOCOL_REGEX: /^(https?:\/\/)/, URL_DOMAIN_REGEX: /^https?:\/\/([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/, - URL_PORT_REGEX: /^https?:\/\/[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(:[0-9]{1,5})?/, - URL_PATH_REGEX: /^https?:\/\/[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\/[^\s]*)?$/ }); \ No newline at end of file diff --git a/backend/src/utils/team.helper.js b/backend/src/utils/team.helper.js index 46cc99fe..fa241d01 100644 --- a/backend/src/utils/team.helper.js +++ b/backend/src/utils/team.helper.js @@ -1,5 +1,6 @@ const jwt = require('jsonwebtoken'); const { URL_PROTOCOL_REGEX, URL_DOMAIN_REGEX } = require('./constants.helper'); +const { check } = require('express-validator'); require('dotenv').config(); @@ -18,10 +19,6 @@ const decryptApiKey = (apiKey) => { const validateServerUrl = url => { const errors = []; - if (url === "") { - return { valid: true, error: null } - } - if (!URL_PROTOCOL_REGEX.test(url)) { errors.push("Invalid or missing protocol (must be 'http://' or 'https://').") } @@ -43,4 +40,24 @@ const validateServerUrl = url => { return { valid: false, errors } }; -module.exports = { encryptApiKey, decryptApiKey, validateServerUrl }; \ No newline at end of file +const validateSetConfig = [ + check('apiKey') + .exists().withMessage('API Key is required') + .isString().withMessage('API Key must be a string') + .trim() + .notEmpty().withMessage('API Key cannot be empty'), + + check('serverUrl') + .optional() + .isString().withMessage('Server URL must be a string') + .trim() + .custom(value => { + const result = validateServerUrl(value); + if (result.valid) { + return true; + } + throw new Error(result.errors); + }) +]; + +module.exports = { encryptApiKey, decryptApiKey, validateSetConfig }; \ No newline at end of file From 32989345fe294d199ae65ff0c572b4a7ace2be14 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Tue, 10 Dec 2024 15:22:12 -0800 Subject: [PATCH 34/66] feat: add column action url to models --- backend/src/models/Banner.js | 140 +++++++++++++++++++---------------- backend/src/models/Popup.js | 35 ++++++--- 2 files changed, 103 insertions(+), 72 deletions(-) diff --git a/backend/src/models/Banner.js b/backend/src/models/Banner.js index 23d9124b..fb021833 100644 --- a/backend/src/models/Banner.js +++ b/backend/src/models/Banner.js @@ -1,74 +1,90 @@ -const { validateHexColor, validateActionButton } = require('../utils/guide.helper'); -const { validatePositionWrapper } = require('../utils/banner.helper'); +const { + validateHexColor, + validateActionButton, +} = require("../utils/guide.helper"); +const { validatePositionWrapper } = require("../utils/banner.helper"); module.exports = (sequelize, DataTypes) => { - const Banner = sequelize.define('Banner', { - closeButtonAction: { - type: DataTypes.STRING, - allowNull: false, - validate: { - isValidAction(value) { - validateActionButton(value); - }, - }, + const Banner = sequelize.define( + "Banner", + { + closeButtonAction: { + type: DataTypes.STRING, + allowNull: false, + validate: { + isValidAction(value) { + validateActionButton(value); }, - position: { - type: DataTypes.STRING, - allowNull: false, - validate: { - isValidPosition(value) { - validatePositionWrapper(value); - }, - }, - }, - url: { - type: DataTypes.STRING, - allowNull: true, + }, + }, + position: { + type: DataTypes.STRING, + allowNull: false, + validate: { + isValidPosition(value) { + validatePositionWrapper(value); }, - fontColor: { - type: DataTypes.STRING, - allowNull: false, - defaultValue: "#FFFFFF", - validate: { - isHexColor(value) { - validateHexColor(value, 'fontColor'); - }, - }, + }, + }, + url: { + type: DataTypes.STRING, + allowNull: true, + }, + fontColor: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "#FFFFFF", + validate: { + isHexColor(value) { + validateHexColor(value, "fontColor"); }, - backgroundColor: { - type: DataTypes.STRING, - allowNull: false, - defaultValue: "#FFFFFF", - validate: { - isHexColor(value) { - validateHexColor(value, 'backgroundColor'); - }, - }, + }, + }, + backgroundColor: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "#FFFFFF", + validate: { + isHexColor(value) { + validateHexColor(value, "backgroundColor"); }, - bannerText: { - type: DataTypes.STRING, - allowNull: false, - defaultValue: "", + }, + }, + bannerText: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "", + }, + actionUrl: { + type: DataTypes.STRING, + validate: { + isUrl(value) { + try { + new URL(value); + } catch { + throw new Error("Invalid URL for actionUrl"); + } }, + }, + }, - createdBy: { - type: DataTypes.INTEGER, - allowNull: false, - references: { - model: "users", - key: "id", - }, + createdBy: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: "users", + key: "id", }, + }, }, - { - tableName: "banners", - timestamps: false, - }, - ); + { + tableName: "banners", + timestamps: false, + } + ); - Banner.associate = (models) => { - Banner.belongsTo(models.User, { foreignKey: "createdBy", as: "creator" }); - }; - return Banner; + Banner.associate = (models) => { + Banner.belongsTo(models.User, { foreignKey: "createdBy", as: "creator" }); + }; + return Banner; }; - diff --git a/backend/src/models/Popup.js b/backend/src/models/Popup.js index f1b9719f..0b0b9c68 100644 --- a/backend/src/models/Popup.js +++ b/backend/src/models/Popup.js @@ -1,5 +1,8 @@ -const { validateHexColor, validateActionButton } = require('../utils/guide.helper'); -const { validatePopupSizeWrapper } = require('../utils/popup.helper'); +const { + validateHexColor, + validateActionButton, +} = require("../utils/guide.helper"); +const { validatePopupSizeWrapper } = require("../utils/popup.helper"); module.exports = (sequelize, DataTypes) => { const Popup = sequelize.define( @@ -15,7 +18,7 @@ module.exports = (sequelize, DataTypes) => { allowNull: false, validate: { isValidAction(value) { - validateActionButton(value); + validateActionButton(value); }, }, }, @@ -24,7 +27,7 @@ module.exports = (sequelize, DataTypes) => { allowNull: false, validate: { isValidPopupSize(value) { - validatePopupSizeWrapper(value); + validatePopupSizeWrapper(value); }, }, }, @@ -42,7 +45,7 @@ module.exports = (sequelize, DataTypes) => { defaultValue: "#FFFFFF", validate: { isHexColor(value) { - validateHexColor(value, 'headerBackgroundColor'); + validateHexColor(value, "headerBackgroundColor"); }, }, }, @@ -52,7 +55,7 @@ module.exports = (sequelize, DataTypes) => { defaultValue: "#FFFFFF", validate: { isHexColor(value) { - validateHexColor(value, 'headerColor'); + validateHexColor(value, "headerColor"); }, }, }, @@ -62,7 +65,7 @@ module.exports = (sequelize, DataTypes) => { defaultValue: "#FFFFFF", validate: { isHexColor(value) { - validateHexColor(value, 'textColor'); + validateHexColor(value, "textColor"); }, }, }, @@ -72,7 +75,7 @@ module.exports = (sequelize, DataTypes) => { defaultValue: "#FFFFFF", validate: { isHexColor(value) { - validateHexColor(value, 'buttonBackgroundColor'); + validateHexColor(value, "buttonBackgroundColor"); }, }, }, @@ -82,7 +85,7 @@ module.exports = (sequelize, DataTypes) => { defaultValue: "#FFFFFF", validate: { isHexColor(value) { - validateHexColor(value, 'buttonTextColor'); + validateHexColor(value, "buttonTextColor"); }, }, }, @@ -96,6 +99,18 @@ module.exports = (sequelize, DataTypes) => { allowNull: false, defaultValue: "", }, + actionUrl: { + type: DataTypes.STRING, + validate: { + isUrl(value) { + try { + new URL(value); + } catch { + throw new Error("Invalid URL for actionUrl"); + } + }, + }, + }, createdBy: { type: DataTypes.INTEGER, allowNull: false, @@ -108,7 +123,7 @@ module.exports = (sequelize, DataTypes) => { { tableName: "popup", timestamps: false, - }, + } ); Popup.associate = (models) => { From af2615308b147e47a3ff7cc7b577a6080cfdd6ce Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Tue, 10 Dec 2024 15:25:55 -0800 Subject: [PATCH 35/66] feat: add migrations --- .../20241210225728-add-action-url-banner.js | 18 ++++++++++++++++++ .../20241210225734-add-action-url-popup.js | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 backend/migrations/20241210225728-add-action-url-banner.js create mode 100644 backend/migrations/20241210225734-add-action-url-popup.js diff --git a/backend/migrations/20241210225728-add-action-url-banner.js b/backend/migrations/20241210225728-add-action-url-banner.js new file mode 100644 index 00000000..949f5c67 --- /dev/null +++ b/backend/migrations/20241210225728-add-action-url-banner.js @@ -0,0 +1,18 @@ +"use strict"; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.addColumn("banners", "actionUrl", { + type: Sequelize.STRING, + allowNull: true, + validate: { + isUrl: true, + }, + }); + }, + + async down(queryInterface, Sequelize) { + await queryInterface.removeColumn("banners", "actionUrl"); + }, +}; diff --git a/backend/migrations/20241210225734-add-action-url-popup.js b/backend/migrations/20241210225734-add-action-url-popup.js new file mode 100644 index 00000000..cd07d11a --- /dev/null +++ b/backend/migrations/20241210225734-add-action-url-popup.js @@ -0,0 +1,18 @@ +"use strict"; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.addColumn("popup", "actionUrl", { + type: Sequelize.STRING, + allowNull: true, + validate: { + isUrl: true, + }, + }); + }, + + async down(queryInterface, Sequelize) { + await queryInterface.removeColumn("popup", "actionUrl"); + }, +}; From 23081e39398d6bf2c91b0d965d98bf4ec11ec68b Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Tue, 10 Dec 2024 15:31:25 -0800 Subject: [PATCH 36/66] feat: add validation on controller to actionUrl column --- backend/src/controllers/banner.controller.js | 20 +++- backend/src/controllers/popup.controller.js | 119 +++++++++++-------- 2 files changed, 88 insertions(+), 51 deletions(-) diff --git a/backend/src/controllers/banner.controller.js b/backend/src/controllers/banner.controller.js index ad6994c2..a1e7b3d8 100644 --- a/backend/src/controllers/banner.controller.js +++ b/backend/src/controllers/banner.controller.js @@ -7,7 +7,7 @@ const { checkColorFieldsFail } = require("../utils/guide.helper"); class BannerController { async addBanner(req, res) { const userId = req.user.id; - const { position, closeButtonAction, fontColor, backgroundColor } = req.body; + const { position, closeButtonAction, fontColor, backgroundColor, actionUrl } = req.body; if (!position || !closeButtonAction) { return res @@ -25,6 +25,14 @@ class BannerController { }); } + if (actionUrl) { + try { + new URL(actionUrl); + } catch (err) { + return res.status(400).json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + } + } + const colorFields = { fontColor, backgroundColor }; const colorCheck = checkColorFieldsFail(colorFields, res) if (colorCheck) { return colorCheck }; @@ -76,7 +84,7 @@ class BannerController { async editBanner(req, res) { try { const { id } = req.params; - const { fontColor, backgroundColor, url, position, closeButtonAction, bannerText } = req.body; + const { fontColor, backgroundColor, url, position, closeButtonAction, bannerText, actionUrl } = req.body; if (!position || !closeButtonAction) { return res @@ -98,6 +106,14 @@ class BannerController { .json({ errors: [{ msg: "Invalid value for closeButtonAction" }] }); } + if (actionUrl) { + try { + new URL(actionUrl); + } catch (err) { + return res.status(400).json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + } + } + const colorFields = { fontColor, backgroundColor }; const colorCheck = checkColorFieldsFail(colorFields, res) if (colorCheck) { return colorCheck }; diff --git a/backend/src/controllers/popup.controller.js b/backend/src/controllers/popup.controller.js index d1c6f050..6de38a13 100644 --- a/backend/src/controllers/popup.controller.js +++ b/backend/src/controllers/popup.controller.js @@ -1,8 +1,8 @@ const popupService = require("../service/popup.service"); const { internalServerError } = require("../utils/errors.helper"); -const {validateCloseButtonAction } = require("../utils/guide.helper"); +const { validateCloseButtonAction } = require("../utils/guide.helper"); const { validatePopupSize } = require("../utils/popup.helper"); -const { checkColorFieldsFail } =require("../utils/guide.helper"); +const { checkColorFieldsFail } = require("../utils/guide.helper"); class PopupController { async addPopup(req, res) { @@ -15,25 +15,32 @@ class PopupController { textColor, buttonBackgroundColor, buttonTextColor, + actionUrl, } = req.body; if (!popupSize || !closeButtonAction) { - return res - .status(400) - .json({ - errors: [{ msg: "popupSize and closeButtonAction are required" }], - }); + return res.status(400).json({ + errors: [{ msg: "popupSize and closeButtonAction are required" }], + }); } if ( !validatePopupSize(popupSize) || !validateCloseButtonAction(closeButtonAction) ) { - return res - .status(400) - .json({ - errors: [{ msg: "Invalid value for popupSize or closeButtonAction" }], - }); + return res.status(400).json({ + errors: [{ msg: "Invalid value for popupSize or closeButtonAction" }], + }); + } + + if (actionUrl) { + try { + new URL(actionUrl); + } catch (err) { + return res + .status(400) + .json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + } } const colorFields = { @@ -43,8 +50,10 @@ class PopupController { buttonBackgroundColor, buttonTextColor, }; - const colorCheck = checkColorFieldsFail(colorFields, res) - if(colorCheck){return colorCheck}; + const colorCheck = checkColorFieldsFail(colorFields, res); + if (colorCheck) { + return colorCheck; + } try { const newPopupData = { ...req.body, createdBy: userId }; @@ -54,7 +63,7 @@ class PopupController { console.log(err); const { statusCode, payload } = internalServerError( "CREATE_POPUP_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -64,18 +73,16 @@ class PopupController { try { const { id } = req.params; - if (Number.isNaN(Number(id)) || id.trim() === "") { + if (Number.isNaN(Number(id)) || id.trim() === "") { return res.status(400).json({ errors: [{ msg: "Invalid id" }] }); } const deletionResult = await popupService.deletePopup(id); if (!deletionResult) { - return res - .status(400) - .json({ - errors: [{ msg: "Popup with the specified id does not exist" }], - }); + return res.status(400).json({ + errors: [{ msg: "Popup with the specified id does not exist" }], + }); } res @@ -84,7 +91,7 @@ class PopupController { } catch (err) { const { statusCode, payload } = internalServerError( "DELETE_POPUP_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -93,14 +100,21 @@ class PopupController { async editPopup(req, res) { try { const { id } = req.params; - const { popupSize, closeButtonAction, headerBackgroundColor, headerColor, textColor, buttonBackgroundColor, buttonTextColor } = req.body; + const { + popupSize, + closeButtonAction, + headerBackgroundColor, + headerColor, + textColor, + buttonBackgroundColor, + buttonTextColor, + actionUrl, + } = req.body; if (!popupSize || !closeButtonAction) { - return res - .status(400) - .json({ - errors: [{ msg: "popupSize and closeButtonAction are required" }], - }); + return res.status(400).json({ + errors: [{ msg: "popupSize and closeButtonAction are required" }], + }); } if (!validatePopupSize(popupSize)) { @@ -115,6 +129,16 @@ class PopupController { .json({ errors: [{ msg: "Invalid value for closeButtonAction" }] }); } + if (actionUrl) { + try { + new URL(actionUrl); + } catch (err) { + return res + .status(400) + .json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + } + } + const colorFields = { headerBackgroundColor, headerColor, @@ -122,21 +146,22 @@ class PopupController { buttonBackgroundColor, buttonTextColor, }; - const colorCheck = checkColorFieldsFail(colorFields, res) - if(colorCheck){return colorCheck}; + const colorCheck = checkColorFieldsFail(colorFields, res); + if (colorCheck) { + return colorCheck; + } const updatedPopup = await popupService.updatePopup(id, req.body); res.status(200).json(updatedPopup); } catch (err) { const { statusCode, payload } = internalServerError( "EDIT_POPUP_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } } - async getAllPopups(req, res) { try { const popups = await popupService.getAllPopups(); @@ -144,7 +169,7 @@ class PopupController { } catch (err) { const { statusCode, payload } = internalServerError( "GET_ALL_POPUPS_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -158,7 +183,7 @@ class PopupController { } catch (err) { const { statusCode, payload } = internalServerError( "GET_POPUPS_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -168,23 +193,21 @@ class PopupController { try { const { id } = req.params; - if (Number.isNaN(Number(id)) || id.trim() === "") { + if (Number.isNaN(Number(id)) || id.trim() === "") { return res.status(400).json({ errors: [{ msg: "Invalid popup ID" }] }); } const popup = await popupService.getPopupById(id); if (!popup) { - return res - .status(404) - .json({ errors: [{ msg: "Popup not found" }] }); + return res.status(404).json({ errors: [{ msg: "Popup not found" }] }); } res.status(200).json(popup); } catch (err) { const { statusCode, payload } = internalServerError( "GET_POPUP_BY_ID_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -193,20 +216,18 @@ class PopupController { try { const { url } = req.body; - if (!url || typeof url !== 'string' ) { - return res.status(400).json({ errors: [{ msg: "URL is missing or invalid" }] }); + if (!url || typeof url !== "string") { + return res + .status(400) + .json({ errors: [{ msg: "URL is missing or invalid" }] }); } const popup = await popupService.getPopupByUrl(url); - res.status(200).json({popup}); + res.status(200).json({ popup }); } catch (error) { - internalServerError( - "GET_POPUP_BY_URL_ERROR", - error.message, - ); + internalServerError("GET_POPUP_BY_URL_ERROR", error.message); } - }; - + } } -module.exports = new PopupController(); \ No newline at end of file +module.exports = new PopupController(); From bf2b3b0cd45a4c3ad7bd9488677630ca3d36cb1e Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Fri, 13 Dec 2024 14:12:49 -0800 Subject: [PATCH 37/66] feat: add action url to banner in front --- .../BannerLeftContent/BannerLeftContent.jsx | 122 ++++++----- .../src/scenes/banner/CreateBannerPage.jsx | 196 ++++++++++-------- 2 files changed, 176 insertions(+), 142 deletions(-) diff --git a/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx b/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx index 79a336d6..4f54f01c 100644 --- a/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx +++ b/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx @@ -1,54 +1,74 @@ -import React from 'react'; -import styles from './BannerLeftContent.module.scss'; -import DropdownList from '@components/DropdownList/DropdownList'; -import CustomTextField from '@components/TextFieldComponents/CustomTextField/CustomTextField'; -import RadioButton from '@components/RadioButton/RadioButton'; - -const BannerLeftContent = ({ setIsTopPosition, url, setUrl, setButtonAction, isTopPosition, buttonAction }) => { - const handleSetUrl = (event) => { - setUrl(event.target.value); - }; - - const handleActionChange = (newAction) => { - setButtonAction(newAction); - }; - - const handlePositionChange = (newPosition) => { - setIsTopPosition(newPosition); - }; - - return ( -
-

Action

- -

Position

-
- handlePositionChange(true)} - /> -
-
- handlePositionChange(false)} - /> -
- -

URL

- -
- ); +import DropdownList from "@components/DropdownList/DropdownList"; +import RadioButton from "@components/RadioButton/RadioButton"; +import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; +import React from "react"; +import styles from "./BannerLeftContent.module.scss"; + +const BannerLeftContent = ({ + setIsTopPosition, + url, + setUrl, + setButtonAction, + isTopPosition, + buttonAction, + actionUrl, + setActionUrl, +}) => { + const handleSetUrl = (event) => { + setUrl(event.target.value); + }; + + const handleSetActionUrl = (event) => { + setActionUrl(event.target.value); + }; + + const handleActionChange = (newAction) => { + setButtonAction(newAction); + }; + + const handlePositionChange = (newPosition) => { + setIsTopPosition(newPosition); + }; + + return ( +
+

Action

+ +

Position

+
+ handlePositionChange(true)} + /> +
+
+ handlePositionChange(false)} + /> +
+ +

URL

+ + +

Action URL

+ +
+ ); }; export default BannerLeftContent; diff --git a/frontend/src/scenes/banner/CreateBannerPage.jsx b/frontend/src/scenes/banner/CreateBannerPage.jsx index 678717c9..154c4346 100644 --- a/frontend/src/scenes/banner/CreateBannerPage.jsx +++ b/frontend/src/scenes/banner/CreateBannerPage.jsx @@ -1,106 +1,120 @@ -import { React, useState, useEffect } from 'react'; -import GuideTemplate from '../../templates/GuideTemplate/GuideTemplate'; -import BannerLeftContent from './BannerPageComponents/BannerLeftContent/BannerLeftContent'; -import BannerLeftAppearance from './BannerPageComponents/BannerLeftAppearance/BannerLeftApperance'; -import BannerPreview from './BannerPageComponents/BannerPreview/BannerPreview'; -import { addBanner, getBannerById, editBanner } from '../../services/bannerServices'; -import { useNavigate, useLocation } from 'react-router-dom'; -import toastEmitter, { TOAST_EMITTER_KEY } from '../../utils/toastEmitter'; -import {emitToastError} from '../../utils/guideHelper' +import { React, useEffect, useState } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import { + addBanner, + editBanner, + getBannerById, +} from "../../services/bannerServices"; +import GuideTemplate from "../../templates/GuideTemplate/GuideTemplate"; +import { emitToastError } from "../../utils/guideHelper"; +import toastEmitter, { TOAST_EMITTER_KEY } from "../../utils/toastEmitter"; +import BannerLeftAppearance from "./BannerPageComponents/BannerLeftAppearance/BannerLeftApperance"; +import BannerLeftContent from "./BannerPageComponents/BannerLeftContent/BannerLeftContent"; +import BannerPreview from "./BannerPageComponents/BannerPreview/BannerPreview"; const BannerPage = () => { - const navigate = useNavigate(); - const location = useLocation(); + const navigate = useNavigate(); + const location = useLocation(); - const [backgroundColor, setBackgroundColor] = useState("#F9F5FF"); - const [fontColor, setFontColor] = useState("#344054"); - const [activeButton, setActiveButton] = useState(0); - const [isTopPosition, setIsTopPosition] = useState(true); - const [bannerText, setBannerText] = useState(''); - const [url, setUrl] = useState(''); - const [buttonAction, setButtonAction] = useState('No action'); + const [backgroundColor, setBackgroundColor] = useState("#F9F5FF"); + const [fontColor, setFontColor] = useState("#344054"); + const [activeButton, setActiveButton] = useState(0); + const [isTopPosition, setIsTopPosition] = useState(true); + const [bannerText, setBannerText] = useState(""); + const [url, setUrl] = useState(""); + const [actionUrl, setActionUrl] = useState(""); + const [buttonAction, setButtonAction] = useState("No action"); - const handleButtonClick = (index) => { - setActiveButton(index); - }; - - useEffect(() => { - if (location.state?.isEdit) { - const fetchBannerData = async () => { - try { - const bannerData = await getBannerById(location.state.id); - - // Update the state with the fetched data - setBackgroundColor(bannerData.backgroundColor || '#F9F5FF'); - setFontColor(bannerData.fontColor || '#344054'); - setBannerText(bannerData.bannerText || ''); - setUrl(bannerData.url || ''); - setButtonAction(bannerData.closeButtonAction || 'No action'); - setIsTopPosition(bannerData.position === 'top'); + const handleButtonClick = (index) => { + setActiveButton(index); + }; - console.log('Get banner successful:', bannerData); - } catch (error) { - emitToastError(error) - } - }; + useEffect(() => { + if (location.state?.isEdit) { + const fetchBannerData = async () => { + try { + const bannerData = await getBannerById(location.state.id); - fetchBannerData(); - } - }, [location.state]); + // Update the state with the fetched data + setBackgroundColor(bannerData.backgroundColor || "#F9F5FF"); + setFontColor(bannerData.fontColor || "#344054"); + setBannerText(bannerData.bannerText || ""); + setUrl(bannerData.url || ""); + setActionUrl(bannerData.actionUrl || ""); + setButtonAction(bannerData.closeButtonAction || "No action"); + setIsTopPosition(bannerData.position === "top"); - const onSave = async () => { - const bannerData = { - backgroundColor: backgroundColor, - fontColor: fontColor, - url: url, - position: isTopPosition ? 'top' : 'bottom', - closeButtonAction: buttonAction.toLowerCase(), - bannerText: bannerText - }; - try { - const response = location.state?.isEdit - ? await editBanner(location.state?.id, bannerData) - : await addBanner(bannerData); - const toastMessage = location.state?.isEdit ? 'You edited this banner' : 'New banner saved' - toastEmitter.emit(TOAST_EMITTER_KEY, toastMessage); - navigate('/banner'); + console.log("Get banner successful:", bannerData); } catch (error) { - emitToastError(error) + emitToastError(error); } + }; + + fetchBannerData(); } + }, [location.state]); - return ( + const onSave = async () => { + const bannerData = { + backgroundColor, + fontColor, + url, + actionUrl, + position: isTopPosition ? "top" : "bottom", + closeButtonAction: buttonAction.toLowerCase(), + bannerText, + }; + try { + const response = location.state?.isEdit + ? await editBanner(location.state?.id, bannerData) + : await addBanner(bannerData); + const toastMessage = location.state?.isEdit + ? "You edited this banner" + : "New banner saved"; + toastEmitter.emit(TOAST_EMITTER_KEY, toastMessage); + navigate("/banner"); + } catch (error) { + emitToastError(error); + } + }; - - } - leftContent={() => - } - leftAppearance={() => ( - - )} /> - ); + return ( + ( + + )} + leftContent={() => ( + + )} + leftAppearance={() => ( + + )} + /> + ); }; export default BannerPage; From a14f07a4a77d15fab4056458486d57887be9665f Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Fri, 13 Dec 2024 14:25:40 -0800 Subject: [PATCH 38/66] feat: add action url to popup front --- frontend/src/scenes/popup/CreatePopupPage.jsx | 283 ++++++++++-------- .../PopupContent/PopupContent.jsx | 86 ++++-- 2 files changed, 216 insertions(+), 153 deletions(-) diff --git a/frontend/src/scenes/popup/CreatePopupPage.jsx b/frontend/src/scenes/popup/CreatePopupPage.jsx index cde5ec25..4397d891 100644 --- a/frontend/src/scenes/popup/CreatePopupPage.jsx +++ b/frontend/src/scenes/popup/CreatePopupPage.jsx @@ -1,140 +1,181 @@ -import React, { useState, useEffect } from 'react'; -import { useNavigate, useLocation } from 'react-router-dom'; -import GuideTemplate from '../../templates/GuideTemplate/GuideTemplate'; -import RichTextEditor from '@components/RichTextEditor/RichTextEditor'; -import PopupAppearance from './PopupPageComponents/PopupAppearance/PopupAppearance'; -import PopupContent from './PopupPageComponents/PopupContent/PopupContent'; -import { addPopup, getPopupById, editPopup } from '../../services/popupServices'; -import toastEmitter, { TOAST_EMITTER_KEY } from '../../utils/toastEmitter'; -import { emitToastError } from '../../utils/guideHelper'; +import RichTextEditor from "@components/RichTextEditor/RichTextEditor"; +import React, { useEffect, useState } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import { + addPopup, + editPopup, + getPopupById, +} from "../../services/popupServices"; +import GuideTemplate from "../../templates/GuideTemplate/GuideTemplate"; +import { emitToastError } from "../../utils/guideHelper"; +import toastEmitter, { TOAST_EMITTER_KEY } from "../../utils/toastEmitter"; +import PopupAppearance from "./PopupPageComponents/PopupAppearance/PopupAppearance"; +import PopupContent from "./PopupPageComponents/PopupContent/PopupContent"; const CreatePopupPage = () => { - const navigate = useNavigate(); - const location = useLocation(); + const navigate = useNavigate(); + const location = useLocation(); - const [activeButton, setActiveButton] = useState(0); + const [activeButton, setActiveButton] = useState(0); - const [headerBackgroundColor, setHeaderBackgroundColor] = useState('#F8F9F8'); - const [headerColor, setHeaderColor] = useState('#101828'); - const [textColor, setTextColor] = useState('#344054'); - const [buttonBackgroundColor, setButtonBackgroundColor] = useState('#7F56D9'); - const [buttonTextColor, setButtonTextColor] = useState('#FFFFFF'); + const [headerBackgroundColor, setHeaderBackgroundColor] = useState("#F8F9F8"); + const [headerColor, setHeaderColor] = useState("#101828"); + const [textColor, setTextColor] = useState("#344054"); + const [buttonBackgroundColor, setButtonBackgroundColor] = useState("#7F56D9"); + const [buttonTextColor, setButtonTextColor] = useState("#FFFFFF"); - const [header, setHeader] = useState(''); - const [content, setContent] = useState(''); + const [header, setHeader] = useState(""); + const [content, setContent] = useState(""); - const [actionButtonUrl, setActionButtonUrl] = useState("https://"); - const [actionButtonText, setActionButtonText] = useState("Take me to subscription page"); - const [buttonAction, setButtonAction] = useState('No action'); - const [popupSize, setPopupSize] = useState('Small'); + const [actionButtonUrl, setActionButtonUrl] = useState("https://"); + const [url, setUrl] = useState("https://"); + const [actionButtonText, setActionButtonText] = useState( + "Take me to subscription page" + ); + const [buttonAction, setButtonAction] = useState("No action"); + const [popupSize, setPopupSize] = useState("Small"); - const stateList = [ - { stateName: 'Header Background Color', state: headerBackgroundColor, setState: setHeaderBackgroundColor }, - { stateName: 'Header Color', state: headerColor, setState: setHeaderColor }, - { stateName: 'Text Color', state: textColor, setState: setTextColor }, - { stateName: 'Button Background Color', state: buttonBackgroundColor, setState: setButtonBackgroundColor }, - { stateName: 'Button Text Color', state: buttonTextColor, setState: setButtonTextColor }, - ]; - - useEffect(() => { - if (location.state?.isEdit) { - const fetchPopupData = async () => { - try { - const popupData = await getPopupById(location.state.id); - - // Update the state with the fetched data - setHeaderBackgroundColor(popupData.headerBackgroundColor || '#F8F9F8'); - setHeaderColor(popupData.headerColor || '#101828'); - setTextColor(popupData.textColor || '#344054'); - setButtonBackgroundColor(popupData.buttonBackgroundColor || '#7F56D9'); - setButtonTextColor(popupData.buttonTextColor || '#FFFFFF'); - setHeader(popupData.header || ''); - setContent(popupData.content || ''); - setActionButtonUrl(popupData.url || 'https://'); - setActionButtonText(popupData.actionButtonText || 'Take me to subscription page'); - setButtonAction(popupData.closeButtonAction || 'No action'); - setPopupSize(popupData.popupSize || 'Small'); - } catch (error) { - emitToastError(error); - } - }; - - fetchPopupData(); - } - }, [location.state]); + const stateList = [ + { + stateName: "Header Background Color", + state: headerBackgroundColor, + setState: setHeaderBackgroundColor, + }, + { stateName: "Header Color", state: headerColor, setState: setHeaderColor }, + { stateName: "Text Color", state: textColor, setState: setTextColor }, + { + stateName: "Button Background Color", + state: buttonBackgroundColor, + setState: setButtonBackgroundColor, + }, + { + stateName: "Button Text Color", + state: buttonTextColor, + setState: setButtonTextColor, + } + ]; - const onSave = async () => { - const popupData = { - popupSize: popupSize.toLowerCase(), - url: actionButtonUrl, - actionButtonText: actionButtonText, - headerBackgroundColor: headerBackgroundColor, - headerColor: headerColor, - textColor: textColor, - buttonBackgroundColor: buttonBackgroundColor, - buttonTextColor: buttonTextColor, - closeButtonAction: buttonAction.toLowerCase(), - header: header, - content: content - }; + useEffect(() => { + if (location.state?.isEdit) { + const fetchPopupData = async () => { try { - const response = location.state?.isEdit - ? await editPopup(location.state?.id, popupData) - : await addPopup(popupData); - - const toastMessage = location.state?.isEdit ? 'You edited this popup' : 'New popup Saved' + const popupData = await getPopupById(location.state.id); - toastEmitter.emit(TOAST_EMITTER_KEY, toastMessage) - navigate('/popup'); + // Update the state with the fetched data + setHeaderBackgroundColor( + popupData.headerBackgroundColor || "#F8F9F8" + ); + setHeaderColor(popupData.headerColor || "#101828"); + setTextColor(popupData.textColor || "#344054"); + setButtonBackgroundColor( + popupData.buttonBackgroundColor || "#7F56D9" + ); + setButtonTextColor(popupData.buttonTextColor || "#FFFFFF"); + setHeader(popupData.header || ""); + setContent(popupData.content || ""); + setActionButtonUrl(popupData.actionUrl || "https://"); + setUrl(popupData.url || "https://"); + setActionButtonText( + popupData.actionButtonText || "Take me to subscription page" + ); + setButtonAction(popupData.closeButtonAction || "No action"); + setPopupSize(popupData.popupSize || "Small"); } catch (error) { - const errorMessage = error.response?.data?.message - ? `Error: ${error.response.data.message}` - : 'An unexpected error occurred. Please try again.'; - toastEmitter.emit(TOAST_EMITTER_KEY, errorMessage); + emitToastError(error); } + }; + + fetchPopupData(); } + }, [location.state]); - const handleButtonClick = (index) => { - setActiveButton(index); + const onSave = async () => { + const popupData = { + popupSize: popupSize.toLowerCase(), + url, + actionUrl: actionButtonUrl, + actionButtonText, + headerBackgroundColor, + headerColor, + textColor, + buttonBackgroundColor, + buttonTextColor, + closeButtonAction: buttonAction.toLowerCase(), + header, + content, }; + try { + const response = location.state?.isEdit + ? await editPopup(location.state?.id, popupData) + : await addPopup(popupData); + + console.log(response); + const toastMessage = location.state?.isEdit + ? "You edited this popup" + : "New popup Saved"; + + toastEmitter.emit(TOAST_EMITTER_KEY, toastMessage); + navigate("/popup"); + } catch (error) { + const errorMessage = error.response?.data?.message + ? `Error: ${error.response.data.message}` + : "An unexpected error occurred. Please try again."; + toastEmitter.emit(TOAST_EMITTER_KEY, errorMessage); + } + }; + + const handleButtonClick = (index) => { + setActiveButton(index); + }; - return ( - - } - leftContent={() => - } - leftAppearance={() => ( - - )} /> - ); + return ( + ( + + )} + leftContent={() => ( + + )} + leftAppearance={() => ( + + )} + /> + ); }; export default CreatePopupPage; diff --git a/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx b/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx index a63923d6..4d2b2a4c 100644 --- a/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx +++ b/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx @@ -1,36 +1,58 @@ -import { React } from 'react'; -import styles from './PopupContent.module.scss'; -import DropdownList from '@components/DropdownList/DropdownList'; -import CustomTextField from '@components/TextFieldComponents/CustomTextField/CustomTextField'; +import DropdownList from "@components/DropdownList/DropdownList"; +import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; +import { React } from "react"; +import styles from "./PopupContent.module.scss"; -const PopupContent = ({ actionButtonText, setActionButtonText, setActionButtonUrl, buttonAction, actionButtonUrl, setButtonAction }) => { - const handleActionButtonText = (event) => { - setActionButtonText(event.target.value); - }; - const handleActionButtonUrl = (event) => { - setActionButtonUrl(event.target.value); - }; - const handleActionChange = (newAction) => { - setButtonAction(newAction); - }; - return ( -
-

Action

- -

Action button url (can be relative)

- -

Action button text

- -
- ); +const PopupContent = ({ + actionButtonText, + setActionButtonText, + setActionButtonUrl, + buttonAction, + actionButtonUrl, + setButtonAction, + url, + setUrl, +}) => { + const handleActionButtonText = (event) => { + setActionButtonText(event.target.value); + }; + const handleActionButtonUrl = (event) => { + setActionButtonUrl(event.target.value); + }; + const handleActionChange = (newAction) => { + setButtonAction(newAction); + }; + const handleUrlChange = (event) => { + setUrl(event.target.value); + }; + return ( +
+

Action

+ +

URL

+ +

Action button URL (can be relative)

+ +

Action button text

+ +
+ ); }; export default PopupContent; From 1e877549e28737aa540746f6a13787ef2cb4e652 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:06:28 -0800 Subject: [PATCH 39/66] chore: add proptypes to banner and popup content --- .../BannerLeftContent/BannerLeftContent.jsx | 11 +++++++++++ .../PopupPageComponents/PopupContent/PopupContent.jsx | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx b/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx index 4f54f01c..600d083c 100644 --- a/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx +++ b/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx @@ -1,6 +1,7 @@ import DropdownList from "@components/DropdownList/DropdownList"; import RadioButton from "@components/RadioButton/RadioButton"; import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; +import PropTypes from "prop-types"; import React from "react"; import styles from "./BannerLeftContent.module.scss"; @@ -72,3 +73,13 @@ const BannerLeftContent = ({ }; export default BannerLeftContent; +BannerLeftContent.propTypes = { + setIsTopPosition: PropTypes.func, + url: PropTypes.string, + setUrl: PropTypes.func, + setButtonAction: PropTypes.func, + isTopPosition: PropTypes.bool, + buttonAction: PropTypes.string, + actionUrl: PropTypes.string, + setActionUrl: PropTypes.func, +}; diff --git a/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx b/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx index 4d2b2a4c..18a04e31 100644 --- a/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx +++ b/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx @@ -2,6 +2,7 @@ import DropdownList from "@components/DropdownList/DropdownList"; import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; import { React } from "react"; import styles from "./PopupContent.module.scss"; +import PropTypes from "prop-types"; const PopupContent = ({ actionButtonText, @@ -56,3 +57,13 @@ const PopupContent = ({ }; export default PopupContent; +PopupContent.propTypes = { + actionButtonText: PropTypes.string, + setActionButtonText: PropTypes.func, + setActionButtonUrl: PropTypes.func, + buttonAction: PropTypes.string, + actionButtonUrl: PropTypes.string, + setButtonAction: PropTypes.func, + url: PropTypes.string, + setUrl: PropTypes.func, +} From 75db22810d33190f256e564f788cd2cd8fd73cb8 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:09:42 -0800 Subject: [PATCH 40/66] chore: improve url validation on model --- backend/src/models/Banner.js | 17 +++++++++++------ backend/src/models/Popup.js | 17 +++++++++++------ backend/src/utils/banner.helper.js | 24 ++++++++++++++++++------ backend/src/utils/popup.helper.js | 15 +++++++++++++-- 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/backend/src/models/Banner.js b/backend/src/models/Banner.js index fb021833..5e1aa55d 100644 --- a/backend/src/models/Banner.js +++ b/backend/src/models/Banner.js @@ -2,7 +2,10 @@ const { validateHexColor, validateActionButton, } = require("../utils/guide.helper"); -const { validatePositionWrapper } = require("../utils/banner.helper"); +const { + validatePositionWrapper, + validateUrl, +} = require("../utils/banner.helper"); module.exports = (sequelize, DataTypes) => { const Banner = sequelize.define( @@ -29,6 +32,11 @@ module.exports = (sequelize, DataTypes) => { url: { type: DataTypes.STRING, allowNull: true, + validate: { + isUrl(value) { + validateUrl(value, "url"); + }, + }, }, fontColor: { type: DataTypes.STRING, @@ -57,13 +65,10 @@ module.exports = (sequelize, DataTypes) => { }, actionUrl: { type: DataTypes.STRING, + allowNull: true, validate: { isUrl(value) { - try { - new URL(value); - } catch { - throw new Error("Invalid URL for actionUrl"); - } + validateUrl(value, "actionUrl"); }, }, }, diff --git a/backend/src/models/Popup.js b/backend/src/models/Popup.js index 0b0b9c68..084758e5 100644 --- a/backend/src/models/Popup.js +++ b/backend/src/models/Popup.js @@ -2,7 +2,10 @@ const { validateHexColor, validateActionButton, } = require("../utils/guide.helper"); -const { validatePopupSizeWrapper } = require("../utils/popup.helper"); +const { + validatePopupSizeWrapper, + validateUrl, +} = require("../utils/popup.helper"); module.exports = (sequelize, DataTypes) => { const Popup = sequelize.define( @@ -34,6 +37,11 @@ module.exports = (sequelize, DataTypes) => { url: { type: DataTypes.STRING, allowNull: true, + validate: { + isUrl(value) { + validateUrl(value, "url"); + }, + }, }, actionButtonText: { type: DataTypes.STRING, @@ -101,13 +109,10 @@ module.exports = (sequelize, DataTypes) => { }, actionUrl: { type: DataTypes.STRING, + allowNull: true, validate: { isUrl(value) { - try { - new URL(value); - } catch { - throw new Error("Invalid URL for actionUrl"); - } + validateUrl(value, "actionUrl"); }, }, }, diff --git a/backend/src/utils/banner.helper.js b/backend/src/utils/banner.helper.js index 5c23eb8c..d217af73 100644 --- a/backend/src/utils/banner.helper.js +++ b/backend/src/utils/banner.helper.js @@ -5,12 +5,24 @@ const validatePosition = (value) => { const validatePositionWrapper = (value) => { if (!validatePosition(value)) { - throw new Error('Invalid position'); + throw new Error("Invalid position"); } }; - - module.exports = { - validatePosition, - validatePositionWrapper - }; \ No newline at end of file +const validateUrl = (value, fieldName) => { + if (!value) return; + try { + const url = new URL(value); + if (!["http:", "https:"].includes(url.protocol)) { + throw new Error("URL must use HTTP or HTTPS protocol"); + } + } catch (error) { + throw new Error(`Invalid URL for ${fieldName}: ${error.message}`); + } +}; + +module.exports = { + validatePosition, + validatePositionWrapper, + validateUrl, +}; diff --git a/backend/src/utils/popup.helper.js b/backend/src/utils/popup.helper.js index 41d258a8..e285d3eb 100644 --- a/backend/src/utils/popup.helper.js +++ b/backend/src/utils/popup.helper.js @@ -9,9 +9,20 @@ const validatePopupSizeWrapper = (value) => { } }; - +const validateUrl = (value, fieldName) => { + if (!value) return; + try { + const url = new URL(value); + if (!['http:', 'https:'].includes(url.protocol)) { + throw new Error('URL must use HTTP or HTTPS protocol'); + } + } catch (error) { + throw new Error(`Invalid URL for ${fieldName}: ${error.message}`); + } +}; module.exports = { validatePopupSize, - validatePopupSizeWrapper + validatePopupSizeWrapper, + validateUrl, }; From 09e76c96d218fa19082e94ef833fad34cbd097eb Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:14:26 -0800 Subject: [PATCH 41/66] chore: improve url validation on front --- .../src/scenes/banner/CreateBannerPage.jsx | 24 +++++++++++++++++ frontend/src/scenes/popup/CreatePopupPage.jsx | 27 +++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/frontend/src/scenes/banner/CreateBannerPage.jsx b/frontend/src/scenes/banner/CreateBannerPage.jsx index 154c4346..59ad75fd 100644 --- a/frontend/src/scenes/banner/CreateBannerPage.jsx +++ b/frontend/src/scenes/banner/CreateBannerPage.jsx @@ -54,7 +54,31 @@ const BannerPage = () => { } }, [location.state]); + const validateUrl = (url) => { + try { + new URL(url); + return null; + } catch (err) { + return "Invalid URL format"; + } + }; + const onSave = async () => { + if (actionUrl && actionUrl !== "https://") { + const urlError = validateUrl(actionUrl); + if (urlError) { + emitToastError(urlError); + return; + } + } + if (url && url !== "https://") { + const urlError = validateUrl(url); + if (urlError) { + emitToastError(urlError); + return; + } + } + const bannerData = { backgroundColor, fontColor, diff --git a/frontend/src/scenes/popup/CreatePopupPage.jsx b/frontend/src/scenes/popup/CreatePopupPage.jsx index 4397d891..ad66f853 100644 --- a/frontend/src/scenes/popup/CreatePopupPage.jsx +++ b/frontend/src/scenes/popup/CreatePopupPage.jsx @@ -52,7 +52,7 @@ const CreatePopupPage = () => { stateName: "Button Text Color", state: buttonTextColor, setState: setButtonTextColor, - } + }, ]; useEffect(() => { @@ -89,7 +89,30 @@ const CreatePopupPage = () => { } }, [location.state]); + const validateUrl = (url) => { + try { + new URL(url); + return null; + } catch (err) { + return "Invalid URL format"; + } + }; + const onSave = async () => { + if (actionButtonUrl && actionButtonUrl !== "https://") { + const urlError = validateUrl(actionButtonUrl); + if (urlError) { + emitToastError(urlError); + return; + } + } + if (url && url !== "https://") { + const urlError = validateUrl(url); + if (urlError) { + emitToastError(urlError); + return; + } + } const popupData = { popupSize: popupSize.toLowerCase(), url, @@ -109,7 +132,7 @@ const CreatePopupPage = () => { ? await editPopup(location.state?.id, popupData) : await addPopup(popupData); - console.log(response); + console.log(response); const toastMessage = location.state?.isEdit ? "You edited this popup" : "New popup Saved"; From 7ce60bafd425eb214130280a2be769a811cdca72 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:18:25 -0800 Subject: [PATCH 42/66] chore: improve url validation on controller --- backend/src/controllers/banner.controller.js | 123 ++++++++++++------- backend/src/controllers/popup.controller.js | 32 +++-- 2 files changed, 99 insertions(+), 56 deletions(-) diff --git a/backend/src/controllers/banner.controller.js b/backend/src/controllers/banner.controller.js index a1e7b3d8..8eba6290 100644 --- a/backend/src/controllers/banner.controller.js +++ b/backend/src/controllers/banner.controller.js @@ -1,41 +1,57 @@ const bannerService = require("../service/banner.service.js"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { validatePosition } = require("../utils/banner.helper"); +const { validatePosition, validateUrl } = require("../utils/banner.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class BannerController { async addBanner(req, res) { const userId = req.user.id; - const { position, closeButtonAction, fontColor, backgroundColor, actionUrl } = req.body; + const { + position, + closeButtonAction, + fontColor, + backgroundColor, + actionUrl, + url, + } = req.body; if (!position || !closeButtonAction) { - return res - .status(400) - .json({ - errors: [{ msg: "position and closeButtonAction are required" }], - }); + return res.status(400).json({ + errors: [{ msg: "position and closeButtonAction are required" }], + }); } - if (!validatePosition(position) || !validateCloseButtonAction(closeButtonAction)) { - return res - .status(400) - .json({ - errors: [{ msg: "Invalid value entered" }], - }); + if ( + !validatePosition(position) || + !validateCloseButtonAction(closeButtonAction) + ) { + return res.status(400).json({ + errors: [{ msg: "Invalid value entered" }], + }); } if (actionUrl) { try { - new URL(actionUrl); + validateUrl(actionUrl, "actionUrl"); } catch (err) { - return res.status(400).json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + return res.status(400).json({ errors: [{ msg: err.message }] }); + } + } + + if (url) { + try { + validateUrl(url, "url"); + } catch (err) { + return res.status(400).json({ errors: [{ msg: err.message }] }); } } const colorFields = { fontColor, backgroundColor }; - const colorCheck = checkColorFieldsFail(colorFields, res) - if (colorCheck) { return colorCheck }; + const colorCheck = checkColorFieldsFail(colorFields, res); + if (colorCheck) { + return colorCheck; + } try { const newBannerData = { ...req.body, createdBy: userId }; @@ -45,7 +61,7 @@ class BannerController { console.log(err); const { statusCode, payload } = internalServerError( "CREATE_BANNER_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -62,11 +78,9 @@ class BannerController { const deletionResult = await bannerService.deleteBanner(id); if (!deletionResult) { - return res - .status(400) - .json({ - errors: [{ msg: "Banner with the specified id does not exist" }], - }); + return res.status(400).json({ + errors: [{ msg: "Banner with the specified id does not exist" }], + }); } res @@ -75,7 +89,7 @@ class BannerController { } catch (err) { const { statusCode, payload } = internalServerError( "DELETE_BANNER_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -84,14 +98,20 @@ class BannerController { async editBanner(req, res) { try { const { id } = req.params; - const { fontColor, backgroundColor, url, position, closeButtonAction, bannerText, actionUrl } = req.body; + const { + fontColor, + backgroundColor, + url, + position, + closeButtonAction, + bannerText, + actionUrl, + } = req.body; if (!position || !closeButtonAction) { - return res - .status(400) - .json({ - errors: [{ msg: "position and closeButtonAction are required" }], - }); + return res.status(400).json({ + errors: [{ msg: "position and closeButtonAction are required" }], + }); } if (!validatePosition(position)) { @@ -108,22 +128,32 @@ class BannerController { if (actionUrl) { try { - new URL(actionUrl); + validateUrl(actionUrl, "actionUrl"); } catch (err) { - return res.status(400).json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + return res.status(400).json({ errors: [{ msg: err.message }] }); + } + } + + if (url) { + try { + validateUrl(url, "url"); + } catch (err) { + return res.status(400).json({ errors: [{ msg: err.message }] }); } } const colorFields = { fontColor, backgroundColor }; - const colorCheck = checkColorFieldsFail(colorFields, res) - if (colorCheck) { return colorCheck }; + const colorCheck = checkColorFieldsFail(colorFields, res); + if (colorCheck) { + return colorCheck; + } const updatedBanner = await bannerService.updateBanner(id, req.body); res.status(200).json(updatedBanner); } catch (err) { const { statusCode, payload } = internalServerError( "EDIT_BANNER_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -136,7 +166,7 @@ class BannerController { } catch (err) { const { statusCode, payload } = internalServerError( "GET_ALL_BANNERS_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -149,8 +179,8 @@ class BannerController { res.status(200).json(banners); } catch (err) { const { statusCode, payload } = internalServerError( - "GET\_BANNERS_ERROR", - err.message, + "GET_BANNERS_ERROR", + err.message ); res.status(statusCode).json(payload); } @@ -174,7 +204,7 @@ class BannerController { } catch (err) { const { statusCode, payload } = internalServerError( "GET_BANNER_BY_ID_ERROR", - err.message, + err.message ); res.status(statusCode).json(payload); } @@ -183,19 +213,18 @@ class BannerController { try { const { url } = req.body; - if (!url || typeof url !== 'string' ) { - return res.status(400).json({ errors: [{ msg: "URL is missing or invalid" }] }); + if (!url || typeof url !== "string") { + return res + .status(400) + .json({ errors: [{ msg: "URL is missing or invalid" }] }); } const banner = await bannerService.getBannerByUrl(url); - res.status(200).json({banner}); + res.status(200).json({ banner }); } catch (error) { - internalServerError( - "GET_BANNER_BY_URL_ERROR", - error.message, - ); + internalServerError("GET_BANNER_BY_URL_ERROR", error.message); } - }; + } } module.exports = new BannerController(); diff --git a/backend/src/controllers/popup.controller.js b/backend/src/controllers/popup.controller.js index 6de38a13..09640664 100644 --- a/backend/src/controllers/popup.controller.js +++ b/backend/src/controllers/popup.controller.js @@ -1,7 +1,7 @@ const popupService = require("../service/popup.service"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { validatePopupSize } = require("../utils/popup.helper"); +const { validatePopupSize, validateUrl } = require("../utils/popup.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class PopupController { @@ -16,6 +16,7 @@ class PopupController { buttonBackgroundColor, buttonTextColor, actionUrl, + url, } = req.body; if (!popupSize || !closeButtonAction) { @@ -35,11 +36,17 @@ class PopupController { if (actionUrl) { try { - new URL(actionUrl); + validateUrl(actionUrl, "actionUrl"); } catch (err) { - return res - .status(400) - .json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + return res.status(400).json({ errors: [{ msg: err.message }] }); + } + } + + if (url) { + try { + validateUrl(url, "url"); + } catch (err) { + return res.status(400).json({ errors: [{ msg: err.message }] }); } } @@ -109,6 +116,7 @@ class PopupController { buttonBackgroundColor, buttonTextColor, actionUrl, + url, } = req.body; if (!popupSize || !closeButtonAction) { @@ -131,11 +139,17 @@ class PopupController { if (actionUrl) { try { - new URL(actionUrl); + validateUrl(actionUrl, "actionUrl"); + } catch (err) { + return res.status(400).json({ errors: [{ msg: err.message }] }); + } + } + + if (url) { + try { + validateUrl(url, "url"); } catch (err) { - return res - .status(400) - .json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + return res.status(400).json({ errors: [{ msg: err.message }] }); } } From 5d11055d1fabaf08bfe6fb847f7221c07eb9188c Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:19:53 -0800 Subject: [PATCH 43/66] fix: fix error return on popup --- backend/src/controllers/popup.controller.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/src/controllers/popup.controller.js b/backend/src/controllers/popup.controller.js index 09640664..5ece1c11 100644 --- a/backend/src/controllers/popup.controller.js +++ b/backend/src/controllers/popup.controller.js @@ -239,7 +239,11 @@ class PopupController { const popup = await popupService.getPopupByUrl(url); res.status(200).json({ popup }); } catch (error) { - internalServerError("GET_POPUP_BY_URL_ERROR", error.message); + const { payload, statusCode } = internalServerError( + "GET_POPUP_BY_URL_ERROR", + error.message + ); + res.status(statusCode).json(payload); } } } From 47defaa5f99c0349291d37bc0c388e6b8ebbc592 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:20:36 -0800 Subject: [PATCH 44/66] chore: remove console log from popup front --- frontend/src/scenes/popup/CreatePopupPage.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/scenes/popup/CreatePopupPage.jsx b/frontend/src/scenes/popup/CreatePopupPage.jsx index ad66f853..5d68f3ac 100644 --- a/frontend/src/scenes/popup/CreatePopupPage.jsx +++ b/frontend/src/scenes/popup/CreatePopupPage.jsx @@ -132,7 +132,6 @@ const CreatePopupPage = () => { ? await editPopup(location.state?.id, popupData) : await addPopup(popupData); - console.log(response); const toastMessage = location.state?.isEdit ? "You edited this popup" : "New popup Saved"; From 9a9c734ccdbb5f443f3ebb42b60766f179972637 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:45:32 -0800 Subject: [PATCH 45/66] test: fix test on front --- frontend/src/tests/scenes/popup/CreatePopupPage.test.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/tests/scenes/popup/CreatePopupPage.test.jsx b/frontend/src/tests/scenes/popup/CreatePopupPage.test.jsx index e5d86b09..726de2b6 100644 --- a/frontend/src/tests/scenes/popup/CreatePopupPage.test.jsx +++ b/frontend/src/tests/scenes/popup/CreatePopupPage.test.jsx @@ -105,7 +105,7 @@ describe('CreatePopupPage component', () => { // Check initial state of form fields const headerBackgroundColor = screen.getByDisplayValue('No action'); - const headerColor = screen.getByDisplayValue('https://'); + const headerColor = screen.getAllByDisplayValue('https://')[0]; expect(headerBackgroundColor).not.toBeNull(); // Example for headerBackgroundColor expect(headerColor).not.toBeNull(); // Example for headerColor From ceec1e9d6ecb70f68b0a3980ef18ec012c91d704 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 11:56:22 -0800 Subject: [PATCH 46/66] test: fix test on back --- backend/src/controllers/banner.controller.js | 11 +++++++---- backend/src/controllers/popup.controller.js | 13 +++++++++---- backend/src/models/Banner.js | 3 ++- backend/src/models/Popup.js | 3 ++- backend/src/test/mocks/banner.mock.js | 1 + backend/src/test/mocks/popup.mock.js | 1 + backend/src/test/unit/controllers/popup.test.js | 1 + backend/src/utils/banner.helper.js | 13 +++++++++++++ backend/src/utils/popup.helper.js | 13 +++++++++++++ 9 files changed, 49 insertions(+), 10 deletions(-) diff --git a/backend/src/controllers/banner.controller.js b/backend/src/controllers/banner.controller.js index 8eba6290..4afcec14 100644 --- a/backend/src/controllers/banner.controller.js +++ b/backend/src/controllers/banner.controller.js @@ -1,7 +1,11 @@ const bannerService = require("../service/banner.service.js"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { validatePosition, validateUrl } = require("../utils/banner.helper"); +const { + validatePosition, + validateUrl, + validateRelativeUrl, +} = require("../utils/banner.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class BannerController { @@ -41,7 +45,7 @@ class BannerController { if (url) { try { - validateUrl(url, "url"); + validateRelativeUrl(url, "url"); } catch (err) { return res.status(400).json({ errors: [{ msg: err.message }] }); } @@ -104,7 +108,6 @@ class BannerController { url, position, closeButtonAction, - bannerText, actionUrl, } = req.body; @@ -136,7 +139,7 @@ class BannerController { if (url) { try { - validateUrl(url, "url"); + validateRelativeUrl(url, "url"); } catch (err) { return res.status(400).json({ errors: [{ msg: err.message }] }); } diff --git a/backend/src/controllers/popup.controller.js b/backend/src/controllers/popup.controller.js index 5ece1c11..0a566696 100644 --- a/backend/src/controllers/popup.controller.js +++ b/backend/src/controllers/popup.controller.js @@ -1,7 +1,11 @@ const popupService = require("../service/popup.service"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { validatePopupSize, validateUrl } = require("../utils/popup.helper"); +const { + validatePopupSize, + validateUrl, + validateRelativeUrl, +} = require("../utils/popup.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class PopupController { @@ -41,15 +45,16 @@ class PopupController { return res.status(400).json({ errors: [{ msg: err.message }] }); } } - + if (url) { try { - validateUrl(url, "url"); + validateRelativeUrl(url, "url"); } catch (err) { return res.status(400).json({ errors: [{ msg: err.message }] }); } } + const colorFields = { headerBackgroundColor, headerColor, @@ -147,7 +152,7 @@ class PopupController { if (url) { try { - validateUrl(url, "url"); + validateRelativeUrl(url, "url"); } catch (err) { return res.status(400).json({ errors: [{ msg: err.message }] }); } diff --git a/backend/src/models/Banner.js b/backend/src/models/Banner.js index 5e1aa55d..6655ab5d 100644 --- a/backend/src/models/Banner.js +++ b/backend/src/models/Banner.js @@ -5,6 +5,7 @@ const { const { validatePositionWrapper, validateUrl, + validateRelativeUrl, } = require("../utils/banner.helper"); module.exports = (sequelize, DataTypes) => { @@ -34,7 +35,7 @@ module.exports = (sequelize, DataTypes) => { allowNull: true, validate: { isUrl(value) { - validateUrl(value, "url"); + validateRelativeUrl(value, "url"); }, }, }, diff --git a/backend/src/models/Popup.js b/backend/src/models/Popup.js index 084758e5..0e81dffa 100644 --- a/backend/src/models/Popup.js +++ b/backend/src/models/Popup.js @@ -5,6 +5,7 @@ const { const { validatePopupSizeWrapper, validateUrl, + validateRelativeUrl, } = require("../utils/popup.helper"); module.exports = (sequelize, DataTypes) => { @@ -39,7 +40,7 @@ module.exports = (sequelize, DataTypes) => { allowNull: true, validate: { isUrl(value) { - validateUrl(value, "url"); + validateRelativeUrl(value, "url"); }, }, }, diff --git a/backend/src/test/mocks/banner.mock.js b/backend/src/test/mocks/banner.mock.js index 1a88364c..d82af968 100644 --- a/backend/src/test/mocks/banner.mock.js +++ b/backend/src/test/mocks/banner.mock.js @@ -9,6 +9,7 @@ class BannerBuilder { backgroundColor: "#FFFFFF", bannerText: "banner 1", createdBy: 1, + actionUrl: "https://www.google.com", }; } diff --git a/backend/src/test/mocks/popup.mock.js b/backend/src/test/mocks/popup.mock.js index 12957914..75495073 100644 --- a/backend/src/test/mocks/popup.mock.js +++ b/backend/src/test/mocks/popup.mock.js @@ -14,6 +14,7 @@ class PopupBuilder { header: "header", content: "content", createdBy: 1, + actionUrl: "https://www.google.com", }; } diff --git a/backend/src/test/unit/controllers/popup.test.js b/backend/src/test/unit/controllers/popup.test.js index 990ec7b7..4eba0f6e 100644 --- a/backend/src/test/unit/controllers/popup.test.js +++ b/backend/src/test/unit/controllers/popup.test.js @@ -349,6 +349,7 @@ describe("Test popup controller", () => { await popupController.editPopup(req, res); const status = res.status.getCall(0).args[0]; const body = res.json.getCall(0).args[0]; + console.log(body) expect(status).to.be.equal(500); expect(body).to.be.deep.equal({ error: "Internal Server Error", diff --git a/backend/src/utils/banner.helper.js b/backend/src/utils/banner.helper.js index d217af73..93c42be8 100644 --- a/backend/src/utils/banner.helper.js +++ b/backend/src/utils/banner.helper.js @@ -9,6 +9,18 @@ const validatePositionWrapper = (value) => { } }; +const validateRelativeUrl = (value, fieldName) => { + if (!value) return; + try { + new URL(value); + } catch (error) { + if (value.startsWith('/')) { + return + } + throw new Error(`Invalid URL for ${fieldName}: ${error.message}`); + } +} + const validateUrl = (value, fieldName) => { if (!value) return; try { @@ -25,4 +37,5 @@ module.exports = { validatePosition, validatePositionWrapper, validateUrl, + validateRelativeUrl, }; diff --git a/backend/src/utils/popup.helper.js b/backend/src/utils/popup.helper.js index e285d3eb..aff9cf03 100644 --- a/backend/src/utils/popup.helper.js +++ b/backend/src/utils/popup.helper.js @@ -9,6 +9,18 @@ const validatePopupSizeWrapper = (value) => { } }; +const validateRelativeUrl = (value, fieldName) => { + if (!value) return; + try { + new URL(value); + } catch (error) { + if (value.startsWith('/')) { + return + } + throw new Error(`Invalid URL for ${fieldName}: ${error.message}`); + } +} + const validateUrl = (value, fieldName) => { if (!value) return; try { @@ -25,4 +37,5 @@ module.exports = { validatePopupSize, validatePopupSizeWrapper, validateUrl, + validateRelativeUrl }; From 2ce3cad268f0364c883b3a14558f9d8d7f7af4e3 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 12:05:36 -0800 Subject: [PATCH 47/66] fix: fix error return on banner --- backend/src/controllers/banner.controller.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/src/controllers/banner.controller.js b/backend/src/controllers/banner.controller.js index 4afcec14..ccc92855 100644 --- a/backend/src/controllers/banner.controller.js +++ b/backend/src/controllers/banner.controller.js @@ -225,7 +225,11 @@ class BannerController { const banner = await bannerService.getBannerByUrl(url); res.status(200).json({ banner }); } catch (error) { - internalServerError("GET_BANNER_BY_URL_ERROR", error.message); + const { payload, statusCode } = internalServerError( + "GET_BANNER_BY_URL_ERROR", + error.message + ); + res.status(statusCode).json(payload); } } } From 5b3aef0e2f4a35839832d2b31d60ec76633a9815 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Tue, 10 Dec 2024 15:22:12 -0800 Subject: [PATCH 48/66] feat: add column action url to models --- backend/src/models/Banner.js | 18 ++++++------------ backend/src/models/Popup.js | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/backend/src/models/Banner.js b/backend/src/models/Banner.js index 6655ab5d..fb021833 100644 --- a/backend/src/models/Banner.js +++ b/backend/src/models/Banner.js @@ -2,11 +2,7 @@ const { validateHexColor, validateActionButton, } = require("../utils/guide.helper"); -const { - validatePositionWrapper, - validateUrl, - validateRelativeUrl, -} = require("../utils/banner.helper"); +const { validatePositionWrapper } = require("../utils/banner.helper"); module.exports = (sequelize, DataTypes) => { const Banner = sequelize.define( @@ -33,11 +29,6 @@ module.exports = (sequelize, DataTypes) => { url: { type: DataTypes.STRING, allowNull: true, - validate: { - isUrl(value) { - validateRelativeUrl(value, "url"); - }, - }, }, fontColor: { type: DataTypes.STRING, @@ -66,10 +57,13 @@ module.exports = (sequelize, DataTypes) => { }, actionUrl: { type: DataTypes.STRING, - allowNull: true, validate: { isUrl(value) { - validateUrl(value, "actionUrl"); + try { + new URL(value); + } catch { + throw new Error("Invalid URL for actionUrl"); + } }, }, }, diff --git a/backend/src/models/Popup.js b/backend/src/models/Popup.js index 0e81dffa..c0f7a29b 100644 --- a/backend/src/models/Popup.js +++ b/backend/src/models/Popup.js @@ -2,11 +2,7 @@ const { validateHexColor, validateActionButton, } = require("../utils/guide.helper"); -const { - validatePopupSizeWrapper, - validateUrl, - validateRelativeUrl, -} = require("../utils/popup.helper"); +const { validatePopupSizeWrapper } = require("../utils/popup.helper"); module.exports = (sequelize, DataTypes) => { const Popup = sequelize.define( @@ -23,6 +19,7 @@ module.exports = (sequelize, DataTypes) => { validate: { isValidAction(value) { validateActionButton(value); + validateActionButton(value); }, }, }, @@ -32,6 +29,7 @@ module.exports = (sequelize, DataTypes) => { validate: { isValidPopupSize(value) { validatePopupSizeWrapper(value); + validatePopupSizeWrapper(value); }, }, }, @@ -55,6 +53,7 @@ module.exports = (sequelize, DataTypes) => { validate: { isHexColor(value) { validateHexColor(value, "headerBackgroundColor"); + validateHexColor(value, "headerBackgroundColor"); }, }, }, @@ -65,6 +64,7 @@ module.exports = (sequelize, DataTypes) => { validate: { isHexColor(value) { validateHexColor(value, "headerColor"); + validateHexColor(value, "headerColor"); }, }, }, @@ -75,6 +75,7 @@ module.exports = (sequelize, DataTypes) => { validate: { isHexColor(value) { validateHexColor(value, "textColor"); + validateHexColor(value, "textColor"); }, }, }, @@ -95,6 +96,7 @@ module.exports = (sequelize, DataTypes) => { validate: { isHexColor(value) { validateHexColor(value, "buttonTextColor"); + validateHexColor(value, "buttonTextColor"); }, }, }, @@ -110,10 +112,13 @@ module.exports = (sequelize, DataTypes) => { }, actionUrl: { type: DataTypes.STRING, - allowNull: true, validate: { isUrl(value) { - validateUrl(value, "actionUrl"); + try { + new URL(value); + } catch { + throw new Error("Invalid URL for actionUrl"); + } }, }, }, @@ -130,6 +135,7 @@ module.exports = (sequelize, DataTypes) => { tableName: "popup", timestamps: false, } + } ); Popup.associate = (models) => { From 23d97d0847e1848ad314defbbb1502bd6848b15f Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Tue, 10 Dec 2024 15:31:25 -0800 Subject: [PATCH 49/66] feat: add validation on controller to actionUrl column --- backend/src/controllers/banner.controller.js | 42 ++--------- backend/src/controllers/popup.controller.js | 79 ++++++++++++-------- 2 files changed, 52 insertions(+), 69 deletions(-) diff --git a/backend/src/controllers/banner.controller.js b/backend/src/controllers/banner.controller.js index ccc92855..1669cd65 100644 --- a/backend/src/controllers/banner.controller.js +++ b/backend/src/controllers/banner.controller.js @@ -11,14 +11,7 @@ const { checkColorFieldsFail } = require("../utils/guide.helper"); class BannerController { async addBanner(req, res) { const userId = req.user.id; - const { - position, - closeButtonAction, - fontColor, - backgroundColor, - actionUrl, - url, - } = req.body; + const { position, closeButtonAction, fontColor, backgroundColor, actionUrl } = req.body; if (!position || !closeButtonAction) { return res.status(400).json({ @@ -37,17 +30,9 @@ class BannerController { if (actionUrl) { try { - validateUrl(actionUrl, "actionUrl"); + new URL(actionUrl); } catch (err) { - return res.status(400).json({ errors: [{ msg: err.message }] }); - } - } - - if (url) { - try { - validateRelativeUrl(url, "url"); - } catch (err) { - return res.status(400).json({ errors: [{ msg: err.message }] }); + return res.status(400).json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); } } @@ -102,14 +87,7 @@ class BannerController { async editBanner(req, res) { try { const { id } = req.params; - const { - fontColor, - backgroundColor, - url, - position, - closeButtonAction, - actionUrl, - } = req.body; + const { fontColor, backgroundColor, url, position, closeButtonAction, bannerText, actionUrl } = req.body; if (!position || !closeButtonAction) { return res.status(400).json({ @@ -131,17 +109,9 @@ class BannerController { if (actionUrl) { try { - validateUrl(actionUrl, "actionUrl"); - } catch (err) { - return res.status(400).json({ errors: [{ msg: err.message }] }); - } - } - - if (url) { - try { - validateRelativeUrl(url, "url"); + new URL(actionUrl); } catch (err) { - return res.status(400).json({ errors: [{ msg: err.message }] }); + return res.status(400).json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); } } diff --git a/backend/src/controllers/popup.controller.js b/backend/src/controllers/popup.controller.js index 0a566696..4ab9e106 100644 --- a/backend/src/controllers/popup.controller.js +++ b/backend/src/controllers/popup.controller.js @@ -1,11 +1,7 @@ const popupService = require("../service/popup.service"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { - validatePopupSize, - validateUrl, - validateRelativeUrl, -} = require("../utils/popup.helper"); +const { validatePopupSize } = require("../utils/popup.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class PopupController { @@ -20,13 +16,15 @@ class PopupController { buttonBackgroundColor, buttonTextColor, actionUrl, - url, } = req.body; if (!popupSize || !closeButtonAction) { return res.status(400).json({ errors: [{ msg: "popupSize and closeButtonAction are required" }], }); + return res.status(400).json({ + errors: [{ msg: "popupSize and closeButtonAction are required" }], + }); } if ( @@ -36,25 +34,21 @@ class PopupController { return res.status(400).json({ errors: [{ msg: "Invalid value for popupSize or closeButtonAction" }], }); + return res.status(400).json({ + errors: [{ msg: "Invalid value for popupSize or closeButtonAction" }], + }); } if (actionUrl) { try { - validateUrl(actionUrl, "actionUrl"); + new URL(actionUrl); } catch (err) { - return res.status(400).json({ errors: [{ msg: err.message }] }); - } - } - - if (url) { - try { - validateRelativeUrl(url, "url"); - } catch (err) { - return res.status(400).json({ errors: [{ msg: err.message }] }); + return res + .status(400) + .json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); } } - const colorFields = { headerBackgroundColor, headerColor, @@ -66,6 +60,10 @@ class PopupController { if (colorCheck) { return colorCheck; } + const colorCheck = checkColorFieldsFail(colorFields, res); + if (colorCheck) { + return colorCheck; + } try { const newPopupData = { ...req.body, createdBy: userId }; @@ -76,6 +74,7 @@ class PopupController { const { statusCode, payload } = internalServerError( "CREATE_POPUP_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -85,6 +84,7 @@ class PopupController { try { const { id } = req.params; + if (Number.isNaN(Number(id)) || id.trim() === "") { if (Number.isNaN(Number(id)) || id.trim() === "") { return res.status(400).json({ errors: [{ msg: "Invalid id" }] }); } @@ -95,6 +95,9 @@ class PopupController { return res.status(400).json({ errors: [{ msg: "Popup with the specified id does not exist" }], }); + return res.status(400).json({ + errors: [{ msg: "Popup with the specified id does not exist" }], + }); } res @@ -104,6 +107,7 @@ class PopupController { const { statusCode, payload } = internalServerError( "DELETE_POPUP_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -121,13 +125,15 @@ class PopupController { buttonBackgroundColor, buttonTextColor, actionUrl, - url, } = req.body; if (!popupSize || !closeButtonAction) { return res.status(400).json({ errors: [{ msg: "popupSize and closeButtonAction are required" }], }); + return res.status(400).json({ + errors: [{ msg: "popupSize and closeButtonAction are required" }], + }); } if (!validatePopupSize(popupSize)) { @@ -144,17 +150,11 @@ class PopupController { if (actionUrl) { try { - validateUrl(actionUrl, "actionUrl"); + new URL(actionUrl); } catch (err) { - return res.status(400).json({ errors: [{ msg: err.message }] }); - } - } - - if (url) { - try { - validateRelativeUrl(url, "url"); - } catch (err) { - return res.status(400).json({ errors: [{ msg: err.message }] }); + return res + .status(400) + .json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); } } @@ -169,6 +169,10 @@ class PopupController { if (colorCheck) { return colorCheck; } + const colorCheck = checkColorFieldsFail(colorFields, res); + if (colorCheck) { + return colorCheck; + } const updatedPopup = await popupService.updatePopup(id, req.body); res.status(200).json(updatedPopup); @@ -176,6 +180,7 @@ class PopupController { const { statusCode, payload } = internalServerError( "EDIT_POPUP_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -189,6 +194,7 @@ class PopupController { const { statusCode, payload } = internalServerError( "GET_ALL_POPUPS_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -203,6 +209,7 @@ class PopupController { const { statusCode, payload } = internalServerError( "GET_POPUPS_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -212,6 +219,7 @@ class PopupController { try { const { id } = req.params; + if (Number.isNaN(Number(id)) || id.trim() === "") { if (Number.isNaN(Number(id)) || id.trim() === "") { return res.status(400).json({ errors: [{ msg: "Invalid popup ID" }] }); } @@ -220,6 +228,7 @@ class PopupController { if (!popup) { return res.status(404).json({ errors: [{ msg: "Popup not found" }] }); + return res.status(404).json({ errors: [{ msg: "Popup not found" }] }); } res.status(200).json(popup); @@ -227,6 +236,7 @@ class PopupController { const { statusCode, payload } = internalServerError( "GET_POPUP_BY_ID_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -235,6 +245,10 @@ class PopupController { try { const { url } = req.body; + if (!url || typeof url !== "string") { + return res + .status(400) + .json({ errors: [{ msg: "URL is missing or invalid" }] }); if (!url || typeof url !== "string") { return res .status(400) @@ -243,14 +257,13 @@ class PopupController { const popup = await popupService.getPopupByUrl(url); res.status(200).json({ popup }); + res.status(200).json({ popup }); } catch (error) { - const { payload, statusCode } = internalServerError( - "GET_POPUP_BY_URL_ERROR", - error.message - ); - res.status(statusCode).json(payload); + internalServerError("GET_POPUP_BY_URL_ERROR", error.message); } } + } } module.exports = new PopupController(); + From db9c7d1705854c51d29eb403509eb9cdf5cd8975 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Fri, 13 Dec 2024 14:12:49 -0800 Subject: [PATCH 50/66] feat: add action url to banner in front --- .../BannerLeftContent/BannerLeftContent.jsx | 62 ++++++++++++++++++- .../src/scenes/banner/CreateBannerPage.jsx | 24 ------- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx b/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx index 600d083c..4dc7f298 100644 --- a/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx +++ b/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx @@ -1,7 +1,6 @@ import DropdownList from "@components/DropdownList/DropdownList"; import RadioButton from "@components/RadioButton/RadioButton"; import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; -import PropTypes from "prop-types"; import React from "react"; import styles from "./BannerLeftContent.module.scss"; @@ -22,15 +21,61 @@ const BannerLeftContent = ({ const handleSetActionUrl = (event) => { setActionUrl(event.target.value); }; +const BannerLeftContent = ({ + setIsTopPosition, + url, + setUrl, + setButtonAction, + isTopPosition, + buttonAction, + actionUrl, + setActionUrl, +}) => { + const handleSetUrl = (event) => { + setUrl(event.target.value); + }; + const handleSetActionUrl = (event) => { + setActionUrl(event.target.value); + }; + + const handleActionChange = (newAction) => { + setButtonAction(newAction); + }; const handleActionChange = (newAction) => { setButtonAction(newAction); }; + const handlePositionChange = (newPosition) => { + setIsTopPosition(newPosition); + }; const handlePositionChange = (newPosition) => { setIsTopPosition(newPosition); }; + return ( +
+

Action

+ +

Position

+
+ handlePositionChange(true)} + /> +
+
+ handlePositionChange(false)} + /> +
return (

Action

@@ -62,6 +107,21 @@ const BannerLeftContent = ({ onChange={handleSetUrl} /> +

Action URL

+ +
+ ); +

URL

+ +

Action URL

{ } }, [location.state]); - const validateUrl = (url) => { - try { - new URL(url); - return null; - } catch (err) { - return "Invalid URL format"; - } - }; - const onSave = async () => { - if (actionUrl && actionUrl !== "https://") { - const urlError = validateUrl(actionUrl); - if (urlError) { - emitToastError(urlError); - return; - } - } - if (url && url !== "https://") { - const urlError = validateUrl(url); - if (urlError) { - emitToastError(urlError); - return; - } - } - const bannerData = { backgroundColor, fontColor, From 3cd858431796771beb9b6583f87acf4540b7b713 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Fri, 13 Dec 2024 14:25:40 -0800 Subject: [PATCH 51/66] feat: add action url to popup front --- frontend/src/scenes/popup/CreatePopupPage.jsx | 143 +++++++++++++++--- .../PopupContent/PopupContent.jsx | 1 - 2 files changed, 119 insertions(+), 25 deletions(-) diff --git a/frontend/src/scenes/popup/CreatePopupPage.jsx b/frontend/src/scenes/popup/CreatePopupPage.jsx index 5d68f3ac..cf143e48 100644 --- a/frontend/src/scenes/popup/CreatePopupPage.jsx +++ b/frontend/src/scenes/popup/CreatePopupPage.jsx @@ -11,22 +11,52 @@ import { emitToastError } from "../../utils/guideHelper"; import toastEmitter, { TOAST_EMITTER_KEY } from "../../utils/toastEmitter"; import PopupAppearance from "./PopupPageComponents/PopupAppearance/PopupAppearance"; import PopupContent from "./PopupPageComponents/PopupContent/PopupContent"; +import RichTextEditor from "@components/RichTextEditor/RichTextEditor"; +import React, { useEffect, useState } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import { + addPopup, + editPopup, + getPopupById, +} from "../../services/popupServices"; +import GuideTemplate from "../../templates/GuideTemplate/GuideTemplate"; +import { emitToastError } from "../../utils/guideHelper"; +import toastEmitter, { TOAST_EMITTER_KEY } from "../../utils/toastEmitter"; +import PopupAppearance from "./PopupPageComponents/PopupAppearance/PopupAppearance"; +import PopupContent from "./PopupPageComponents/PopupContent/PopupContent"; const CreatePopupPage = () => { const navigate = useNavigate(); const location = useLocation(); + const navigate = useNavigate(); + const location = useLocation(); + const [activeButton, setActiveButton] = useState(0); const [activeButton, setActiveButton] = useState(0); + const [headerBackgroundColor, setHeaderBackgroundColor] = useState("#F8F9F8"); + const [headerColor, setHeaderColor] = useState("#101828"); + const [textColor, setTextColor] = useState("#344054"); + const [buttonBackgroundColor, setButtonBackgroundColor] = useState("#7F56D9"); + const [buttonTextColor, setButtonTextColor] = useState("#FFFFFF"); const [headerBackgroundColor, setHeaderBackgroundColor] = useState("#F8F9F8"); const [headerColor, setHeaderColor] = useState("#101828"); const [textColor, setTextColor] = useState("#344054"); const [buttonBackgroundColor, setButtonBackgroundColor] = useState("#7F56D9"); const [buttonTextColor, setButtonTextColor] = useState("#FFFFFF"); + const [header, setHeader] = useState(""); + const [content, setContent] = useState(""); const [header, setHeader] = useState(""); const [content, setContent] = useState(""); + const [actionButtonUrl, setActionButtonUrl] = useState("https://"); + const [url, setUrl] = useState("https://"); + const [actionButtonText, setActionButtonText] = useState( + "Take me to subscription page" + ); + const [buttonAction, setButtonAction] = useState("No action"); + const [popupSize, setPopupSize] = useState("Small"); const [actionButtonUrl, setActionButtonUrl] = useState("https://"); const [url, setUrl] = useState("https://"); const [actionButtonText, setActionButtonText] = useState( @@ -52,9 +82,14 @@ const CreatePopupPage = () => { stateName: "Button Text Color", state: buttonTextColor, setState: setButtonTextColor, - }, + } ]; + useEffect(() => { + if (location.state?.isEdit) { + const fetchPopupData = async () => { + try { + const popupData = await getPopupById(location.state.id); useEffect(() => { if (location.state?.isEdit) { const fetchPopupData = async () => { @@ -84,35 +119,35 @@ const CreatePopupPage = () => { emitToastError(error); } }; + // Update the state with the fetched data + setHeaderBackgroundColor( + popupData.headerBackgroundColor || "#F8F9F8" + ); + setHeaderColor(popupData.headerColor || "#101828"); + setTextColor(popupData.textColor || "#344054"); + setButtonBackgroundColor( + popupData.buttonBackgroundColor || "#7F56D9" + ); + setButtonTextColor(popupData.buttonTextColor || "#FFFFFF"); + setHeader(popupData.header || ""); + setContent(popupData.content || ""); + setActionButtonUrl(popupData.actionUrl || "https://"); + setUrl(popupData.url || "https://"); + setActionButtonText( + popupData.actionButtonText || "Take me to subscription page" + ); + setButtonAction(popupData.closeButtonAction || "No action"); + setPopupSize(popupData.popupSize || "Small"); + } catch (error) { + emitToastError(error); + } + }; fetchPopupData(); } }, [location.state]); - const validateUrl = (url) => { - try { - new URL(url); - return null; - } catch (err) { - return "Invalid URL format"; - } - }; - const onSave = async () => { - if (actionButtonUrl && actionButtonUrl !== "https://") { - const urlError = validateUrl(actionButtonUrl); - if (urlError) { - emitToastError(urlError); - return; - } - } - if (url && url !== "https://") { - const urlError = validateUrl(url); - if (urlError) { - emitToastError(urlError); - return; - } - } const popupData = { popupSize: popupSize.toLowerCase(), url, @@ -132,6 +167,7 @@ const CreatePopupPage = () => { ? await editPopup(location.state?.id, popupData) : await addPopup(popupData); + console.log(response); const toastMessage = location.state?.isEdit ? "You edited this popup" : "New popup Saved"; @@ -143,9 +179,20 @@ const CreatePopupPage = () => { ? `Error: ${error.response.data.message}` : "An unexpected error occurred. Please try again."; toastEmitter.emit(TOAST_EMITTER_KEY, errorMessage); + toastEmitter.emit(TOAST_EMITTER_KEY, toastMessage); + navigate("/popup"); + } catch (error) { + const errorMessage = error.response?.data?.message + ? `Error: ${error.response.data.message}` + : "An unexpected error occurred. Please try again."; + toastEmitter.emit(TOAST_EMITTER_KEY, errorMessage); } }; + }; + const handleButtonClick = (index) => { + setActiveButton(index); + }; const handleButtonClick = (index) => { setActiveButton(index); }; @@ -198,6 +245,54 @@ const CreatePopupPage = () => { )} /> ); + return ( + ( + + )} + leftContent={() => ( + + )} + leftAppearance={() => ( + + )} + /> + ); }; export default CreatePopupPage; diff --git a/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx b/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx index 18a04e31..621c8776 100644 --- a/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx +++ b/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx @@ -2,7 +2,6 @@ import DropdownList from "@components/DropdownList/DropdownList"; import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; import { React } from "react"; import styles from "./PopupContent.module.scss"; -import PropTypes from "prop-types"; const PopupContent = ({ actionButtonText, From 777cce7314e1ecf90a8ac28e0a2d03baaa28735f Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:06:28 -0800 Subject: [PATCH 52/66] chore: add proptypes to banner and popup content --- .../BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx | 1 + .../popup/PopupPageComponents/PopupContent/PopupContent.jsx | 1 + 2 files changed, 2 insertions(+) diff --git a/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx b/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx index 4dc7f298..20186251 100644 --- a/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx +++ b/frontend/src/scenes/banner/BannerPageComponents/BannerLeftContent/BannerLeftContent.jsx @@ -1,6 +1,7 @@ import DropdownList from "@components/DropdownList/DropdownList"; import RadioButton from "@components/RadioButton/RadioButton"; import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; +import PropTypes from "prop-types"; import React from "react"; import styles from "./BannerLeftContent.module.scss"; diff --git a/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx b/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx index 621c8776..18a04e31 100644 --- a/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx +++ b/frontend/src/scenes/popup/PopupPageComponents/PopupContent/PopupContent.jsx @@ -2,6 +2,7 @@ import DropdownList from "@components/DropdownList/DropdownList"; import CustomTextField from "@components/TextFieldComponents/CustomTextField/CustomTextField"; import { React } from "react"; import styles from "./PopupContent.module.scss"; +import PropTypes from "prop-types"; const PopupContent = ({ actionButtonText, From 32aa9548b91bdef5dc1d564cc8b6f8885790c5b2 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:09:42 -0800 Subject: [PATCH 53/66] chore: improve url validation on model --- backend/src/models/Banner.js | 17 +++++++++++------ backend/src/models/Popup.js | 14 +++++++------- backend/src/utils/banner.helper.js | 13 ------------- backend/src/utils/popup.helper.js | 13 ------------- 4 files changed, 18 insertions(+), 39 deletions(-) diff --git a/backend/src/models/Banner.js b/backend/src/models/Banner.js index fb021833..5e1aa55d 100644 --- a/backend/src/models/Banner.js +++ b/backend/src/models/Banner.js @@ -2,7 +2,10 @@ const { validateHexColor, validateActionButton, } = require("../utils/guide.helper"); -const { validatePositionWrapper } = require("../utils/banner.helper"); +const { + validatePositionWrapper, + validateUrl, +} = require("../utils/banner.helper"); module.exports = (sequelize, DataTypes) => { const Banner = sequelize.define( @@ -29,6 +32,11 @@ module.exports = (sequelize, DataTypes) => { url: { type: DataTypes.STRING, allowNull: true, + validate: { + isUrl(value) { + validateUrl(value, "url"); + }, + }, }, fontColor: { type: DataTypes.STRING, @@ -57,13 +65,10 @@ module.exports = (sequelize, DataTypes) => { }, actionUrl: { type: DataTypes.STRING, + allowNull: true, validate: { isUrl(value) { - try { - new URL(value); - } catch { - throw new Error("Invalid URL for actionUrl"); - } + validateUrl(value, "actionUrl"); }, }, }, diff --git a/backend/src/models/Popup.js b/backend/src/models/Popup.js index c0f7a29b..5b845d76 100644 --- a/backend/src/models/Popup.js +++ b/backend/src/models/Popup.js @@ -2,7 +2,10 @@ const { validateHexColor, validateActionButton, } = require("../utils/guide.helper"); -const { validatePopupSizeWrapper } = require("../utils/popup.helper"); +const { + validatePopupSizeWrapper, + validateUrl, +} = require("../utils/popup.helper"); module.exports = (sequelize, DataTypes) => { const Popup = sequelize.define( @@ -38,7 +41,7 @@ module.exports = (sequelize, DataTypes) => { allowNull: true, validate: { isUrl(value) { - validateRelativeUrl(value, "url"); + validateUrl(value, "url"); }, }, }, @@ -112,13 +115,10 @@ module.exports = (sequelize, DataTypes) => { }, actionUrl: { type: DataTypes.STRING, + allowNull: true, validate: { isUrl(value) { - try { - new URL(value); - } catch { - throw new Error("Invalid URL for actionUrl"); - } + validateUrl(value, "actionUrl"); }, }, }, diff --git a/backend/src/utils/banner.helper.js b/backend/src/utils/banner.helper.js index 93c42be8..d217af73 100644 --- a/backend/src/utils/banner.helper.js +++ b/backend/src/utils/banner.helper.js @@ -9,18 +9,6 @@ const validatePositionWrapper = (value) => { } }; -const validateRelativeUrl = (value, fieldName) => { - if (!value) return; - try { - new URL(value); - } catch (error) { - if (value.startsWith('/')) { - return - } - throw new Error(`Invalid URL for ${fieldName}: ${error.message}`); - } -} - const validateUrl = (value, fieldName) => { if (!value) return; try { @@ -37,5 +25,4 @@ module.exports = { validatePosition, validatePositionWrapper, validateUrl, - validateRelativeUrl, }; diff --git a/backend/src/utils/popup.helper.js b/backend/src/utils/popup.helper.js index aff9cf03..e285d3eb 100644 --- a/backend/src/utils/popup.helper.js +++ b/backend/src/utils/popup.helper.js @@ -9,18 +9,6 @@ const validatePopupSizeWrapper = (value) => { } }; -const validateRelativeUrl = (value, fieldName) => { - if (!value) return; - try { - new URL(value); - } catch (error) { - if (value.startsWith('/')) { - return - } - throw new Error(`Invalid URL for ${fieldName}: ${error.message}`); - } -} - const validateUrl = (value, fieldName) => { if (!value) return; try { @@ -37,5 +25,4 @@ module.exports = { validatePopupSize, validatePopupSizeWrapper, validateUrl, - validateRelativeUrl }; From f9e5748548fa4e7e2b88ca502cf9d77f305cc745 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:14:26 -0800 Subject: [PATCH 54/66] chore: improve url validation on front --- .../src/scenes/banner/CreateBannerPage.jsx | 24 +++++++++++++++++ frontend/src/scenes/popup/CreatePopupPage.jsx | 27 +++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/frontend/src/scenes/banner/CreateBannerPage.jsx b/frontend/src/scenes/banner/CreateBannerPage.jsx index 154c4346..59ad75fd 100644 --- a/frontend/src/scenes/banner/CreateBannerPage.jsx +++ b/frontend/src/scenes/banner/CreateBannerPage.jsx @@ -54,7 +54,31 @@ const BannerPage = () => { } }, [location.state]); + const validateUrl = (url) => { + try { + new URL(url); + return null; + } catch (err) { + return "Invalid URL format"; + } + }; + const onSave = async () => { + if (actionUrl && actionUrl !== "https://") { + const urlError = validateUrl(actionUrl); + if (urlError) { + emitToastError(urlError); + return; + } + } + if (url && url !== "https://") { + const urlError = validateUrl(url); + if (urlError) { + emitToastError(urlError); + return; + } + } + const bannerData = { backgroundColor, fontColor, diff --git a/frontend/src/scenes/popup/CreatePopupPage.jsx b/frontend/src/scenes/popup/CreatePopupPage.jsx index cf143e48..db590022 100644 --- a/frontend/src/scenes/popup/CreatePopupPage.jsx +++ b/frontend/src/scenes/popup/CreatePopupPage.jsx @@ -82,7 +82,7 @@ const CreatePopupPage = () => { stateName: "Button Text Color", state: buttonTextColor, setState: setButtonTextColor, - } + }, ]; useEffect(() => { @@ -147,7 +147,30 @@ const CreatePopupPage = () => { } }, [location.state]); + const validateUrl = (url) => { + try { + new URL(url); + return null; + } catch (err) { + return "Invalid URL format"; + } + }; + const onSave = async () => { + if (actionButtonUrl && actionButtonUrl !== "https://") { + const urlError = validateUrl(actionButtonUrl); + if (urlError) { + emitToastError(urlError); + return; + } + } + if (url && url !== "https://") { + const urlError = validateUrl(url); + if (urlError) { + emitToastError(urlError); + return; + } + } const popupData = { popupSize: popupSize.toLowerCase(), url, @@ -167,7 +190,7 @@ const CreatePopupPage = () => { ? await editPopup(location.state?.id, popupData) : await addPopup(popupData); - console.log(response); + console.log(response); const toastMessage = location.state?.isEdit ? "You edited this popup" : "New popup Saved"; From 9ef45c45cf36bed721996762d78b28b02176343b Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:18:25 -0800 Subject: [PATCH 55/66] chore: improve url validation on controller --- backend/src/controllers/banner.controller.js | 92 ++++++++++++++++---- backend/src/controllers/popup.controller.js | 32 +++++-- 2 files changed, 99 insertions(+), 25 deletions(-) diff --git a/backend/src/controllers/banner.controller.js b/backend/src/controllers/banner.controller.js index 1669cd65..4f2c6b0f 100644 --- a/backend/src/controllers/banner.controller.js +++ b/backend/src/controllers/banner.controller.js @@ -1,24 +1,37 @@ const bannerService = require("../service/banner.service.js"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { - validatePosition, - validateUrl, - validateRelativeUrl, -} = require("../utils/banner.helper"); +const { validatePosition, validateUrl } = require("../utils/banner.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class BannerController { async addBanner(req, res) { const userId = req.user.id; - const { position, closeButtonAction, fontColor, backgroundColor, actionUrl } = req.body; + const { + position, + closeButtonAction, + fontColor, + backgroundColor, + actionUrl, + url, + } = req.body; if (!position || !closeButtonAction) { return res.status(400).json({ errors: [{ msg: "position and closeButtonAction are required" }], }); + return res.status(400).json({ + errors: [{ msg: "position and closeButtonAction are required" }], + }); } + if ( + !validatePosition(position) || + !validateCloseButtonAction(closeButtonAction) + ) { + return res.status(400).json({ + errors: [{ msg: "Invalid value entered" }], + }); if ( !validatePosition(position) || !validateCloseButtonAction(closeButtonAction) @@ -30,9 +43,17 @@ class BannerController { if (actionUrl) { try { - new URL(actionUrl); + validateUrl(actionUrl, "actionUrl"); } catch (err) { - return res.status(400).json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + return res.status(400).json({ errors: [{ msg: err.message }] }); + } + } + + if (url) { + try { + validateUrl(url, "url"); + } catch (err) { + return res.status(400).json({ errors: [{ msg: err.message }] }); } } @@ -41,6 +62,10 @@ class BannerController { if (colorCheck) { return colorCheck; } + const colorCheck = checkColorFieldsFail(colorFields, res); + if (colorCheck) { + return colorCheck; + } try { const newBannerData = { ...req.body, createdBy: userId }; @@ -51,6 +76,7 @@ class BannerController { const { statusCode, payload } = internalServerError( "CREATE_BANNER_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -70,6 +96,9 @@ class BannerController { return res.status(400).json({ errors: [{ msg: "Banner with the specified id does not exist" }], }); + return res.status(400).json({ + errors: [{ msg: "Banner with the specified id does not exist" }], + }); } res @@ -79,6 +108,7 @@ class BannerController { const { statusCode, payload } = internalServerError( "DELETE_BANNER_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -87,12 +117,23 @@ class BannerController { async editBanner(req, res) { try { const { id } = req.params; - const { fontColor, backgroundColor, url, position, closeButtonAction, bannerText, actionUrl } = req.body; + const { + fontColor, + backgroundColor, + url, + position, + closeButtonAction, + bannerText, + actionUrl, + } = req.body; if (!position || !closeButtonAction) { return res.status(400).json({ errors: [{ msg: "position and closeButtonAction are required" }], }); + return res.status(400).json({ + errors: [{ msg: "position and closeButtonAction are required" }], + }); } if (!validatePosition(position)) { @@ -109,9 +150,17 @@ class BannerController { if (actionUrl) { try { - new URL(actionUrl); + validateUrl(actionUrl, "actionUrl"); + } catch (err) { + return res.status(400).json({ errors: [{ msg: err.message }] }); + } + } + + if (url) { + try { + validateUrl(url, "url"); } catch (err) { - return res.status(400).json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + return res.status(400).json({ errors: [{ msg: err.message }] }); } } @@ -120,6 +169,10 @@ class BannerController { if (colorCheck) { return colorCheck; } + const colorCheck = checkColorFieldsFail(colorFields, res); + if (colorCheck) { + return colorCheck; + } const updatedBanner = await bannerService.updateBanner(id, req.body); res.status(200).json(updatedBanner); @@ -127,6 +180,7 @@ class BannerController { const { statusCode, payload } = internalServerError( "EDIT_BANNER_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -140,6 +194,7 @@ class BannerController { const { statusCode, payload } = internalServerError( "GET_ALL_BANNERS_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -154,6 +209,8 @@ class BannerController { const { statusCode, payload } = internalServerError( "GET_BANNERS_ERROR", err.message + "GET_BANNERS_ERROR", + err.message ); res.status(statusCode).json(payload); } @@ -178,6 +235,7 @@ class BannerController { const { statusCode, payload } = internalServerError( "GET_BANNER_BY_ID_ERROR", err.message + err.message ); res.status(statusCode).json(payload); } @@ -186,6 +244,10 @@ class BannerController { try { const { url } = req.body; + if (!url || typeof url !== "string") { + return res + .status(400) + .json({ errors: [{ msg: "URL is missing or invalid" }] }); if (!url || typeof url !== "string") { return res .status(400) @@ -194,14 +256,12 @@ class BannerController { const banner = await bannerService.getBannerByUrl(url); res.status(200).json({ banner }); + res.status(200).json({ banner }); } catch (error) { - const { payload, statusCode } = internalServerError( - "GET_BANNER_BY_URL_ERROR", - error.message - ); - res.status(statusCode).json(payload); + internalServerError("GET_BANNER_BY_URL_ERROR", error.message); } } + } } module.exports = new BannerController(); diff --git a/backend/src/controllers/popup.controller.js b/backend/src/controllers/popup.controller.js index 4ab9e106..5b76d572 100644 --- a/backend/src/controllers/popup.controller.js +++ b/backend/src/controllers/popup.controller.js @@ -1,7 +1,7 @@ const popupService = require("../service/popup.service"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { validatePopupSize } = require("../utils/popup.helper"); +const { validatePopupSize, validateUrl } = require("../utils/popup.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class PopupController { @@ -16,6 +16,7 @@ class PopupController { buttonBackgroundColor, buttonTextColor, actionUrl, + url, } = req.body; if (!popupSize || !closeButtonAction) { @@ -41,11 +42,17 @@ class PopupController { if (actionUrl) { try { - new URL(actionUrl); + validateUrl(actionUrl, "actionUrl"); } catch (err) { - return res - .status(400) - .json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + return res.status(400).json({ errors: [{ msg: err.message }] }); + } + } + + if (url) { + try { + validateUrl(url, "url"); + } catch (err) { + return res.status(400).json({ errors: [{ msg: err.message }] }); } } @@ -125,6 +132,7 @@ class PopupController { buttonBackgroundColor, buttonTextColor, actionUrl, + url, } = req.body; if (!popupSize || !closeButtonAction) { @@ -150,11 +158,17 @@ class PopupController { if (actionUrl) { try { - new URL(actionUrl); + validateUrl(actionUrl, "actionUrl"); + } catch (err) { + return res.status(400).json({ errors: [{ msg: err.message }] }); + } + } + + if (url) { + try { + validateUrl(url, "url"); } catch (err) { - return res - .status(400) - .json({ errors: [{ msg: "Invalid URL format for actionUrl" }] }); + return res.status(400).json({ errors: [{ msg: err.message }] }); } } From b47b6f5b630835cb2b0faddb3b10be12352f5059 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:19:53 -0800 Subject: [PATCH 56/66] fix: fix error return on popup --- backend/src/controllers/popup.controller.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/src/controllers/popup.controller.js b/backend/src/controllers/popup.controller.js index 5b76d572..2fcb5ae1 100644 --- a/backend/src/controllers/popup.controller.js +++ b/backend/src/controllers/popup.controller.js @@ -273,7 +273,11 @@ class PopupController { res.status(200).json({ popup }); res.status(200).json({ popup }); } catch (error) { - internalServerError("GET_POPUP_BY_URL_ERROR", error.message); + const { payload, statusCode } = internalServerError( + "GET_POPUP_BY_URL_ERROR", + error.message + ); + res.status(statusCode).json(payload); } } } From 2018c5d7a1b05bdbe8d9435ff2aa7b0b108c37ec Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 10:20:36 -0800 Subject: [PATCH 57/66] chore: remove console log from popup front --- frontend/src/scenes/popup/CreatePopupPage.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/scenes/popup/CreatePopupPage.jsx b/frontend/src/scenes/popup/CreatePopupPage.jsx index db590022..2c8212c5 100644 --- a/frontend/src/scenes/popup/CreatePopupPage.jsx +++ b/frontend/src/scenes/popup/CreatePopupPage.jsx @@ -190,7 +190,6 @@ const CreatePopupPage = () => { ? await editPopup(location.state?.id, popupData) : await addPopup(popupData); - console.log(response); const toastMessage = location.state?.isEdit ? "You edited this popup" : "New popup Saved"; From 43fbb228ec4afdcbcd7e70da47488aa4decfdd61 Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 11:56:22 -0800 Subject: [PATCH 58/66] test: fix test on back --- backend/src/controllers/banner.controller.js | 11 +++++++---- backend/src/controllers/popup.controller.js | 13 +++++++++---- backend/src/models/Banner.js | 3 ++- backend/src/models/Popup.js | 3 ++- backend/src/utils/banner.helper.js | 13 +++++++++++++ backend/src/utils/popup.helper.js | 13 +++++++++++++ 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/backend/src/controllers/banner.controller.js b/backend/src/controllers/banner.controller.js index 4f2c6b0f..6a879efd 100644 --- a/backend/src/controllers/banner.controller.js +++ b/backend/src/controllers/banner.controller.js @@ -1,7 +1,11 @@ const bannerService = require("../service/banner.service.js"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { validatePosition, validateUrl } = require("../utils/banner.helper"); +const { + validatePosition, + validateUrl, + validateRelativeUrl, +} = require("../utils/banner.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class BannerController { @@ -51,7 +55,7 @@ class BannerController { if (url) { try { - validateUrl(url, "url"); + validateRelativeUrl(url, "url"); } catch (err) { return res.status(400).json({ errors: [{ msg: err.message }] }); } @@ -123,7 +127,6 @@ class BannerController { url, position, closeButtonAction, - bannerText, actionUrl, } = req.body; @@ -158,7 +161,7 @@ class BannerController { if (url) { try { - validateUrl(url, "url"); + validateRelativeUrl(url, "url"); } catch (err) { return res.status(400).json({ errors: [{ msg: err.message }] }); } diff --git a/backend/src/controllers/popup.controller.js b/backend/src/controllers/popup.controller.js index 2fcb5ae1..4e2b911c 100644 --- a/backend/src/controllers/popup.controller.js +++ b/backend/src/controllers/popup.controller.js @@ -1,7 +1,11 @@ const popupService = require("../service/popup.service"); const { internalServerError } = require("../utils/errors.helper"); const { validateCloseButtonAction } = require("../utils/guide.helper"); -const { validatePopupSize, validateUrl } = require("../utils/popup.helper"); +const { + validatePopupSize, + validateUrl, + validateRelativeUrl, +} = require("../utils/popup.helper"); const { checkColorFieldsFail } = require("../utils/guide.helper"); class PopupController { @@ -47,15 +51,16 @@ class PopupController { return res.status(400).json({ errors: [{ msg: err.message }] }); } } - + if (url) { try { - validateUrl(url, "url"); + validateRelativeUrl(url, "url"); } catch (err) { return res.status(400).json({ errors: [{ msg: err.message }] }); } } + const colorFields = { headerBackgroundColor, headerColor, @@ -166,7 +171,7 @@ class PopupController { if (url) { try { - validateUrl(url, "url"); + validateRelativeUrl(url, "url"); } catch (err) { return res.status(400).json({ errors: [{ msg: err.message }] }); } diff --git a/backend/src/models/Banner.js b/backend/src/models/Banner.js index 5e1aa55d..6655ab5d 100644 --- a/backend/src/models/Banner.js +++ b/backend/src/models/Banner.js @@ -5,6 +5,7 @@ const { const { validatePositionWrapper, validateUrl, + validateRelativeUrl, } = require("../utils/banner.helper"); module.exports = (sequelize, DataTypes) => { @@ -34,7 +35,7 @@ module.exports = (sequelize, DataTypes) => { allowNull: true, validate: { isUrl(value) { - validateUrl(value, "url"); + validateRelativeUrl(value, "url"); }, }, }, diff --git a/backend/src/models/Popup.js b/backend/src/models/Popup.js index 5b845d76..3c1313be 100644 --- a/backend/src/models/Popup.js +++ b/backend/src/models/Popup.js @@ -5,6 +5,7 @@ const { const { validatePopupSizeWrapper, validateUrl, + validateRelativeUrl, } = require("../utils/popup.helper"); module.exports = (sequelize, DataTypes) => { @@ -41,7 +42,7 @@ module.exports = (sequelize, DataTypes) => { allowNull: true, validate: { isUrl(value) { - validateUrl(value, "url"); + validateRelativeUrl(value, "url"); }, }, }, diff --git a/backend/src/utils/banner.helper.js b/backend/src/utils/banner.helper.js index d217af73..93c42be8 100644 --- a/backend/src/utils/banner.helper.js +++ b/backend/src/utils/banner.helper.js @@ -9,6 +9,18 @@ const validatePositionWrapper = (value) => { } }; +const validateRelativeUrl = (value, fieldName) => { + if (!value) return; + try { + new URL(value); + } catch (error) { + if (value.startsWith('/')) { + return + } + throw new Error(`Invalid URL for ${fieldName}: ${error.message}`); + } +} + const validateUrl = (value, fieldName) => { if (!value) return; try { @@ -25,4 +37,5 @@ module.exports = { validatePosition, validatePositionWrapper, validateUrl, + validateRelativeUrl, }; diff --git a/backend/src/utils/popup.helper.js b/backend/src/utils/popup.helper.js index e285d3eb..aff9cf03 100644 --- a/backend/src/utils/popup.helper.js +++ b/backend/src/utils/popup.helper.js @@ -9,6 +9,18 @@ const validatePopupSizeWrapper = (value) => { } }; +const validateRelativeUrl = (value, fieldName) => { + if (!value) return; + try { + new URL(value); + } catch (error) { + if (value.startsWith('/')) { + return + } + throw new Error(`Invalid URL for ${fieldName}: ${error.message}`); + } +} + const validateUrl = (value, fieldName) => { if (!value) return; try { @@ -25,4 +37,5 @@ module.exports = { validatePopupSize, validatePopupSizeWrapper, validateUrl, + validateRelativeUrl }; From 161bf4cfa14629e5b38b83fc1df6d1840b14994c Mon Sep 17 00:00:00 2001 From: Debora Serra Date: Sat, 14 Dec 2024 12:05:36 -0800 Subject: [PATCH 59/66] fix: fix error return on banner --- backend/src/controllers/banner.controller.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/src/controllers/banner.controller.js b/backend/src/controllers/banner.controller.js index 6a879efd..5e31d11f 100644 --- a/backend/src/controllers/banner.controller.js +++ b/backend/src/controllers/banner.controller.js @@ -261,7 +261,11 @@ class BannerController { res.status(200).json({ banner }); res.status(200).json({ banner }); } catch (error) { - internalServerError("GET_BANNER_BY_URL_ERROR", error.message); + const { payload, statusCode } = internalServerError( + "GET_BANNER_BY_URL_ERROR", + error.message + ); + res.status(statusCode).json(payload); } } } From 2bf8716636645acbec647403c7435d45e8ae66b3 Mon Sep 17 00:00:00 2001 From: erenfn Date: Wed, 11 Dec 2024 01:23:14 +0300 Subject: [PATCH 60/66] guide init --- backend/src/controllers/guide.controller.js | 21 +++++++++++++++++++++ backend/src/routes/guide.routes.js | 4 ++-- backend/src/service/banner.service.js | 14 ++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/backend/src/controllers/guide.controller.js b/backend/src/controllers/guide.controller.js index 33c0e613..ee5e2855 100644 --- a/backend/src/controllers/guide.controller.js +++ b/backend/src/controllers/guide.controller.js @@ -23,6 +23,27 @@ class GuideController { ); } } + + async getIncompleteGuidesByUrl(req, res) { + try { + const { url, userId } = req.body; + + if (!url || typeof url !== 'string') { + return res.status(400).json({ errors: [{ msg: "URL is missing or invalid" }] }); + } + if (!userId || typeof url !== 'userId') { + return res.status(400).json({ errors: [{ msg: "userId is missing or invalid" }] }); + } + + + + } catch (error) { + internalServerError( + "GET_INCOMPLETE_GUIDES_BY_URL_ERROR", + error.message, + ); + } + } } module.exports = new GuideController(); \ No newline at end of file diff --git a/backend/src/routes/guide.routes.js b/backend/src/routes/guide.routes.js index adf32244..b7df280b 100644 --- a/backend/src/routes/guide.routes.js +++ b/backend/src/routes/guide.routes.js @@ -3,7 +3,7 @@ const guideController = require("../controllers/guide.controller.js"); const router = express.Router(); -router.post("/get_guides_by_url", guideController.getGuidesByUrl); -// router.get("/get_incomplete_guides_by_url", guideController.getIncompleteGuidesByUrl); +router.get("/get_guides_by_url", guideController.getGuidesByUrl); +router.get("/get_incomplete_guides_by_url", guideController.getIncompleteGuidesByUrl); module.exports = router; diff --git a/backend/src/service/banner.service.js b/backend/src/service/banner.service.js index 5b5f9e9a..925e9ba4 100644 --- a/backend/src/service/banner.service.js +++ b/backend/src/service/banner.service.js @@ -1,4 +1,5 @@ const db = require("../models"); +const { Op } = require('sequelize'); const Banner = db.Banner; class BannerService { @@ -61,6 +62,19 @@ class BannerService { throw new Error("Error retrieving banner by URL"); } }; + + async getIncompleteBannersByUrl(url, ids) { + try { + return await Banner.findAll({ + where: { + url, + id: { [Op.notIn]: ids } + } + }); + } catch (error) { + throw new Error("Error retrieving banner by URL"); + } + }; } module.exports = new BannerService(); From 6039fe4f8cfbc0df07617bfcd3b0c57091bf3119 Mon Sep 17 00:00:00 2001 From: erenfn Date: Wed, 11 Dec 2024 01:25:39 +0300 Subject: [PATCH 61/66] resolve dockerfile --- backend/Dockerfile | 2 -- backend/src/service/popup.service.js | 31 +++++++++++++--------------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index ed2ea280..033bab83 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -2,8 +2,6 @@ FROM node:22-alpine3.21 RUN apk update && apk add bash && rm -rf /var/cache/apk/* -RUN apk update && apk add bash && rm -rf /var/cache/apk/* - WORKDIR /app COPY package*.json ./ diff --git a/backend/src/service/popup.service.js b/backend/src/service/popup.service.js index 21824d2c..d736cb25 100644 --- a/backend/src/service/popup.service.js +++ b/backend/src/service/popup.service.js @@ -1,3 +1,4 @@ +const { Op } = require("sequelize"); const db = require("../models"); const Popup = db.Popup; @@ -55,29 +56,25 @@ class PopupService { } } - async getPopupByApiAndClientId(apiId, clientId) { + async getPopupByUrl(url) { try { - return await Popup.findAll({ - include: [ - { - model: db.User, - as: "creator", - where: { apiId } - }, - ], - where: { clientId }, - order: [['createdAt', 'DESC']], - }); + return await Popup.findAll({ where: { url } }); } catch (error) { - throw new Error("Error retrieving popups for the given API and Client ID"); + throw new Error("Error retrieving Popup by URL"); } - } + }; - async getPopupByUrl(url) { + + async getIncompletePopupsByUrl(url, ids) { try { - return await Popup.findAll({ where: { url } }); + return await Popup.findAll({ + where: { + url, + id: { [Op.notIn]: ids } + } + }); } catch (error) { - throw new Error("Error retrieving Popup by URL"); + throw new Error("Error retrieving popup by URL"); } }; } From 2bdf41fc4ebdfc8c32fdabfb96dd364add66aa07 Mon Sep 17 00:00:00 2001 From: erenfn Date: Wed, 11 Dec 2024 04:21:38 +0300 Subject: [PATCH 62/66] find incomplete guides done --- backend/config/settings.js | 1 + backend/src/controllers/guide.controller.js | 28 +++++++++--- .../src/controllers/helperLink.controller.js | 13 ++++++ backend/src/routes/helperLink.routes.js | 20 +++++---- backend/src/service/guidelog.service.js | 45 +++++++++++++++++++ backend/src/service/helperLink.service.js | 26 +++++++++++ 6 files changed, 119 insertions(+), 14 deletions(-) diff --git a/backend/config/settings.js b/backend/config/settings.js index 2bb3415b..e7b97a36 100644 --- a/backend/config/settings.js +++ b/backend/config/settings.js @@ -26,6 +26,7 @@ module.exports = { serverUrlAndApiKey: [userRole.ADMIN], links: [userRole.ADMIN], tours: [userRole.ADMIN], + helpers: [userRole.ADMIN], } } }; diff --git a/backend/src/controllers/guide.controller.js b/backend/src/controllers/guide.controller.js index ee5e2855..e1f432cf 100644 --- a/backend/src/controllers/guide.controller.js +++ b/backend/src/controllers/guide.controller.js @@ -1,5 +1,6 @@ const bannerService = require("../service/banner.service"); -const linkService = require("../service/link.service"); +const guidelogService = require("../service/guidelog.service"); +const helperLinkService = require("../service/helperLink.service"); const popupService = require("../service/popup.service"); class GuideController { @@ -10,12 +11,12 @@ class GuideController { if (!url || typeof url !== 'string') { return res.status(400).json({ errors: [{ msg: "URL is missing or invalid" }] }); } - const [banner, popup, link] = await Promise.all([ + const [banner, popup, helperLink] = await Promise.all([ bannerService.getBannerByUrl(url), popupService.getPopupByUrl(url), - linkService.getLinkByUrl(url), + helperLinkService.getAllHelpersWithLinks(), ]); - res.status(200).json({ banner, popup, link }); + res.status(200).json({ banner, popup, helperLink }); } catch (error) { internalServerError( "GET_GUIDES_BY_URL_ERROR", @@ -31,11 +32,26 @@ class GuideController { if (!url || typeof url !== 'string') { return res.status(400).json({ errors: [{ msg: "URL is missing or invalid" }] }); } - if (!userId || typeof url !== 'userId') { + if (!userId || typeof userId !== 'string') { return res.status(400).json({ errors: [{ msg: "userId is missing or invalid" }] }); } - + const [completePopupLogs, completeBannerLogs, completeHelperLogs] = await Promise.all([ + guidelogService.getCompletePopupLogs(userId), + guidelogService.getCompleteBannerLogs(userId), + guidelogService.getCompleteHelperLogs(userId), + ]); + + const popupIds = completePopupLogs.map(log => log.guideId); + const bannerIds = completeBannerLogs.map(log => log.guideId); + const helperLinkIds = completeHelperLogs.map(log => log.guideId); + + const [banner, popup, helperLink] = await Promise.all([ + bannerService.getIncompleteBannersByUrl(url, bannerIds), + popupService.getIncompletePopupsByUrl(url, popupIds), + helperLinkService.getIncompleteHelpers(helperLinkIds), + ]); + res.status(200).json({ banner, popup, helperLink }); } catch (error) { internalServerError( diff --git a/backend/src/controllers/helperLink.controller.js b/backend/src/controllers/helperLink.controller.js index 07bbe0b0..94463a43 100644 --- a/backend/src/controllers/helperLink.controller.js +++ b/backend/src/controllers/helperLink.controller.js @@ -185,6 +185,19 @@ class LinkController { } } + async getAllHelpersWithLinks(_, res) { + try { + const links = await helperService.getAllHelpersWithLinks(); + res.status(200).json(links); + } catch (err) { + const { statusCode, payload } = internalServerError( + "GET_ALL_HELPERS_WITH_LINKSERROR", + err.message + ); + res.status(statusCode).json(payload); + } + } + async getHelpersByUserId(req, res) { try { const userId = req.user.id; diff --git a/backend/src/routes/helperLink.routes.js b/backend/src/routes/helperLink.routes.js index 8a97f007..a77e090a 100644 --- a/backend/src/routes/helperLink.routes.js +++ b/backend/src/routes/helperLink.routes.js @@ -1,18 +1,22 @@ const express = require("express"); const helper = require("../controllers/helperLink.controller"); const authenticateJWT = require("../middleware/auth.middleware"); - +const settings = require('../../config/settings'); +const accessGuard = require('../middleware/accessGuard.middleware'); const helperController = helper.controller; + const router = express.Router(); +const teamPermissions = settings.team.permissions; + -router.use(authenticateJWT); +router.post("/add_helper", authenticateJWT, accessGuard(teamPermissions.helpers), helperController.addHelper); +router.get("/get_helpers", authenticateJWT, helperController.getHelpersByUserId); +router.get("/get_helpers_with_links", authenticateJWT, helperController.getAllHelpersWithLinks); +router.get("/all_helpers", authenticateJWT, helperController.getAllHelpers); +router.get("/get_helper/:id", authenticateJWT, helperController.getHelperById); +router.put("/edit_helper/:id", authenticateJWT, accessGuard(teamPermissions.helpers), helperController.editHelper); +router.delete("/delete_helper/:id", authenticateJWT, accessGuard(teamPermissions.helpers), helperController.deleteHelper); -router.route("/add_helper").post(helperController.addHelper); -router.route("/get_helpers").get(helperController.getHelpersByUserId); -router.route("/all_helpers").get(helperController.getAllHelpers); -router.route("/get_helper/:id").get(helperController.getHelperById); -router.route("/edit_helper/:id").put(helperController.editHelper); -router.route("/delete_helper/:id").delete(helperController.deleteHelper); module.exports = router; diff --git a/backend/src/service/guidelog.service.js b/backend/src/service/guidelog.service.js index 9819aa85..c6b43052 100644 --- a/backend/src/service/guidelog.service.js +++ b/backend/src/service/guidelog.service.js @@ -1,5 +1,6 @@ const db = require("../models"); const GuideLog = db.GuideLog; +const { GuideType } = require('../utils/guidelog.helper'); class GuideLogService { async addGuideLog({ guideType, userId, guideId, completed }) { @@ -22,6 +23,50 @@ class GuideLogService { async getAllGuideLogs() { return await GuideLog.findAll(); } + + async getCompleteBannerLogs(userId) { + try { + return await GuideLog.findAll({ + where: { + userId: userId, + completed: true, + guideType: GuideType.BANNER + }, + }); + } catch (err) { + throw new Error(`Failed to retrieve banner log for user ${userId}: ${err.message}`); + } + } + + async getCompletePopupLogs(userId) { + try { + return await GuideLog.findAll({ + where: { + userId: userId, + completed: true, + guideType: GuideType.POPUP + }, + }); + } catch (err) { + throw new Error(`Failed to retrieve popup log for user ${userId}: ${err.message}`); + } + } + + async getCompleteHelperLogs(userId) { + try { + return await GuideLog.findAll({ + where: { + userId: userId, + completed: true, + guideType: GuideType.LINK + }, + }); + } catch (err) { + throw new Error(`Failed to retrieve helper link log for user ${userId}: ${err.message}`); + } + } + + async getCompleteGuideLogs(userId) { try { return await GuideLog.findAll({ diff --git a/backend/src/service/helperLink.service.js b/backend/src/service/helperLink.service.js index ce0c7a1e..6ffced26 100644 --- a/backend/src/service/helperLink.service.js +++ b/backend/src/service/helperLink.service.js @@ -1,3 +1,4 @@ +const { Op } = require("sequelize"); const db = require("../models"); const HelperLink = db.HelperLink; const Link = db.Link; @@ -17,6 +18,31 @@ class HelperLinkService { }); } + async getAllHelpersWithLinks() { + return await HelperLink.findAll({ + include: [ + { + model: Link, + as: "links", + }, + ] + }); + } + + async getIncompleteHelpers(ids) { + return await HelperLink.findAll({ + include: [ + { + model: Link, + as: "links", + }, + ], + where: { + id: { [Op.notIn]: ids } + } + }); + } + async getHelpersByUserId(userId) { return await HelperLink.findAll({ where: { From b368d094235195101209a37d8534285d395ab29a Mon Sep 17 00:00:00 2001 From: erenfn <81182796+erenfn@users.noreply.github.com> Date: Wed, 11 Dec 2024 04:23:37 +0300 Subject: [PATCH 63/66] Update guide.routes.js --- backend/src/routes/guide.routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/routes/guide.routes.js b/backend/src/routes/guide.routes.js index b7df280b..8cab74ef 100644 --- a/backend/src/routes/guide.routes.js +++ b/backend/src/routes/guide.routes.js @@ -3,7 +3,7 @@ const guideController = require("../controllers/guide.controller.js"); const router = express.Router(); -router.get("/get_guides_by_url", guideController.getGuidesByUrl); +router.post("/get_guides_by_url", guideController.getGuidesByUrl); router.get("/get_incomplete_guides_by_url", guideController.getIncompleteGuidesByUrl); module.exports = router; From dd16c3caf16f8bc4631019d37ea97c97d115b024 Mon Sep 17 00:00:00 2001 From: erenfn Date: Wed, 11 Dec 2024 04:25:37 +0300 Subject: [PATCH 64/66] added getPopupByApiAndClientId --- backend/src/service/popup.service.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/backend/src/service/popup.service.js b/backend/src/service/popup.service.js index d736cb25..48a73584 100644 --- a/backend/src/service/popup.service.js +++ b/backend/src/service/popup.service.js @@ -63,7 +63,24 @@ class PopupService { throw new Error("Error retrieving Popup by URL"); } }; - + + async getPopupByApiAndClientId(apiId, clientId) { + try { + return await Popup.findAll({ + include: [ + { + model: db.User, + as: "creator", + where: { apiId } + }, + ], + where: { clientId }, + order: [['createdAt', 'DESC']], + }); + } catch (error) { + throw new Error("Error retrieving popups for the given API and Client ID"); + } + } async getIncompletePopupsByUrl(url, ids) { try { From 2be6c41b13712605d989f4a9ea54700f2f238e06 Mon Sep 17 00:00:00 2001 From: d02ev Date: Tue, 17 Dec 2024 01:09:11 +0530 Subject: [PATCH 65/66] resolved merge issues --- frontend/src/scenes/popup/CreatePopupPage.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/scenes/popup/CreatePopupPage.jsx b/frontend/src/scenes/popup/CreatePopupPage.jsx index cbbb6720..c428eeee 100644 --- a/frontend/src/scenes/popup/CreatePopupPage.jsx +++ b/frontend/src/scenes/popup/CreatePopupPage.jsx @@ -145,7 +145,8 @@ const CreatePopupPage = () => { ? `Error: ${error.response.data.message}` : "An unexpected error occurred. Please try again."; toastEmitter.emit(TOAST_EMITTER_KEY, errorMessage); - + } + } const handleButtonClick = (index) => { setActiveButton(index); @@ -200,7 +201,6 @@ const CreatePopupPage = () => { )} /> ); - }; -export default CreatePopupPage; +export default CreatePopupPage; \ No newline at end of file From 3e945a6f54b426182a3be20bec066d1d4e062364 Mon Sep 17 00:00:00 2001 From: d02ev Date: Tue, 17 Dec 2024 01:11:34 +0530 Subject: [PATCH 66/66] updated server url and api key allowed values --- backend/src/controllers/team.controller.js | 24 ++++--- backend/src/utils/team.helper.js | 15 ++-- .../src/scenes/settings/CodeTab/CodeTab.jsx | 68 ++++++++++++------- frontend/src/utils/constants.js | 8 ++- 4 files changed, 76 insertions(+), 39 deletions(-) diff --git a/backend/src/controllers/team.controller.js b/backend/src/controllers/team.controller.js index 8d25b84d..a6bb06a2 100644 --- a/backend/src/controllers/team.controller.js +++ b/backend/src/controllers/team.controller.js @@ -66,12 +66,10 @@ const getTeamCount = async (req, res) => { const getServerUrlAndApiKey = async (req, res) => { try { let { serverUrl, apiKey } = await teamService.fetchServerUrlAndApiKey(); - apiKey = decryptApiKey(apiKey); - const data = { - serverUrl, - apiKey - } - return res.status(200).json(data); + const decryptedApiKey = apiKey === null || apiKey === "" ? "" : decryptApiKey(apiKey); + serverUrl = serverUrl === null ? "" : serverUrl; + + return res.status(200).json({ serverUrl, apiKey: decryptedApiKey}); } catch (err) { const { statusCode, payload } = internalServerError( "GET_SERVER_URL_AND_API_KEY_ERROR", @@ -125,12 +123,22 @@ const setConfig = async (req, res) => { const validationErrors = validationResult(req); if (!validationErrors.isEmpty()) { - return res.status(400).json({ errors: validationErrors.array() }); + const errors = []; + validationErrors.array().forEach(err => { + errors.push(err.msg); + }); + return res.status(400).json({ errors }); } try { const { serverUrl, apiKey } = req.body; - const encryptedApiKey = encryptApiKey(apiKey); + let encryptedApiKey; + + if (apiKey === null || apiKey === "" || apiKey === undefined) { + encryptedApiKey = ""; + } else { + encryptedApiKey = encryptApiKey(apiKey); + } await teamService.addServerUrlAndApiKey(serverUrl, encryptedApiKey); return res.status(200).json({ message: "Server URL and API Key Set Successfully" }); diff --git a/backend/src/utils/team.helper.js b/backend/src/utils/team.helper.js index fa241d01..1616b16b 100644 --- a/backend/src/utils/team.helper.js +++ b/backend/src/utils/team.helper.js @@ -17,6 +17,10 @@ const decryptApiKey = (apiKey) => { } const validateServerUrl = url => { + if (url === "") { + return { valid: true, errors: null } + } + const errors = []; if (!URL_PROTOCOL_REGEX.test(url)) { @@ -42,13 +46,16 @@ const validateServerUrl = url => { const validateSetConfig = [ check('apiKey') - .exists().withMessage('API Key is required') + .optional({ + values: ["", null, undefined], + }) .isString().withMessage('API Key must be a string') - .trim() - .notEmpty().withMessage('API Key cannot be empty'), + .trim(), check('serverUrl') - .optional() + .optional({ + values: ["", null, undefined] + }) .isString().withMessage('Server URL must be a string') .trim() .custom(value => { diff --git a/frontend/src/scenes/settings/CodeTab/CodeTab.jsx b/frontend/src/scenes/settings/CodeTab/CodeTab.jsx index 2ccedd2f..edb871c4 100644 --- a/frontend/src/scenes/settings/CodeTab/CodeTab.jsx +++ b/frontend/src/scenes/settings/CodeTab/CodeTab.jsx @@ -8,12 +8,41 @@ import { generateApiKey } from "../../../utils/generalHelper"; import { emitToastError } from "../../../utils/guideHelper"; import { setConfig, getConfig } from '../../../services/teamServices'; import toastEmitter, { TOAST_EMITTER_KEY } from "../../../utils/toastEmitter"; +import { URL_REGEX } from "../../../utils/constants"; const CodeTab = () => { const [apiKey, setApiKey] = useState('') const [serverUrl, setServerUrl] = useState('') const [isLoading, setIsLoading] = useState(false); + const validateServerUrl = url => { + const errors = []; + + if (url === "") { + return { valid: true, errors: null }; + } + + if (!URL_REGEX.PROTOCOL.test(url)) { + errors.push("Invalid or missing protocol (must be 'http://' or 'https://').") + } + + const domainMatch = url.match(URL_REGEX.DOMAIN); + if (!domainMatch) { + errors.push("Invalid domain name (must include a valid top-level domain like '.com')."); + } else { + const domain = domainMatch[1]; + if (!/^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(domain)) { + errors.push(`Malformed domain: '${domain}'.`); + } + } + + if (errors.length === 0) { + return { valid: true, errors: null } + } + + return { valid: false, errors } + }; + useEffect(() => { const getServerUrlAndApiKey = async () => { try { @@ -28,6 +57,8 @@ const CodeTab = () => { }, []) const handleUrlChange = (e) => { + + setServerUrl(e.target.value); }; @@ -40,28 +71,15 @@ const CodeTab = () => { } const onSave = async () => { - if (!serverUrl.trim()) { - toastEmitter.emit(TOAST_EMITTER_KEY, 'Server URL cannot be empty'); - return; - } + const { valid, errors } = validateServerUrl(serverUrl); - try { - const url = new URL(serverUrl); - if (!['http:', 'https:'].includes(url.protocol)) { - toastEmitter.emit(TOAST_EMITTER_KEY, 'Invalid URL protocol must be http or https'); - return; - } - } catch { - toastEmitter.emit(TOAST_EMITTER_KEY, 'Invalid server URL'); + if (!valid) { + errors.forEach(err => { + toastEmitter.emit(TOAST_EMITTER_KEY, err); + }); return; } - - if (!apiKey.trim()) { - toastEmitter.emit(TOAST_EMITTER_KEY, 'API key cannot be empty'); - return; - } - try { setIsLoading(true); const response = await setConfig(serverUrl, apiKey); @@ -80,15 +98,15 @@ const CodeTab = () => { {/* api key */}
-

API key:

+

API key:

-
{/* server url */}
@@ -96,13 +114,13 @@ const CodeTab = () => { - -
-

Code in your webpage

+

Code in your webpage

Code snippet to copy in your web page between {""} and {""}. Make sure you edit the API URL. diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 54add205..04b8681a 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -1,12 +1,16 @@ // API constants //local environment -// export const API_BASE_URL = 'http://localhost:3000/api/'; +export const API_BASE_URL = 'http://localhost:3000/api/'; //staging environment -export const API_BASE_URL = 'https://onboarding-demo.bluewavelabs.ca/api/'; +// export const API_BASE_URL = 'https://onboarding-demo.bluewavelabs.ca/api/'; // Other constants export const APP_TITLE = 'Bluewave Onboarding'; export const SUPPORT_EMAIL = 'support@bluewave.com'; export const roles = Object.freeze(["admin", "member"]); +export const URL_REGEX = Object.freeze({ + PROTOCOL: /^(https?:\/\/)/, + DOMAIN: /^https?:\/\/([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/, +}); \ No newline at end of file