@@ -1,19 +0,0 @@ -import fetch from 'cross-fetch' - -export function fetchToCrossfetch() { - global.fetch = (...params: Parameters) => { - let url = params[0] - - const baseUrl = 'http://localhost:3000/' - - if ( - typeof url === 'string' && - !(url as string).startsWith(baseUrl) && - !(url as string).includes('http') - ) { - url = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) + params[0] : baseUrl + params[0] - } - - return fetch(url, params[1]) - } -} Binary files a/public/pages/image-model/1.jpg and /dev/null differ Binary files a/public/pages/image-model/10.jpg and /dev/null differ Binary files a/public/pages/image-model/11.jpg and /dev/null differ Binary files a/public/pages/image-model/12.jpg and /dev/null differ Binary files a/public/pages/image-model/13.jpg and /dev/null differ Binary files a/public/pages/image-model/14.jpg and /dev/null differ Binary files a/public/pages/image-model/15.jpg and /dev/null differ Binary files a/public/pages/image-model/16.jpg and /dev/null differ Binary files a/public/pages/image-model/17.jpg and /dev/null differ Binary files a/public/pages/image-model/18.jpg and /dev/null differ Binary files a/public/pages/image-model/19.jpg and /dev/null differ Binary files a/public/pages/image-model/2.jpg and /dev/null differ Binary files a/public/pages/image-model/20.jpg and /dev/null differ Binary files a/public/pages/image-model/21.jpg and /dev/null differ Binary files a/public/pages/image-model/22.jpg and /dev/null differ Binary files a/public/pages/image-model/23.jpg and /dev/null differ Binary files a/public/pages/image-model/24.jpg and /dev/null differ Binary files a/public/pages/image-model/25.jpg and /dev/null differ Binary files a/public/pages/image-model/26.jpg and /dev/null differ Binary files a/public/pages/image-model/27.jpg and /dev/null differ Binary files a/public/pages/image-model/3.jpg and /dev/null differ Binary files a/public/pages/image-model/4.jpg and /dev/null differ Binary files a/public/pages/image-model/5.jpg and /dev/null differ Binary files a/public/pages/image-model/6.jpg and /dev/null differ Binary files a/public/pages/image-model/7.jpg and /dev/null differ Binary files a/public/pages/image-model/8.jpg and /dev/null differ Binary files a/public/pages/image-model/9.jpg and /dev/null differ Binary files a/public/pages/main/capibara.png and /dev/null differ Binary files a/public/pages/main/chat-bots.png and /dev/null differ Binary files a/public/pages/main/copywriting.png and /dev/null differ Binary files a/public/pages/main/flux.png and /dev/null differ Binary files a/public/pages/main/lion.png and /dev/null differ Binary files a/public/pages/main/woman.png and /dev/null differ Binary files a/public/pages/upscale/woman-result.jpg and /dev/null differ Binary files a/public/pages/upscale/woman.jpg and /dev/null differ @@ -1,10 +1,6 @@ - - \ No newline at end of file + + @@ -1,5 +1,3 @@ - - \ No newline at end of file + + @@ -1,70 +0,0 @@ -.card { - background-color: var(--new-ui-main-color); - width: 381px; - height: 227px; - border-radius: 15px; - margin-right: 20px; - margin-top: 20px; - - cursor: pointer; - padding: 30px; - box-sizing: border-box; - - @media (max-width: 420px) { - width: 92vw; - } - - .description { - margin-top: 20px; - - .title { - font-weight: 600; - } - - .text { - color: var(--new-ui-gray-color); - font-weight: 400; - margin-top: 6px; - font-size: 15px; - } - } -} -.blocked { - display: flex; - align-items: center; - justify-content: center; - position: absolute; - top: 20px; - right: 20px; - background-color: white; - border-radius: 100px; - padding-right: 20px; - padding: 8px 12px; - - span { - color: #ff2372; - font-weight: 500; - padding-left: 10px; - font-size: 14px; - } -} -.locked { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.7); - border-radius: 15px; - padding-right: 20px; - - span { - color: white; - padding-top: 10px; - font-weight: 500; - } -} @@ -24,5 +24,5 @@ height: 25px; border-radius: 7px; border: var(--new-ui-ctrl-f-button-border); - background: var(--new-ui-ctrl-f-button-bg); + background: var(--new-ui-ctrl-f-button-bg); } @@ -1,21 +1,17 @@ -import React, { useCallback, useEffect, useRef, useState } from 'react' -import { Autocomplete, Avatar, Box, Popover, Stack, TextField, Typography } from '@mui/material' +import React from 'react' +import { Avatar, Box, Popover, Stack, Typography } from '@mui/material' import Button from '@mui/material/Button' -import axios from 'axios' import Image from 'next/image' import Link from 'next/link' import { useRouter } from 'next/router' -import { signOut, useSession } from 'next-auth/react' -import { useTranslation } from 'next-i18next' +import { signOut } from 'next-auth/react' import styles from '#/app/layout/styles/styles.module.css' import { useBalanceStore } from '#/entities/balance/model/use-balance-store' import { useThemeStore } from '#/entities/theme/model/use-theme-store' import { useUserStore } from '#/entities/user-account' -import { InputStyleDark, InputStyleLight, TooltipCustom } from '#/shared' -import { ShortModel } from '#/shared/api/models/models' -import { API_URL } from '#/shared/lib/constants' +import { TooltipCustom } from '#/shared' import { declineToken } from '#/shared/lib/helpers/get-token' import { IProps } from '#/shared/lib/types/entities' import { NavigationSearch } from '#/widgets/navigation-search' @@ -33,30 +29,19 @@ const languages: Record = { const InfoBar: React.FC = ({ device }) => { const theme = useThemeStore((state) => state.theme) + const { change: changeTheme } = useThemeStore() - const balance = useBalanceStore((state) => state.balance) - const { getUserBalance } = useBalanceStore() + const { balance } = useBalanceStore() const { getUser } = useUserStore() - const { pathname, replace } = useRouter() - - const { data } = useSession() - const { email, first_name, last_name, profile_picture_link, account_type, show_balance } = getUser() const [anchorEl, setAnchorEl] = React.useState(null) const [anchorEl2, setAnchorEl2] = React.useState(null) - // Инициализация баланса при загрузке компонента - useEffect(() => { - if (data?.access) { - getUserBalance(data.access) - } - }, [data?.access, getUserBalance]) - const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget) } @@ -1,10 +1,9 @@ +// Zustand stores export { useThemeStore } from '#/entities/theme/model/use-theme-store' -export { useUserStore } from '#/entities/user-account/model/use-user-store' -export { useUserReferralStore } from '#/entities/user-account/model/use-user-referral-store' -export { useSettingsStore } from '#/entities/user-account/model/use-settings-store' export { useBalanceStore } from '#/entities/balance/model/use-balance-store' -export { useNotificationStore } from './use-notification-store' +export { useNotificationStore } from './use-notification-store' export { useParamsStore } from './use-params-store' export { usePendingStore } from '#/features/pending/model/use-pending-store' -export { useStepperStore } from '#/features/register-business/model/use-stepper-store' -export { useCopyStore } from '#/features/use-copy/model/use-copy-store' +export { useSettingsStore } from '#/entities/user-account/model/use-settings-store' +export { useUserReferralStore } from '#/entities/user-account/model/use-user-referral-store' +export { useUserStore } from '#/entities/user-account/model/use-user-store' @@ -1,7 +1,4 @@ - - :root[data-theme='light'] { - --scrol-bar-color: #e5e5e5; --air-color: #8280ff; --background-color-main: #ffffff; --background-color-additional: #ffffff; @@ -23,7 +20,6 @@ --new-ui-bg-app-color: #eff0f2; --new-ui-main-color: white; --new-ui-gray-color: #a4aab5; - --new-ui-element-bg: #ffffff; --new-ui-gray-text-color: #868686; --new-ui-text-color: #2b2b42; --new-ui-border: 2px solid #eff0f2; @@ -37,7 +33,6 @@ } :root[data-theme='dark'] { - --scrol-bar-color: #49494a; --air-color: #8280ff; --background-color-main: #303030; --background-color-page: #303030; @@ -77,6 +72,9 @@ margin: 0; } +html { +} + body { max-width: 100vw; background-color: var(--new-ui-bg-app-color); @@ -84,13 +82,6 @@ body { font-feature-settings: 'lnum' 1; } -button { - outline: none; - border: none; - background-color: transparent; - cursor: pointer; -} - a { color: inherit; text-decoration: none; @@ -381,25 +372,20 @@ textarea { .rdw-editor-toolbar { background-color: transparent !important; - padding: 20px 0 !important; + padding-bottom: 15px !important; border: none !important; - border-bottom: 1px solid var(--copy-border) !important; - border-top: 1px solid var(--copy-border) !important; + border-bottom: 1px solid #eff0f2 !important; } .rdw-dropdown-wrapper { background-color: transparent !important; border: 2px solid var(--new-ui-bg-app-color) !important; border-radius: 10px !important; - padding: 0 !important; + padding: 10px !important; height: 36px !important; min-width: 40px !important; } -.rdw-dropdown-selectedtext { - padding: 0 16px 0 12px !important; -} - .rdw-dropdown-wrapper:hover { box-shadow: none !important; } @@ -414,13 +400,10 @@ textarea { } .rdw-dropdown-optionwrapper { - border: none !important; - border-radius: 10px !important; width: 100% !important; - margin-top: 12px !important; + margin-top: 15px !important; overflow: hidden; color: inherit !important; - background-color: var(--background-color-main) !important; overflow-y: hidden !important; } @@ -429,50 +412,14 @@ textarea { } .rdw-dropdown-optionwrapper > li { - color: var(--new-ui-text-color) !important; - padding: 0 16px 0 12px !important; -} - -.rdw-dropdown-optionwrapper > li:hover { - background-color: var(--new-ui-gray-color) !important; -} - -.rdw-dropdownoption-active { - background: var(--new-ui-gray-color) !important; + color: inherit !important; } .rdw-dropdown-optionwrapper:hover { - border: none !important; - box-shadow: none !important; + box-shadow: none; color: inherit !important; } -.rdw-dropdown-carettoclose { - border-radius: 5px !important; - border-bottom-color: var(--new-ui-gray-color) !important; -} - -.rdw-dropdown-carettoopen { - border-radius: 5px !important; - border-top-color: var(--new-ui-gray-color) !important; -} - -.rdw-text-align-wrapper { - margin: 0 !important; -} - -.rdw-list-wrapper { - margin: 0 !important; -} - -.rdw-history-wrapper { - margin: 0 !important; -} - -.rdw-block-wrapper { - margin: 0 !important; -} - .border-bottom-1px-gray { border-bottom: 1px solid #eff0f2 !important; } @@ -499,8 +446,7 @@ textarea { *::-webkit-scrollbar-track { background: initial; - /*margin: 21px 0;*/ - margin: 5px 0; + margin: 21px 0; } *::-webkit-scrollbar-thumb { @@ -518,266 +464,10 @@ textarea { transition-duration: 250ms; } -.rotate-0{ - transform: rotate(0deg); - transition: all; - transition-duration: 250ms; -} - - -/*COPY*/ -.toolbarClassName{ - align-items: center; - gap: 15px; -} -.wrapperClassName{ - -} - -.editorClassName{ - border: 1px solid transparent; - transition: border-color 0.3s; - cursor: text; -} - -.editorClassName div:focus{ - outline: none !important; - border-color: transparent !important; -} - -.editorClassName div .public-DraftStyleDefault-block{ - display: inline-block; - padding:0 1px; - margin: 0.5em 0 !important; -} - -.public-DraftEditor-content{ - overflow-y: scroll; - max-height: calc(75vh - 200px) ; - - @media (max-width: 768px) { - max-height: calc(70vh - 200px) ; - } - -} - - -.public-DraftEditor-content::-webkit-scrollbar{ - height: 5px; - width: 2px; -} - -.public-DraftEditor-content::-webkit-scrollbar-track { - background: initial; - margin: 21px 0; -} - -.public-DraftEditor-content::-webkit-scrollbar-thumb { - background-color: rgba(217, 217, 217, 0.49); - border-radius: 5px; -} - -.inline{ - gap:3px; - margin: 0 !important; -} - -.inline-btn{ - width: 12px; - height: 25px !important; - margin: 0 !important; - padding: 0 !important; -} - -.rdw-option-active{ - background: rgba(229, 229, 229, 0.18) !important; - -webkit-box-shadow: inset 0 0 5px #c1c1c1 !important; - -moz-box-shadow: inset 0 0 5px #c1c1c1 !important; - box-shadow: inset 0 0 5px #c1c1c1 !important; - outline: none !important; -} - -.copy-color{ - color:var(--copy-color); - border-color: var(--copy-border); - -} - -.title-h1 { - font-weight: 600; - font-size: 34px; - @media (max-width: 768px) { - font-size: 28px; - } -} - -.title-h2 { - font-weight: 600; - font-size: 28px; - - @media (max-width: 768px) { - font-size: 24px; - } -} - -.item-enter { - opacity: 0; - transform: translateY(-20px); -} -.item-enter-active { - opacity: 1; - transform: translateY(0); - transition: all 500ms; -} -.item-exit { - opacity: 1; - transform: translateY(0); -} -.item-exit-active { - opacity: 0; - transform: translateY(-20px); - transition: all 500ms; -} - -.opacity-enter { - opacity: 0; -} -.opacity-enter-active { - opacity: 1; - transition: all 500ms; -} -.opacity-exit { - opacity: 1; -} -.opacity-exit-active { - opacity: 0; - transition: all 500ms; -} - -/*COPY*/ -.toolbarClassName { - align-items: center; - gap: 15px; -} -.wrapperClassName { -} - -.editorClassName { - border: 1px solid transparent; - transition: border-color 0.3s; - cursor: text; -} - -.editorClassName div:focus { - outline: none !important; - border-color: transparent !important; -} - -.editorClassName div .public-DraftStyleDefault-block { - display: inline-block; - padding: 0 1px; - margin: 0.5em 0 !important; -} - -.public-DraftEditor-content { - overflow-y: scroll; - max-height: calc(75vh - 200px); - - @media (max-width: 768px) { - max-height: calc(70vh - 200px); - } -} - -.public-DraftEditor-content::-webkit-scrollbar { - height: 5px; - width: 2px; -} - -.public-DraftEditor-content::-webkit-scrollbar-track { - background: initial; - margin: 21px 0; -} - -.public-DraftEditor-content::-webkit-scrollbar-thumb { - background-color: rgba(217, 217, 217, 0.49); - border-radius: 5px; -} - -.inline { - gap: 3px; - margin: 0 !important; -} - -.inline-btn { - width: 12px; - height: 25px !important; - margin: 0 !important; - padding: 0 !important; -} - -.rdw-option-active { - background: rgba(229, 229, 229, 0.18) !important; - -webkit-box-shadow: inset 0 0 5px #c1c1c1 !important; - -moz-box-shadow: inset 0 0 5px #c1c1c1 !important; - box-shadow: inset 0 0 5px #c1c1c1 !important; - outline: none !important; -} - -.copy-color { - color: var(--copy-color); - border-color: var(--copy-border); -} - -.title-h1 { - font-weight: 600; - font-size: 34px; - color: var(--new-ui-text-color); - @media (max-width: 768px) { - font-size: 28px; - } -} - -.title-h2 { - font-weight: 600; - font-size: 28px; - color: var(--new-ui-text-color); - @media (max-width: 768px) { - font-size: 24px; - } -} - -.item-enter { - opacity: 0; - transform: translateY(-20px); -} -.item-enter-active { - opacity: 1; - transform: translateY(0); - transition: all 500ms; -} -.item-exit { - opacity: 1; - transform: translateY(0); -} -.item-exit-active { - opacity: 0; - transform: translateY(-20px); - transition: all 500ms; -} - -.opacity-enter { - opacity: 0; -} -.opacity-enter-active { - opacity: 1; - transition: all 500ms; -} -.opacity-exit { - opacity: 1; -} -.opacity-exit-active { - opacity: 0; - transition: all 500ms; +.rotate-0 { + transform: rotate(0deg); + transition: all; + transition-duration: 250ms; } button { @@ -884,9 +574,6 @@ button { background-color: var(--air-color); } -.class-chat-bot-_slug_{ - overflow: hidden !important; -} .node-enter { opacity: 0 !important; @@ -1 +0,0 @@ - \ No newline at end of file @@ -1,4 +0,0 @@ - - - \ No newline at end of file @@ -1,4 +0,0 @@ - - - \ No newline at end of file @@ -1,4 +0,0 @@ - - - \ No newline at end of file @@ -1,4 +0,0 @@ - - - \ No newline at end of file @@ -1,6 +0,0 @@ - - - - \ No newline at end of file @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file @@ -1,12 +0,0 @@ - - - - - - - - - - \ No newline at end of file @@ -1,11 +0,0 @@ - - - - - - - - - - - @@ -1,3 +0,0 @@ - - - \ No newline at end of file @@ -1,5 +1,11 @@ - - + + \ No newline at end of file @@ -1,6 +0,0 @@ - - - - - - @@ -1,6 +0,0 @@ - - - \ No newline at end of file @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file @@ -1,10 +0,0 @@ - - - \ No newline at end of file @@ -1,8 +0,0 @@ - - - - \ No newline at end of file @@ -1,5 +0,0 @@ - - - \ No newline at end of file @@ -1,5 +0,0 @@ - - - - - @@ -1,5 +0,0 @@ - - - \ No newline at end of file @@ -1,5 +0,0 @@ - - - \ No newline at end of file @@ -1,5 +0,0 @@ - - - \ No newline at end of file @@ -1,5 +0,0 @@ - - - \ No newline at end of file @@ -1,5 +0,0 @@ - - - \ No newline at end of file @@ -1,5 +0,0 @@ - - - \ No newline at end of file @@ -1,8 +0,0 @@ - - - - \ No newline at end of file @@ -1,3 +0,0 @@ - - - @@ -1,3 +0,0 @@ - - - @@ -1,31 +0,0 @@ -import { API_URL } from '#/shared/lib/constants' - -export class CopywriteProxy { - static async getTemplates(token?: string): Promise { - try { - const response = await fetch(`${API_URL}/copywrite/templates`, { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - return await response.json() - } catch (error) { - console.error('Error fetching templates:', error) - return [] - } - } - - static async getGeneration(token?: string): Promise { - try { - const response = await fetch(`${API_URL}/copywrite/generation`, { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - return await response.json() - } catch (error) { - console.error('Error fetching generation:', error) - return [] - } - } -} \ No newline at end of file @@ -1,118 +0,0 @@ -import { useThemeStore } from '#/app/store/use-stores' -import { TooltipCustom } from '#/shared' -import { API_URL } from '#/shared/lib/constants' -import { InputStyleSmallLight, InputStyleSmallDark } from '#/shared/ui/input' -import { TableRow, TableCell, TextField, Stack } from '@mui/material' -import { useMask } from '@react-input/mask' -import axios from 'axios' -import { useSession } from 'next-auth/react' -import Image from 'next/image' -import { useState, useMemo, useEffect } from 'react' - -export interface KeyRowProps extends ApiKeyDTO { - deleteKey: (name: string) => void - keyValue: string -} - -export const KeyRow = ({ - key, - name, - user, - keyValue, - deleteKey, - token_limit, - created_at, - expires_at, - ...props -}: KeyRowProps) => { - const [isCopy, setIsCopy] = useState(false) - const [limit, setLimit] = useState(token_limit) - const theme = useThemeStore((state) => state.theme) - const { data: session } = useSession() - - const inputRef = useMask({ - mask: '_'.repeat(10), - replacement: { - _: /\d+/, - }, - }) - - const copy = (text: string) => { - navigator.clipboard.writeText(text) - setIsCopy(true) - setTimeout(() => setIsCopy(false), 3000) - } - - const computedLimit = useMemo(() => { - return limit === '' || limit === 'Бесконечно' ? null : Number(limit) - }, [limit]) - - useEffect(() => { - let timeout = window.setTimeout(() => { - console.log(limit) - if (limit !== token_limit) { - axios.patch( - API_URL + '/public/api-key', - { token_limit: computedLimit, name }, - { headers: { Authorization: `Bearer ${session?.access}` } } - ) - } - }, 1000) - return () => window.clearTimeout(timeout) - }, [limit]) - - return ( - - - {name} - - - {keyValue} - - - setLimit(e.target.value)} - sx={theme === 'light' ? { ...InputStyleSmallLight } : { ...InputStyleSmallDark }} - /> - - - {created_at.split('T')[0]} - - - {expires_at !== null ? expires_at : 'Бессрочно'} - - - - {isCopy ? ( - - ) : ( - - copy(keyValue)} - src={'/svg/copy.svg'} - width={20} - height={20} - style={{ cursor: 'pointer' }} - alt={'copy'} - /> - - )} - - deleteKey(name)} - src={'/svg/delete.svg'} - width={20} - height={20} - style={{ cursor: 'pointer' }} - alt={'delete'} - /> - - - - - ) -} @@ -1,18 +1,6 @@ -import axios from 'axios' +import { api } from '#/shared/api' +import { BalanceDTO } from '../types' -import { API_URL } from '#/shared/lib/constants' - -export const getBalance = async (token: string): Promise => { - try { - const { data } = await axios.get<{ current_token_balance: number }>(API_URL + '/payments/user-balance', { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - return data.current_token_balance - } catch (err) { - return 0 - } +export function getBalance() { + return api.get('/payments/user-balance') } - @@ -0,0 +1 @@ +export * from './balance.routes' \ No newline at end of file @@ -0,0 +1,2 @@ +export * from './use-balance-store' +export * from './use-balance' \ No newline at end of file @@ -5,29 +5,17 @@ import { getBalance } from '../api/balance.routes' export interface BalanceStore { balance: number loading: boolean - getUserBalance: (token: string | undefined | null) => Promise + setBalance: (balance: number) => void } export const useBalanceStore = create((set, get) => { - async function getUserBalance(token: string | undefined | null) { - if (!token) { - set({ balance: 0 }) - return - } - - try { - set({ loading: true }) - const balance = await getBalance(token) - set({ balance, loading: false }) - } catch (error) { - set({ loading: false }) - console.error('Error fetching balance:', error) - } + function setBalance(balance: number) { + set({ ...get(), balance: Math.round(balance) }) } return { balance: 0, loading: false, - getUserBalance, + setBalance, } }) @@ -0,0 +1,26 @@ +import { withPending } from '#/shared' +import { makePrivateRequest } from '#/shared/api' +import { useShowDataStore } from '#/shared/lib/hooks' +import { getBalance } from '../api' +import { useBalanceStore } from './use-balance-store' + +export function useBalance() { + const { balance, setBalance } = useBalanceStore() + + const { showMessage } = useShowDataStore() + + const [fetchUserBalance, pending] = withPending(makePrivateRequest(async () => { + const { status, data } = await getBalance() + + if (status !== 200) return showMessage('Ошибка получения баланса пользователя') + + setBalance(data.current_token_balance) + })) + + return { + fetchUserBalance, + balance, + setBalance, + pending + } +} @@ -0,0 +1,3 @@ +export interface BalanceDTO { + current_token_balance: number +} @@ -0,0 +1 @@ +export * from './balance' \ No newline at end of file @@ -1,10 +1,3 @@ -import { useBalanceStore } from './model/use-balance-store' -export { useBalanceStore } from './model/use-balance-store' -export { getBalance } from './api/balance.routes' - -// Экспорт для обратной совместимости с Redux -export const getUserBalance = (token: string | undefined | null) => { - const { getUserBalance: getUserBalanceFromStore } = useBalanceStore.getState() - return getUserBalanceFromStore(token) -} +export * from './api' +export * from './model' \ No newline at end of file @@ -1,5 +0,0 @@ -import { api } from '#/shared/api' - -export const checkBackendHealth = async () => { - return await api.get('/healthz') -} \ No newline at end of file @@ -1 +0,0 @@ -export * from './error-modal.routes' \ No newline at end of file @@ -1 +0,0 @@ -export * from './use-check-presense-backend' \ No newline at end of file @@ -1,42 +0,0 @@ -import { useState } from 'react' -import { checkBackendHealth } from '../api' -import { useShowDataStore } from '#/shared/lib/hooks' -import { useRouter } from 'next/router' -import { ERROR_MESSAGE, getModalById } from '#/features/modals' -import { withPending } from '#/shared' - -export const useCheckBackendHealth = () => { - const [buttonText, setButtonText] = useState('Проверить доступность') - const [isBackendAvailable, setIsBackendAvailable] = useState(false) - const modal = getModalById(ERROR_MESSAGE) - - const { showMessage } = useShowDataStore() - const { push } = useRouter() - - const goHome = () => { - push('/') - modal.setState(false) - } - - const [handleButtonClick, isLoading] = withPending(async () => { - const { status } = await checkBackendHealth() - - if (status === 200) { - setIsBackendAvailable(true) - setButtonText('Перейти на главную страничку') - } - if ([502, 503, 504].includes(status)) { - showMessage('Сервер ещё недоступен, ждём вас чуть позже', 'error') - } - }) - - return { - handleButtonClick, - buttonText, - setButtonText, - isBackendAvailable, - setIsBackendAvailable, - isLoading, - goHome - } -} @@ -1,140 +0,0 @@ -.wrapper { - width: 100vw; - height: 100vh; - display: flex; - align-items: center; - justify-content: center; -} -.loader { - width: 50px; -} -.container { - position: relative; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - height: 80dvh; - gap: 47px; - - &__action { - height: 50px; - display: flex; - justify-content: center; - align-items: center; - width: fit-content; - // width: 100%; - } - - &__loader { - width: 50px; - height: 50px; - } - - &__content { - display: flex; - flex-direction: column; - - gap: 50px; - h1 { - color: #ffffff; - font-weight: 700; - font-size: 96px; - letter-spacing: -0.02em; - line-height: 1; - margin: 0; - } - - h2 { - color: #ffffff; - font-weight: 600; - font-size: 32px; - letter-spacing: -0.02em; - line-height: 1.2; - margin: 0 0 20px 0; - } - - p { - color: #a4aab5; - font-weight: 500; - font-size: 18px; - letter-spacing: -0.01em; - line-height: 1.4; - margin: 0; - } - } - - &__image { - width: 403px; - height: 382px; - background-size: cover; - } - - &__button { - width: fit-content; - padding: 14.5px 51px; - height: 50px; - - font-size: 15px; - font-weight: 500; - line-height: 140%; - letter-spacing: -1%; - transition: opacity 0.3s ease, transform 0.3s ease; - } - - &__fadeIn { - animation: fadeIn 0.4s ease-in forwards; - } - - &__fadeOut { - animation: fadeOut 0.4s ease-out forwards; - } -} - -@media screen and (max-width: 950px) { - .container { - flex-direction: column-reverse; - text-align: center; - - &__content { - align-items: center; - } - } - .footer { - display: none; - } -} - -@media screen and (max-width: 450px) { - .container__image { - width: 207px; - height: 196px; - } -} -@media screen and (max-width: 400px) { - .container__content h1 { - font-size: 48px; - } -} - -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(10px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -@keyframes fadeOut { - from { - opacity: 1; - transform: translateY(0); - } - to { - opacity: 0; - transform: translateY(-10px); - } -} \ No newline at end of file @@ -1,86 +0,0 @@ -import { ERROR_MESSAGE, getModalById, PlateTemplate } from '#/features/modals' -import { InfoPageTemplate } from '#/shared/ui/info-page-template' -import { useRouter } from 'next/router' -import styles from './error-message-fullscreen.module.scss' -import { CommonButton } from '#/shared/ui/button' -import Image from 'next/image' -import Link from 'next/link' -import { useEffect, useRef, useState } from 'react' -import { useCheckBackendHealth } from '../model' -import { checkBackendHealth } from '../api' -import { c, Loader } from '#/shared' -import { CSSTransition, SwitchTransition } from 'react-transition-group' - -export const ErrorMessageFullscreen = () => { - const { - buttonText, - isLoading, - handleButtonClick, - isBackendAvailable, - goHome, - setIsBackendAvailable, - setButtonText, - } = useCheckBackendHealth() - - const buttonRef = useRef(null) - - const modal = getModalById(ERROR_MESSAGE) - - useEffect(() => { - setIsBackendAvailable(false) - setButtonText('Проверить доступность') - }, [modal.state]) - - return ( - -
-
-
-

Упс!

-
-

Сервис временно недоступен

-

- В настоящее время наш сайт не отвечает из-за технических работ или - перегрузки серверов. -

-
- -
- - - - {buttonText} - - - -
-
- - {'network-error'} -
-
- - ) -} @@ -1 +0,0 @@ -export * from './styles.static' \ No newline at end of file @@ -1,8 +0,0 @@ - - -export interface ImageStyle { - category: string; - image: string; - uid: string; - label: string; -} \ No newline at end of file @@ -1,53 +0,0 @@ -.style { - border-radius: 10px; - position: relative; - &__image { - border-radius: 10px; - width: 100%; - height: 100%; - object-fit: cover; - } - - &__popup { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba($color: #151518, $alpha: 0.8); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 10px; - border-radius: 10px; - - opacity: 0; - transition: opacity 0.3s ease; - - &:hover { - opacity: 1; - } - - span { - color: var(--new-ui-text-color); - max-width: 80px; - text-align: center; - font-size: 14px; - } - } - - &__favorite{ - position: absolute; - top: 10px; - right: 10px; - z-index: 1; - background-color: rgba($color: #A4AAB5, $alpha: 0.1); - width: 30px; - height: 30px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 100%; - } -} @@ -1,39 +0,0 @@ -import React from 'react' -import { ImageStyle } from '../types' -import styles from './image-style.module.scss' -import Image from 'next/image' -import HeartSvg from '#/assets/svg/heart.svg?react' -import { c } from '#/shared' - -type ImageStyleProps = ImageStyle & - React.HTMLAttributes & { - inFavorites: boolean - onCnageFavorite: Function - } - -export const ScopedImageStyle = ({ - label, - image, - className, - inFavorites, - onCnageFavorite, - ...props -}: ImageStyleProps) => { - return ( - - - {label} - - ) -} @@ -1 +0,0 @@ -export * from './image-style' \ No newline at end of file @@ -1,2 +0,0 @@ -export * from './ui' -export * from './types' \ No newline at end of file @@ -1,8 +1,8 @@ -import { Message, MessageSend, PaginatedMessagesResponse } from '../types' +import { Message, MessageSend } from '../types' import { api } from '#/shared/api' export async function getMessagesBySlug(chat: string, offset?: number, limit = 10) { - return await api.get(`/chats/${chat}/messages`, { params: { limit, offset } }) + return await api.get(`/chats/${chat}/messages`, { params: { limit, offset } }) } export async function postMessage(uid: string, { file, content, info }: MessageSend) { @@ -1,4 +1,5 @@ import { API_URL } from '#/shared/lib/constants' +import { IMessageRequest } from '#/shared/lib/types/types-gpt' import axios, { AxiosResponse } from 'axios' import { MediaMessageListResponse, Message, MessageSend } from '../types' import { api } from '#/shared/api' @@ -5,11 +5,9 @@ export interface ChatBotMessagesStore { messages: Message[] loading: boolean loaded: boolean - count: number setMessages: (messages: Message[]) => void setLoading: (loading: boolean) => void setLoaded: (loaded: boolean) => void - setCount: (count: number) => void clearMessages: () => void } @@ -26,10 +24,6 @@ export const useChatBotMessages = create((set, get) => { set({ ...get(), loaded }) } - function setCount(count: number) { - set({ ...get(), count }) - } - function clearMessages() { set({ ...get(), messages: [], loaded: false }) } @@ -38,12 +32,9 @@ export const useChatBotMessages = create((set, get) => { messages: [], loading: false, loaded: false, - count: 0, - setLoaded, setMessages, setLoading, clearMessages, - setCount, } }) @@ -1,42 +1,34 @@ -import { create } from 'zustand' -import { Message } from '../types' + import { create } from 'zustand' + import { Message } from '../types' -export interface ImageBotMessagesStore { - messages: Message[] - loading: boolean - loaded: boolean - count: number - setMessages: (messages: Message[]) => void - setLoading: (loading: boolean) => void - setLoaded: (loaded: boolean) => void - setCount: (count: number) => void -} + export interface ImageBotMessagesStore { + messages: Message[] + loading: boolean + loaded: boolean + setMessages: (messages: Message[]) => void + setLoading: (loading: boolean) => void + setLoaded: (loaded: boolean) => void + } -export const useImageBotMessages = create((set, get) => { - function setMessages(messages: Message[]) { - set({ ...get(), messages }) - } + export const useImageBotMessages = create((set, get) => { + function setMessages(messages: Message[]) { + set({ ...get(), messages }) + } - function setLoading(loading: boolean) { - set({ ...get(), loading }) - } + function setLoading(loading: boolean) { + set({ ...get(), loading }) + } - function setLoaded(loaded: boolean) { - set({ ...get(), loaded }) - } + function setLoaded(loaded: boolean) { + set({ ...get(), loaded }) + } - function setCount(count: number) { - set({ ...get(), count }) - } - - return { - messages: [], - loading: false, - loaded: false, - count: 0, - setLoaded, - setMessages, - setLoading, - setCount - } -}) + return { + messages: [], + loading: false, + loaded: false, + setLoaded, + setMessages, + setLoading, + } + }) @@ -1,10 +0,0 @@ - -import { createUseContext } from '#/shared' -import { createContext } from 'react' -import { useImageErrors } from './use-image-errors' - -export const ImageErrorsContext = createContext | null>(null) - -export const useImageErrorsContext = createUseContext(ImageErrorsContext) - -export const ImageErrorsContextProvider = ImageErrorsContext.Provider @@ -1,10 +1,7 @@ -export * from './use-message-time' export * from './chat-bot-messages.store' export * from './use-user-message-actions' export * from './use-user-message-image' export * from './use-chat-messages-events' export * from './image-bot-messages.store' export * from './use-image-messages-events' -export * from './use-image-icons' -export * from './image-errors-context' -export * from './use-image-errors' +export * from './use-image-icons' \ No newline at end of file @@ -1,9 +0,0 @@ -import { useRef } from 'react' - -export function useImageErrors() { - const errors = useRef([]) - - return { - errors, - } -} @@ -19,7 +19,22 @@ export function useImageMessagesEvents() { const callback = useCallback( ({ id, content }: MessageEventStreamResponse) => { - const file = chunks.current.join('') + content + const joined = chunks.current.join('') + content + + const mimeTypeRegex = /^data:(image\/(jpeg|png|gif|bmp|webp));base64,(.+)$/ + + const matches = chunks.current.at(0) + ? chunks.current[0].match(mimeTypeRegex) + : content.match(mimeTypeRegex) + + const type = matches && matches.at(1) ? matches[1] : 'image/webp' + + const blob = new Blob( + [Uint8Array.from(base64Decode(joined.split(',')[1]), (c) => c.charCodeAt(0))], + { type } + ) + + const file = URL.createObjectURL(blob) const { messages } = useImageBotMessages.getState() @@ -1,45 +0,0 @@ -import { useEffect, useState } from 'react' - -export function useMessageTime(created_at: string | null | undefined) { - const formatVariant = { - 60: (value: number) => getOneOrMore(value / 60, 'минуту', 'минут'), - 3600: (value: number) => getOneOrMore(value / 3600, 'час', 'часов'), - 86400: (value: number) => getOneOrMore(value / 86400, 'день', 'дней'), - } - - const [formatedDate, setFormatedDate] = useState(getFormatedMessageTime(created_at)) - - useEffect(() => { - setInterval(() => { - setFormatedDate(getFormatedMessageTime(created_at)) - }, 1000 * 60) - }, []) - - function getOneOrMore(value: number, one: string, more: string) { - const formated = Math.floor(value) === 0 ? 1 : Math.floor(value) - - return formated !== 0 ? `${formated} ${more} назад` : `${formated} ${one} назад` - } - - function getFormatedMessageTime(created_at?: string | null) { - if (!created_at) created_at = '' - - const date = new Date() - const createdDate = new Date(created_at) - - // разница в секундах - const difference = (date.getTime() - createdDate.getTime()) / 1000 - - for (const [key, value] of Object.entries(formatVariant).reverse()) { - if (difference > Number(key)) { - return value(difference) - } - } - - return formatVariant['60'](difference) - } - return { - getFormatedMessageTime, - formatedDate, - } -} @@ -17,13 +17,6 @@ export interface Message { model: string } -export interface OptimisticMessage extends Omit {} - -export interface PaginatedMessagesResponse { - count: number - items: Message[] -} - export interface MessageEventStreamResponse { id: string content: string @@ -31,6 +24,5 @@ export interface MessageEventStreamResponse { export interface MediaMessageListResponse { id: string - count: number - items: Message[] + messages: Message[] } @@ -79,7 +79,6 @@ export const BotMessage = memo( > @@ -16,10 +16,6 @@ position: relative; border-radius: 15px; - &_disabled { - cursor: default; - } - @media screen and (max-width: 1000px) { width: 291px; height: 291px; @@ -66,9 +62,7 @@ flex-direction: column; align-items: start; position: relative; - overflow-y: hidden; - overflow-x: visible; - + overflow: hidden; width: 250px; height: 250px; font: unset; @@ -10,8 +10,6 @@ import Image from 'next/image' import { useMediaQuery } from 'usehooks-ts' import { useEventStore } from '#/shared/lib/event-source' import { eventBus } from '#/shared/classes' -import { GALLERY_IMAGES, getModalById } from '#/features/modals' -import { useImageErrorsContext } from '../model' interface FileImageMessageProps extends Message {} @@ -22,56 +20,39 @@ export const FileImageMessage = ({ file, content, uid, ...message }: FileImageMe const [loaded, setLoaded] = useState(false) - const { errors } = useImageErrorsContext() - const [hasEvent, setHasEvent] = useState(false) - const modal = getModalById(GALLERY_IMAGES) - - const error = useMemo(() => errors.current.find((e) => e === uid), [errors.current]) - useEffect(() => { eventBus.subscribe(`image-generate-${uid}`, (data) => { setHasEvent(data) }) }, []) - const text = useMemo(() => (error ? 'Ошибка загрузки' : 'Изображение загружается'), [error]) - return ( - ) } @@ -1,14 +1,14 @@ .wrap { padding: 12px 9px; background-color: var(--new-ui-bg-color); - min-width: unset !important; - border-radius: 100px; + min-width: unset !important; + border-radius: 100px; - margin-top: 10px; + margin-top: 10px; - &__content { - display: flex; - flex-direction: column; - gap: 20px; - } + &__content{ + display: flex; + flex-direction: column; + gap: 20px; + } } @@ -1,5 +1,5 @@ import { PopupTemplate, getPopupById } from '#/shared/ui/popup' -import React, { Dispatch, SetStateAction } from 'react' +import React from 'react' import styles from './image-icons-popup.module.scss' import { Message } from '../types' import { CommonTooltip } from '#/shared/ui/tooltip' @@ -8,41 +8,33 @@ import BlankLinkSvg from '#/assets/svg/blank-link.svg?react' import DownloadSvg from '#/assets/svg/download.svg?react' import { CSSTransition } from 'react-transition-group' -interface ImageIconsPopupProps extends Message { - opened: boolean - setOpened: Dispatch> -} +interface ImageIconsPopupProps extends Message {} + +export const ImageIconsPopup = ({ uid, file, content }: ImageIconsPopupProps) => { + const popup = getPopupById(uid) -export const ImageIconsPopup = ({ uid, file, content, opened, setOpened }: ImageIconsPopupProps) => { const { downloadFile } = useImageIcons() return ( - -
-
- - - - - - -
+ +
+ + + + + +
- +
) } @@ -8,27 +8,22 @@ import GamburgerSvg from '#/assets/svg/gamburger.svg?react' import styles from './image-icons.module.scss' import { getPopupById } from '#/shared/ui/popup' import { ImageIconsPopup } from './image-icons-popup' -import { useState } from 'react' export interface ImageIconsProps extends Message {} export const ImageIcons = ({ uid, file, content, ...message }: ImageIconsProps) => { - const [opened, setOpened] = useState(false) + const popup = getPopupById(uid) return ( ) } @@ -1,102 +1,5 @@ -.container { - padding: 5px; - background-color: var(--new-ui-element-bg); - display: flex; - gap: 30px; - border-radius: 15px; - height: 100%; - text-align: left; - @media screen and (max-width: 1000px) { - flex-direction: column; - } -} -.description { - padding: 10px; - width: max-content; - min-width: 220px; - display: flex; - flex-direction: column; - justify-content: space-between; - &__trash { - background-color: rgba($color: #b01e1e, $alpha: 0.25) !important; - // margin-left: auto; - } - &__time { - font-weight: 600; - font-size: 20px; - width: max-content; - margin-bottom: 7px; - } - &__content { - color: #a4aab5; - } - &__model { - display: flex !important; - align-items: center; - width: max-content; - gap: 5px; - margin-bottom: 20px; - } - &__controls { - display: flex; - align-items: center; - gap: 5px; - padding-top: 20px; - } -} - -@keyframes skeleton { - 0% { - background-color: rgba($color: #a4aab5, $alpha: 0.1); - } - 100% { - background-color: rgba($color: #a4aab5, $alpha: 0.3); - } -} - -.images { - display: grid; - grid-template-columns: repeat(4, 1fr); - height: 100%; - width: 100%; - gap: 5px; - @media screen and (max-width: 1400px) { - grid-template-columns: repeat(2, 1fr); - } - @media screen and (max-width: 600px) { - grid-template-columns: repeat(1, 1fr); - } - &__skeleton { - width: 100%; - height: 100%; - border-radius: 10px; - background-color: rgba($color: #a4aab5, $alpha: 0.1); - animation: skeleton 1s infinite ease-in-out alternate; - position: absolute; - top: 0; - left: 0; - } - &__imagebox { - position: relative; - } - - &__image { - width: 100%; - height: auto; - border-radius: 10px; - min-height: 314px; - object-fit: cover; - - &_empty { - visibility: collapse; - } - } -} - -.button { - padding: 9px 12px; - background-color: rgba(#a4aab5, 0.1); - border-radius: 8px; -} +.message{ + position: relative; +} \ No newline at end of file @@ -1,77 +1,33 @@ -import React, { memo, useMemo, useState } from 'react' -import { Message } from '#/entities/message' +import React, { CSSProperties, MouseEventHandler, useEffect, useMemo } from 'react' + import styles from './image-message.module.scss' -import Image from 'next/image' -import { c, formatDate } from '#/shared' -import { CommonBagde } from '#/shared/ui/badge' -import NeuralSvg from '#/assets/svg/neural.svg?react' -import RepeatSvg from '#/assets/svg/repeat.svg?react' -import DownloadSvg from '#/assets/svg/download.svg?react' -import TrashSvg from '#/assets/svg/trash.svg?react' -import { useMessageTime } from '../model' +import { c } from '#/shared' +import { Message } from '../types' +import { ArchiveImageMessage } from './archive-image-message' +import { FileImageMessage } from './file-image-message' -interface ImageMessageProps extends Omit { - file: string | null - ref: any +interface ImageMessageProps extends Message { + onClick?: MouseEventHandler + className?: string + style?: CSSProperties } -export const ImageMessage = memo(({ file, uid, created_at, model, content }: ImageMessageProps) => { - const { formatedDate } = useMessageTime(created_at) +export const ImageMessage = ({ file, onClick, className, style, ...message }: ImageMessageProps) => { + const extention = useMemo(() => { + if (!file) return 'unknown' - const [imageLoadStates, setImageLoadStates] = useState(new Array(4).fill(false)) + const matches = file.match(/\.(\w+)\?/) - return ( -
-
-
-

{formatedDate}

- - - {model} - -

- {content && content.length < 30 ? content : content ? `${content.slice(0, 30)}...` : ''} -

-
-
- - - -
-
-
- {new Array(4).fill(file).map((el, index) => ( -
- - setImageLoadStates((prev) => { - const newState = [...prev] - newState[index] = true - return newState - }) - } - height={300} - src={el} - alt={`image-${uid}-${index}`} - /> + return matches && matches[1] + }, [file]) - {!imageLoadStates[index] && ( -
- )} -
- ))} -
+ return ( +
+ {extention === 'zip' ? ( + + ) : ( + + )}
) -}) +} @@ -1,3 +0,0 @@ -.message{ - position: relative; -} \ No newline at end of file @@ -1,33 +0,0 @@ -import React, { CSSProperties, MouseEventHandler, useEffect, useMemo } from 'react' - -import styles from './image-message.module.scss' -import { c } from '#/shared' -import { Message } from '../types' -import { ArchiveImageMessage } from './archive-image-message' -import { FileImageMessage } from './file-image-message' - -interface ImageMessageProps extends Message { - onClick?: MouseEventHandler - className?: string - style?: CSSProperties -} - -export const ImageOldMessage = ({ file, onClick, className, style, ...message }: ImageMessageProps) => { - const extention = useMemo(() => { - if (!file) return 'unknown' - - const matches = file.match(/\.(\w+)\?/) - - return matches ? matches[1] : 'unknown' - }, [file]) - - return ( -
- {extention === 'zip' ? ( - - ) : ( - - )} -
- ) -} @@ -1,11 +0,0 @@ - - -.popup{ - min-width: 200px; - &__title{ - color: #A4AAB5; - font-weight: 600; - font-size: 16px; - margin-bottom: 20px; - } -} \ No newline at end of file @@ -1,26 +0,0 @@ -import { getPopupById, PopupTemplate } from '#/shared/ui/popup' -import { POPUP_IMAGE_SETTINGS } from '#/shared/ui/popup' -import React, { useEffect } from 'react' -import styles from './image-settings.popup.module.scss' -import { InferenceParams } from '#/entities/model-entity' -import { BotParamsMap } from '#/features/bot-params' - -export const ImageSettingsPopup = () => { - const popup = getPopupById(POPUP_IMAGE_SETTINGS) - - const botParams = popup.getStoreProperty('botParams') - const currentVersion = popup.getStoreProperty('currentVersion') - - return ( - -
-

НАСТРОЙКИ

- {currentVersion && ( -
- -
- )} -
-
- ) -} @@ -1,6 +1,2 @@ -export * from './image-message' -export * from './image-settings.popup' export * from './user-message' -export * from './user-message' -export * from './image-message' -export * from './image-old-message' +export * from './image-message' \ No newline at end of file @@ -66,7 +66,7 @@ export const UserMessage = forwardRef(
) : ( - +
( )}

30 ? 'pre-wrap' : 'pre', + whiteSpace: message.content.length > 30 ? 'pre-wrap' : 'pre', }} > {message.content} @@ -1,4 +1,4 @@ export * from './types' export * from './api' export * from './model' -export * from './ui' +export * from './ui' \ No newline at end of file @@ -1,4 +1,3 @@ export * from './use-chat-bot' export * from './use-chat-bot-params.store' -export * from './use-image-bot-params.store' -export * from './use-images-bots' +export * from './use-image-bot-params.store' \ No newline at end of file @@ -1,21 +0,0 @@ -import { useState } from 'react' -import { useSession } from 'next-auth/react' -import { ShortModel } from '../types' -import { getImageBots } from '../api' -import { makePrivateRequest } from '#/shared/api' - -export function useImagesBots() { - const [bots, setBots] = useState([]) - - const fetchBots = makePrivateRequest(async () => { - const response = await getImageBots() - - if (response.status < 400) setBots(response.data) - }) - - return { - bots, - fetchBots, - setBots, - } -} @@ -1,4 +1,5 @@ -import React, { useMemo } from 'react' +import React, { useEffect, useMemo } from 'react' +import { Avatar, Box, Button, Typography } from '@mui/material' import Image from 'next/image' import Link from 'next/link' @@ -8,6 +9,7 @@ import BlockedSvg from '#/assets/svg/blocked.svg?react' import LockSvg from '#/assets/svg/lock.svg?react' import { ShortModel } from '#/entities/model-entity' import { c } from '#/shared/lib/helpers' +import { useThemeAndDevice } from '#/shared/lib/hooks' import { CommonButton } from '#/shared/ui/button' import { SvgIcon } from '#/shared/ui/svg' @@ -1,164 +0,0 @@ -import axios, { AxiosResponse } from 'axios' -import { User } from 'next-auth' - -import { API_URL } from '#/shared/lib/constants' -import { IOffer } from '#/widgets/payment/model/payment' -import { AccountType, DataForLogin, PayProductRequest, PayProductResponse } from '../model/types' - -export async function getPaymentsPlans(token: string): Promise { - try { - const { data } = await axios.get(API_URL + '/payments/plans', { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - return data - } catch (err) { - return null - } -} - -export async function payProduct(token: string | null, plan: string): Promise { - if (token === null) { - return null - } - - try { - const { data } = await axios.post>( - API_URL + '/payments/plans', - { - uid: plan, - is_test: 1, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ) - return data.payment_url - } catch (err) { - return null - } -} - -export async function changePassword( - token: string | null, - password_1: string, - password_2: string, - current_password: string -): Promise { - try { - const { status } = await axios.put( - API_URL + '/auth/reset-pass', - { - password_1, - password_2, - current_password, - }, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ) - - return status - } catch (err) { - return 400 - } -} - -export async function getApiKeys(token: string | null): Promise { - try { - const { data } = await axios.get(API_URL + '/public/api-key', { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - return data - } catch (err) { - return null - } -} - -export async function createApiKeys(data: any, token: string | null): Promise { - try { - const { data: result } = await axios.post(API_URL + '/public/api-key', data, { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - return result - } catch (err) { - return null - } -} - -export async function deleteApiKey(name: any, token: string | null): Promise { - try { - const { data: result, status } = await axios.delete(API_URL + '/public/api-key', { - data: { - name, - }, - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - return status - } catch (err) { - return null - } -} - -export async function loginByEmail(email: string, password: string): Promise { - try { - const { data } = await axios.post>(API_URL + '/auth/login', { - email, - password, - }) - - return data - } catch (err) { - return null - } -} - -export async function removeSub(token?: string) { - try { - const { status } = await axios.delete(API_URL + '/payments/plans', { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - return status - } catch (err) { - return null - } -} - -export const getAccountType = async (token: string | null | undefined): Promise => { - if (!token) { - return 'regular' - } - - try { - const { data } = await axios.get>( - API_URL + '/auth/account-type', - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ) - - return data.status - } catch (err) { - return 'regular' - } -} @@ -1,8 +1,8 @@ import axios from 'axios' import { API_URL } from '#/shared/lib/constants' -import { IUserSetting } from '../types' +import { IUserSetting } from '../model/types' export const addUserSettings = async ( token: string, @@ -1,19 +0,0 @@ -import axios from 'axios' - -import { API_URL } from '#/shared/lib/constants' -import { IUserSetting } from '../types/dto.user' - - -export const getUserSettings = async (token: string): Promise => { - try { - const { data } = await axios.get(API_URL + '/api/users/settings/', { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - return data - } catch (err) { - return [] - } -} @@ -1,2 +1,3 @@ export * from './settings.routes' export * from './user.routes' +export * from './user-account.routes' @@ -3,7 +3,7 @@ import axios from 'axios' import { API_URL } from '#/shared/lib/constants' import { getUpdatedSettingsLocal } from '../lib/helpers/update-setting-local' -import { IUserSetting, SettingValueType } from '../types' +import { IUserSetting, SettingValueType } from '../model/types' export const updateUserSettings = async ( token: string, @@ -1,18 +1,24 @@ -interface UserDTO { +import { api } from '#/shared/api' + +export type ResponseAllInfo = { uid: string first_name: string last_name: string username: string - created_at: string // ISO 8601 format + created_at: string email: string is_active: boolean - is_superuser: boolean is_staff: boolean + show_balance: boolean is_confirmed: boolean + is_social: boolean + social_auth: string[] is_subscribed_to_emails: boolean - show_balance: boolean - profile_picture_link: string + profile_picture_link: string | null account_type: string + referral_code: { + code: string + } token: { access: string refresh: string @@ -21,17 +27,22 @@ interface UserDTO { uid: string plan: { uid: string - title: string price: string tokens_per_plan: string + title: string duration: string - accessed_models: string[] + accessed_models: string[] | null } - last_payment_at: string // ISO 8601 date - next_payment_at: string // ISO 8601 date + last_payment_at: string + next_payment_at: string current_token_balance: number } - referral_code: string | null - is_social: boolean - social_auth: any[] // Assuming it can hold any type of objects +} + +export function getUserInfo() { + return api.get('/auth/me') +} + +export function updateEmailSubscription() { + return api.patch('/auth/email-sub', {}) } @@ -1,6 +1,6 @@ import { Device } from '#/shared/lib/types/entities' -import { IUserSetting, SettingType } from '../../types' +import { IUserSetting, SettingType } from '../../model/types' interface IProps { settings: Omit | null @@ -1,4 +1,4 @@ -import { IUserSetting, SettingValueType } from '../../types' +import { IUserSetting, SettingValueType } from '../../model/types' interface IProps { settings: IUserSetting[] @@ -1,4 +1,4 @@ export * from './settings-context' export * from './use-global-settings' export * from './use-user-store' -export * from './use-user' +export * from './use-user' \ No newline at end of file @@ -14,21 +14,3 @@ export interface IUserSetting { type: SettingType value: SettingValueType | any } - -export interface UserBalance { - current_token_balance: number -} - -export interface PayProductRequest { - uid: string - is_test: number -} - -export interface PayProductResponse { - payment_url: string -} - -export interface DataForLogin { - email: string - password: string -} @@ -2,9 +2,8 @@ import { create } from 'zustand' import { addUserSettings } from '../api/add-user-settings' import { updateUserSettings } from '../api/update-user-settings' -import { getUserSettings } from '../api/get-user-settings' -import { IUserSetting, SettingValueType } from '../types/dto.user' +import { IUserSetting, SettingValueType } from './types' interface IAddSettings { token: string | undefined | null @@ -35,7 +34,7 @@ export const useSettingsStore = create((set, get) => { try { set({ loading: true }) - const settings = await getUserSettings(token) + const settings: IUserSetting[] = [] set({ settings, loading: false }) localStorage.setItem('global_settings', JSON.stringify(settings)) } catch (error) { @@ -1,46 +1,6 @@ -import axios, { AxiosResponse } from 'axios' import { create } from 'zustand' -import { API_URL } from '#/shared/lib/constants' - -export type ResponseAllInfo = { - uid: string - first_name: string - last_name: string - username: string - created_at: string - email: string - is_active: boolean - is_staff: boolean - show_balance: boolean - is_confirmed: boolean - is_social: boolean - social_auth: string[] - is_subscribed_to_emails: boolean - profile_picture_link: string | null - account_type: string - referral_code: { - code: string - } - token: { - access: string - refresh: string - } - payment_plan: { - uid: string - plan: { - uid: string - price: string - tokens_per_plan: string - title: string - duration: string - accessed_models: string[] | null - } - last_payment_at: string - next_payment_at: string - current_token_balance: number - } -} +import { getUserInfo, ResponseAllInfo,updateEmailSubscription } from '../api/user-account.routes' export interface UserReferralStore { status: 'idle' | 'pending' | 'succeeded' | 'failed' @@ -54,51 +14,9 @@ export interface UserReferralStore { export const useUserReferralStore = create((set, get) => { const getAll = async (token: string | null | undefined): Promise => { - if (!token) { - return { - uid: '', - first_name: '', - last_name: '', - username: '', - created_at: '', - email: '', - is_active: false, - is_staff: false, - show_balance: true, - is_confirmed: false, - is_social: false, - social_auth: [], - is_subscribed_to_emails: false, - profile_picture_link: null, - account_type: 'regular', - referral_code: { code: '' }, - token: { access: '', refresh: '' }, - payment_plan: { - uid: '', - plan: { - uid: '', - price: '', - tokens_per_plan: '', - title: '', - duration: '', - accessed_models: null, - }, - last_payment_at: '', - next_payment_at: '', - current_token_balance: 0, - }, - } - } - try { - const { data } = await axios.get>(API_URL + '/auth/me', { - headers: { - Authorization: `Bearer ${token}`, - }, - validateStatus: (status) => status === 200, - }) - - return data + const response = await getUserInfo() + return response.data } catch (error) { console.error('Error fetching user info:', error) return { @@ -158,11 +76,7 @@ export const useUserReferralStore = create((set, get) => { if (!token) return try { - await axios.patch( - API_URL + '/auth/email-sub', - {}, - { headers: { Authorization: `Bearer ${token}` } } - ) + await updateEmailSubscription() const currentUserInfo = get().userInfo if (currentUserInfo) { @@ -1,6 +0,0 @@ -import { useUserStore } from "./use-user-store"; - -export const useUserSelector = () => { - const { getUser } = useUserStore() - return getUser() -} @@ -1,10 +1,10 @@ import { create } from 'zustand' -import { UserDTO } from '../types/dto.user' +import { UserDTO } from '../types' export interface UserStore { user: UserDTO | null setUser: (user: UserDTO) => void - getUser: () => UserDTO + getUser: () => UserDTO setLoading: (loading: boolean) => void setLoaded: (loaded: boolean) => void loading: boolean @@ -13,30 +13,32 @@ export interface UserStore { export const useUserStore = create((set, get) => { function setUser(user: UserDTO) { - set({ user }) + set({ ...get(), user }) } function getUser() { const { user } = get() - if (!user ) throw new Error("user is not defined") + if (!user) throw new Error('user is not defined') return user } function setLoading(loading: boolean) { - set({ loading }) + set({ ...get(), loading }) } function setLoaded(loaded: boolean) { - set({ loaded }) + set({ ...get(), loaded }) } return { + // s user: null, loaded: false, loading: true, + // f setUser, setLoading, setLoaded, - getUser, + getUser, } }) @@ -1,74 +0,0 @@ -import { Device } from '#/shared/lib/types/entities' - -export type UserDTO = { - uid: string - first_name: string - last_name: string - username: string - created_at: string - email: string - is_active: boolean - is_staff: boolean - show_balance: boolean - is_confirmed: boolean - is_social: boolean - social_auth: string[] - is_subscribed_to_emails: boolean - profile_picture_link: string | null - account_type: string - referral_code: { - code: string - } - token: { - access: string - refresh: string - } - payment_plan: { - uid: string - plan: { - uid: string - price: string - tokens_per_plan: string - title: string - duration: string - accessed_models: string[] | null - } - last_payment_at: string - next_payment_at: string - current_token_balance: number - } -} - -export type AccountType = 'regular' | 'business_host' | 'business_account' - -export type SettingType = 'sidemenu' - -export type SettingValueType = { - sidemenu_state?: 'opened' | 'closed' -} - -export interface IUserSetting { - id: string - device: Device - type: SettingType - value: SettingValueType -} - -export interface CreateUserUtmDTO { - utm_source: string - utm_medium: string - utm_campaign: string - utm_term: string - utm_content: string -} - -export interface CreateUserDTO { - email: string - password: string -} - -export interface CreateUserRefererDTO { - referer?: string | null -} - -export type CreateUserWithRelations = CreateUserDTO & CreateUserRefererDTO & CreateUserUtmDTO & {} @@ -1 +1 @@ -export * from './dto.user' +export * from './user.types' @@ -1,21 +1,13 @@ -// Model exports export * from './model' +export * from './types' // API exports export * from './api' -// Types exports -export * from './types/dto.user' - // Store exports export { useUserStore } from './model/use-user-store' export { useUserReferralStore } from './model/use-user-referral-store' export { useSettingsStore } from './model/use-settings-store' export { useUser } from './model/use-user' -export { useUserSelector } from './model/use-user-selector' export { useGlobalSettings } from './model/use-global-settings' export { UserSettingsContextProvider, useUserSettingsContext } from './model/settings-context' - -// API functions -export { getUserApi, getUserServer } from './api/user.routes' -export { createApiKeys, getApiKeys, loginByEmail } from './api/account-endpoints' @@ -13,8 +13,6 @@ import { DateInput } from '#/shared/ui/date-input/date-input' import styles from '../invite-person-in-business/ui/invite-modal.module.scss' -import { createApiKeys, getApiKeys } from '#/entities/user-account' - export const ApiKeyModal = ({ open, setOpen, @@ -50,7 +48,7 @@ export const ApiKeyModal = ({ ) : await accountApi.createApiKeys({ name: title !== '' ? title : keyName }, data?.access) if (result !== null) { - getApiKeys(data?.access).then((res) => { + accountApi.getApiKeys(data?.access).then((res) => { setKeys(res) setIsLoading(false) }) @@ -1,8 +1,8 @@ -import { api } from '#/shared/api' -import axios from 'axios' -import { signOut, useSession } from 'next-auth/react' -import { useRouter } from 'next/router' import { useEffect } from 'react' +import { useRouter } from 'next/router' +import { signOut, useSession } from 'next-auth/react' + +import { api } from '#/shared/api' export function useAuthSession() { const { data, update } = useSession() @@ -14,21 +14,13 @@ export function useAuthSession() { // axios.defaults.validateStatus = () => true // axios.interceptors.response.use(async ({ status, ...r }) => { // if (status !== 401) return { status, ...r } - // const session = await update('refresh') - // console.log('session::', status) - // if (!session) window.location.href = '/login' - // r.config.headers.Authorization = `Bearer ${session?.access}` - // const response = await axios.request(r.request) - // console.log('response::', response) - // return response // }) - }, [data, update]) } @@ -1,7 +1,7 @@ -import { loginByEmail } from "#/entities/user-account" +import { accountApi } from '#/shared/api/account-endpoints' export const authTelegram = async (email: any, password: any) => { - const user = await loginByEmail(email, password) + const user = await accountApi.loginByEmail(email, password) if (user !== null) { ;(window as any).Telegram.WebApp.sendData(user.token.access) @@ -9,7 +9,7 @@ export const authTelegram = async (email: any, password: any) => { } export const authTelegramYandex = async (email: any, password: any) => { - const user = await loginByEmail(email, password) + const user = await accountApi.loginByEmail(email, password) if (user !== null) { ;(window as any).Telegram.WebApp.sendData(user.token.access) @@ -0,0 +1,31 @@ +import { useParamsStore } from '#/app/store/use-params-store' +import { InferenceParams } from '#/entities/model-entity' +import React, { useEffect } from 'react' + +interface BotParamsMap { + params: InferenceParams[] + currentVersion: string | null +} + +export const useBotParamsMap = ({ params, currentVersion }: BotParamsMap) => { + const { params: includeParams, setParams: setNewParam } = useParamsStore((state) => ({ + params: state.params, + setParams: state.setParams + })) + + useEffect(() => { + if (currentVersion && params) { + const res = params.map((el) => + el.versions.length !== 0 && !el.versions.includes(currentVersion) ? null : el + ) + if (res.every((el) => el === null)) { + setNewParam({}) + } + } + }, [currentVersion, params]) + + return { + includeParams, + setNewParam, + } +} @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react' +import React from 'react' import styles from './bot-params-map.module.scss' import { SwitchFilter } from '#/features/switch-filter/' @@ -10,23 +10,18 @@ import { CommonSelect } from '#/shared/ui/common-select' interface BotParamsMap {} -export function BotParamsMap({}: BotParamsMap) { +export default function BotParamsMap({}: BotParamsMap) { const { infrerenceValues, setInferenceValueByKey, inferenceParams } = useChatBotParams() - const sortedInferenceParams = useMemo( - () => inferenceParams.sort((a, b) => (a.type === 'choices' ? 1 : -1)), - [inferenceParams] - ) - return (

- {sortedInferenceParams.map(({ key, type, name, description, values }) => { + {inferenceParams.map(({ key, type, name, description, values }) => { if (type == 'floatrange' || type == 'intrange') { return ( { const { data } = useSession() const { isLoading, isDataLoaded } = useLoadingStore() - const { loadBusinessHostData } = useBusinessHostData() + const { fetchData } = useBusinessHostData() useEffect(() => { if (data?.access && !isDataLoaded && !isLoading) { - loadBusinessHostData() + fetchData() } }, [data?.access, isDataLoaded, isLoading]) @@ -29,7 +29,6 @@ const checkIsAdditional = (model: string, isAdditional?: boolean): any => { return model } - export const useCalculating = ( model: 'gpt' | 'dalle' | 'sd', count?: number, @@ -34,11 +34,7 @@ export const useChangePassword = () => { return setError('newPassword', { message: 'Пароли не совпадают' }) } - const { data, status } = await changePassword( - modal.getStoreProperty('email')!, - password, - newPassword - ) + const { data, status } = await changePassword(modal.getStoreProperty('email')!, password, newPassword) if (status !== 200) return showMessage(data.detail) @@ -27,8 +27,7 @@ export function useChatBotPagination() { const [isHidden, setIsHidden] = useState(false) - const { messages, setMessages, loading, setLoading, loaded, setLoaded, count, setCount } = - useChatBotMessages() + const { messages, setMessages, loading, setLoading, loaded, setLoaded } = useChatBotMessages() const { showMessage } = useShowDataStore() @@ -77,24 +76,23 @@ export function useChatBotPagination() { if (!currentChat) return - const { - data: { items: result, count: countResult }, - ...response - } = await getMessagesBySlug(currentChat, offset.current, count || 10) + const { data: answer, ...response } = await getMessagesBySlug( + currentChat, + offset.current, + count || 10 + ) setLoading(false) setLoaded(true) - if (response.status >= 400 || !Array.isArray(result)) return showMessage('Ошибка загрузки чата') + if (response.status >= 400 || !Array.isArray(answer)) return showMessage('Ошибка загрузки чата') const { messages } = useChatBotMessages.getState() - setMessages([...result.reverse(), ...messages]) + setMessages([...answer.reverse(), ...messages]) - setCount(countResult) - - offset.current += result.length + offset.current += answer.length }) const callback = async function (entries: IntersectionObserverEntry[]) { @@ -144,6 +142,5 @@ export function useChatBotPagination() { refScroll, loaded, observer, - count, } } @@ -1,14 +1,14 @@ -import React, { Dispatch, SetStateAction, createRef, useEffect, useMemo, useState } from 'react' -import axios from 'axios' +import React, { createRef, Dispatch, SetStateAction, useEffect, useMemo, useState } from 'react' +import { useRouter } from 'next/router' import { useSession } from 'next-auth/react' -import { API_URL } from '../../../shared/lib/constants' -import { useCurrentChat } from '.' -import { useRouter } from 'next/router' import { ChatDTO, getChats, postChat, useChatsStore } from '../../../entities/chat' import { makePrivateRequest } from '../../../shared/api' +import { API_URL } from '../../../shared/lib/constants' import { useShowDataStore } from '../../../shared/lib/hooks' +import { useCurrentChat } from '.' + export function useChats() { const { query } = useRouter() @@ -19,21 +19,14 @@ export const ErrorReportPlate = () => { {isSend ? (

Спасибо!

-

- Ваше сообщение направлено нашим специалистам. Ответ придет на почту, указанную - при регистрации -

+

Ваше сообщение направлено нашим специалистам. Ответ придет на почту, указанную при регистрации

) : (
e.stopPropagation()}>

Сообщить об ошибке

{ id='file-input' /> @@ -63,10 +52,7 @@ export const ErrorReportPlate = () => {

Добавлено 1 изображение: {file.name}

-
@@ -0,0 +1,32 @@ +import { Dayjs } from 'dayjs' + +import { ResponseStats } from '../model/types' + +import { api } from '#/shared/api' + +export function getAdminStats( + start_date?: Dayjs | null, + end_date?: Dayjs | null, + group_by?: string, + product?: string +) { + const formatStartDate = start_date?.format('YYYY-MM-DD') + const formatEndDate = end_date?.format('YYYY-MM-DD') + + let queryParams = '?' + + const args = [ + { start_date: formatStartDate }, + { end_date: formatEndDate }, + { group_by: group_by }, + { product: product }, + ] + + args.forEach((el) => { + if (Object.values(el)[0]) { + queryParams += `&${Object.keys(el)[0]}=${Object.values(el)[0]}` + } + }) + + return api.get('/admin/stats' + queryParams) +} @@ -1,53 +1,21 @@ import React from 'react' -import axios, { AxiosResponse } from 'axios' import { Dayjs } from 'dayjs' -import { RequestStats, ResponseStats } from '#/features/get-admin-stats' -import { API_URL } from '#/shared/lib/constants' +import { getAdminStats } from '../../api/admin-stats.routes' + +import { ResponseStats } from '#/features/get-admin-stats' async function getStats( - token: string | null | undefined, start_date?: Dayjs | null, end_date?: Dayjs | null, group_by?: string, product?: string ): Promise { - const formatStartDate = start_date?.format('YYYY-MM-DD') - const formatEndDate = end_date?.format('YYYY-MM-DD') - - let queryParams = '?' - - const args = [ - { start_date: formatStartDate }, - { end_date: formatEndDate }, - { group_by: group_by }, - { product: product }, - ] - - args.forEach((el) => { - if (Object.values(el)[0]) { - queryParams += `&${Object.keys(el)[0]}=${Object.values(el)[0]}` - } - }) - - try { - const { data } = await axios.get>( - API_URL + '/admin/stats' + queryParams, - { - headers: { - Authorization: `Bearer ${token}`, - }, - } - ) - - return data - } catch (err) { - return [] - } + const response = await getAdminStats(start_date, end_date, group_by, product) + return response.data } export const useGetStats = ( - token: string | null | undefined, start_date?: Dayjs | null, end_date?: Dayjs | null, group_by?: string, @@ -59,7 +27,7 @@ export const useGetStats = ( React.useEffect(() => { setLoading(true) const handlePromise = async () => { - return await getStats(token, start_date, end_date, group_by, product).then((res) => res) + return await getStats(start_date, end_date, group_by, product).then((res) => res) } handlePromise().then((res) => { @@ -1,43 +0,0 @@ -.area { - padding: 40px; - min-width: 660px; - display: flex; - align-items: center; - justify-content: center; - background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='20' ry='20' stroke='%23A4AAB50D' stroke-width='4' stroke-dasharray='6%2c 14' stroke-dashoffset='0' stroke-linecap='round'/%3e%3c/svg%3e"); - border-radius: 20px; - background-color: var(--new-ui-element-bg); - - &__input { - display: none; - } - &__icon { - margin-bottom: 18px; - } - - &__title { - margin-bottom: 5px; - color: var(--new-ui-gray-color); - } - - &__content { - margin-bottom: 25px; - text-align: center; - } - - &__text { - color: var(--new-ui-gray-color); - } - - &__button { - display: flex; - align-items: center; - gap: 12px; - } -} - -.container { - display: flex; - flex-direction: column; - align-items: center; -} @@ -1,55 +0,0 @@ -import React, { useRef } from 'react' -import styles from './image-area.module.scss' - -import PlusSvg from '#/assets/svg/plus.svg?react' -import { c } from '#/shared' -import { CommonButton } from '#/shared/ui/button' - -interface ImageAreaProps { - files: File[] - setFiles: React.Dispatch> -} - -export const ImageArea = ({ files, setFiles }: ImageAreaProps) => { - const fileInput = useRef(null) - - function onDrop(e: React.DragEvent) { - e.preventDefault() - setFiles(Array.from(e.dataTransfer.files)) - } - - function onInputChange(e: React.ChangeEvent) { - e.preventDefault() - - const { target } = e - - if (!target.files) return - - const file = target.files.item(0)! - - if (['png', 'jpg', 'jpeg'].some((ext) => file.name.includes(ext))) { - setFiles([file]) - } - } - - return ( -
e.preventDefault()} className={styles.area}> -
- -
-

Загрузить фото

-

или просто перетащите мышью

-
- - fileInput.current?.click()} - className={styles.area__button} - variant='primary' - > - - Загрузить - -
-
- ) -} @@ -1 +0,0 @@ -export * from './image-area' \ No newline at end of file @@ -1 +0,0 @@ -export * from './ui' \ No newline at end of file @@ -1,4 +1,7 @@ -// TODO: Replace with Zustand store when needed +import { MutableRefObject, RefObject, useEffect, useState } from 'react' +import { useSession } from 'next-auth/react' + +import { getBalance } from '#/entities/balance' import { Message, MessageSend, @@ -6,16 +9,12 @@ import { useImageBotMessages, useImageMessagesEvents, } from '#/entities/message' - -import { useBalanceStore } from '#/entities/balance/model/use-balance-store' -import { Device } from '#/shared/lib/types/entities' -import { MutableRefObject, RefObject, useEffect, useState } from 'react' -import { useShowDataStore } from '#/shared/lib/hooks' import { useImageBot } from '#/entities/model-entity/model/use-image-bot' -import { useSession } from 'next-auth/react' import { makePrivateRequest } from '#/shared/api' -import { useEventSource } from '#/shared/lib/event-source' import { eventBus } from '#/shared/classes' +import { useEventSource } from '#/shared/lib/event-source' +import { useShowDataStore } from '#/shared/lib/hooks' +import { Device } from '#/shared/lib/types/entities' export function useImageBotCreateImage( device: Device, @@ -32,14 +31,10 @@ export function useImageBotCreateImage( const { setMessages, messages } = useImageBotMessages() - - const { data: session } = useSession() const { addOpenCallback, addCloseEvent } = useEventSource() - const { getUserBalance } = useBalanceStore() - const createImage = makePrivateRequest(async (dto: MessageSend) => { if (!botParams) return @@ -54,10 +49,7 @@ export function useImageBotCreateImage( if (status !== 200) return showMessage((data as { detail: string }).detail ?? 'Ошибка при получении сообщений') - // Обновляем баланс после создания изображения - if (session?.access) { - getUserBalance(session.access) - } + // TODO: Add getUserBalance to Zustand store const messages = useImageBotMessages.getState().messages @@ -1,2 +1 @@ -export * from './use-images-bot-pagination-old' export * from './use-images-bot-pagination' \ No newline at end of file @@ -1,157 +0,0 @@ -import { useParamsStore } from '#/app/store/use-stores' -import { getImagesBySlug, Message, useImageBotMessages } from '#/entities/message' -import { Device } from '#/shared/lib/types/entities' -import { getImagesGalery } from '#/widgets/messages' -import { useMediaQuery } from '@mui/material' -import { useSession } from 'next-auth/react' -import { useEffect, useRef, useState } from 'react' -import { LimitSize, Limit } from '../types' -import { useRouter } from 'next/router' -import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' -import { useImageObjectId } from '#/features/image-object-id' - -export function useImageBotPaginationOld(deviceType: Device) { - const refScrollMobile = useRef(null) - const refScrollDesktop = useRef(null) - const mobileScrollContainer = useRef(null) - const offset = useRef(0) - const observer = useRef(null) - - const [isHidden, setIsHidden] = useState(false) - - const { setImageObjectId } = useImageObjectId() - - const { query } = useRouter() - - const { messages, setLoading, setMessages, loading, setCount, count, loaded, setLoaded } = - useImageBotMessages() - - const { showMessage } = useShowDataStore() - - const { data } = useSession() - - const limits: Record = { - small: { - active: useMediaQuery('(max-height: 600px)'), - limit: 20, - firstLimit: 30, - }, - medium: { - active: useMediaQuery('(min-height: 600px) and (max-height: 900px)'), - limit: 30, - firstLimit: 50, - }, - large: { - active: useMediaQuery('(min-height: 900px)'), - limit: 45, - firstLimit: 70, - }, - } - - const fetchMessages = async (count?: number) => { - if (!data) return - - setLoading(true) - setLoaded(false) - - const { data: answer, ...response } = await getImagesBySlug( - query.slug as string, - data.access, - offset.current, - count || 10 - ) - - if (response.status >= 400 || !Array.isArray(answer.items)) - return showMessage('Ошибка загрузки чата') - - setLoaded(true) - - const messages = useImageBotMessages.getState().messages - - if (deviceType === 'desktop') setMessages([...messages, ...answer.items]) - else setMessages([...answer.items.reverse(), ...messages]) - - offset.current += answer.items.length - - setCount(answer.count) - - setImageObjectId(answer.id) - } - - const callback = async function (entries: IntersectionObserverEntry[]) { - if (!entries[0].isIntersecting) return - - if (isHidden) return setIsHidden(false) - - if (deviceType === 'desktop') { - const active = Object.values(limits).find((item) => item.active) - - if (!active) return - - return fetchMessages(offset.current > 0 ? active.limit : active?.firstLimit) - } - - const { current } = mobileScrollContainer - - if (!current) return - - const scrollBottom = current.scrollHeight - current.scrollTop - - await fetchMessages() - - setTimeout(() => { - const { current } = mobileScrollContainer - - if (!current) return - - if (offset.current === 0) current.scrollTop = current.scrollHeight - scrollBottom - else { - current.scroll({ - top: current.scrollHeight - scrollBottom, - behavior: 'smooth', - }) - } - - setLoading(false) - }, 500) - } - - function onObserverMounted() { - const currentObserver = - deviceType === 'desktop' ? refScrollDesktop.current : refScrollMobile.current - - if (!currentObserver || observer.current) return - - setMessages([]) - - observer.current = new IntersectionObserver(callback) - - observer.current.observe(currentObserver!) - } - - function isHiddenHandler() { - if (document.visibilityState === 'hidden') return setIsHidden(true) - setIsHidden(false) - } - - useEffect(() => { - document.addEventListener('visibilitychange', isHiddenHandler) - return () => document.removeEventListener('visibilitychange', isHiddenHandler) - }, []) - - return { - refScrollMobile, - refScrollDesktop, - onObserverMounted, - messages, - loading, - setLoading, - offset, - setMessages, - fetchMessages, - mobileScrollContainer, - loaded, - setLoaded, - count, - } -} @@ -1,42 +1,49 @@ import { getImagesBySlug, Message, useImageBotMessages } from '#/entities/message' import { Device } from '#/shared/lib/types/entities' +import { getImagesGalery } from '#/widgets/messages' +import { useMediaQuery } from '@mui/material' +import { useSession } from 'next-auth/react' +import { useEffect, useRef, useState } from 'react' import { LimitSize, Limit } from '../types' import { useRouter } from 'next/router' import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' import { useImageObjectId } from '#/features/image-object-id' import { makePrivateRequest } from '#/shared/api' -import { useRef } from 'react' -import { useMessagesStore } from '#/widgets/messages' -import { useSession } from 'next-auth/react' -import { useMediaQuery } from 'usehooks-ts' -export function useImageBotPagination(container: React.RefObject) { - const refScroll = useRef(null) +export function useImageBotPagination(deviceType: Device) { + const refScrollMobile = useRef(null) + const refScrollDesktop = useRef(null) + const mobileScrollContainer = useRef(null) const offset = useRef(0) + const observer = useRef(null) + + const [isHidden, setIsHidden] = useState(false) + + const { setImageObjectId } = useImageObjectId() + + const { query } = useRouter() - const { messages, loading, setLoading, addMessages } = useMessagesStore() + const { messages, setLoading, setMessages, loading } = useImageBotMessages() const { showMessage } = useShowDataStore() const { data } = useSession() - const { query } = useRouter() - const { setImageObjectId } = useImageObjectId() const limits: Record = { small: { active: useMediaQuery('(max-height: 600px)'), - limit: 10, - firstLimit: 20, + limit: 20, + firstLimit: 30, }, medium: { active: useMediaQuery('(min-height: 600px) and (max-height: 900px)'), - limit: 15, - firstLimit: 30, + limit: 30, + firstLimit: 50, }, large: { active: useMediaQuery('(min-height: 900px)'), - limit: 20, - firstLimit: 40, + limit: 45, + firstLimit: 70, }, } @@ -50,14 +57,16 @@ export function useImageBotPagination(container: React.RefObject offset.current, count || 10 ) - setLoading(false) - if (response.status >= 400 || !Array.isArray(answer.items)) + if (response.status >= 400 || !Array.isArray(answer.messages)) return showMessage('Ошибка загрузки чата') - addMessages(answer.items) + const messages = useImageBotMessages.getState().messages - offset.current += answer.items.length + if (deviceType === 'desktop') setMessages([...messages, ...answer.messages]) + else setMessages([...answer.messages.reverse(), ...messages]) + + offset.current += answer.messages.length // console.log(offset.current) @@ -65,43 +74,76 @@ export function useImageBotPagination(container: React.RefObject }) const callback = async function (entries: IntersectionObserverEntry[]) { - console.log(entries[0].isIntersecting) if (!entries[0].isIntersecting) return - if (!refScroll.current) return + if (isHidden) return setIsHidden(false) + + if (deviceType === 'desktop') { + const active = Object.values(limits).find((item) => item.active) + + if (!active) return + + return fetchMessages(offset.current > 0 ? active.limit : active?.firstLimit) + } - const scrollBottom = container.current!.scrollHeight - container.current!.scrollTop + const { current } = mobileScrollContainer - const active = Object.values(limits).find((item) => item.active) + if (!current) return - if (offset.current > 0) await fetchMessages(active?.limit) - else await fetchMessages(active?.firstLimit) + const scrollBottom = current.scrollHeight - current.scrollTop + + await fetchMessages() setTimeout(() => { - if (!container.current) return - container.current.scroll({ - top: container.current!.scrollHeight - scrollBottom + 70, - behavior: 'smooth', - }) + const { current } = mobileScrollContainer + + if (!current) return + + if (offset.current === 0) current.scrollTop = current.scrollHeight - scrollBottom + else { + current.scroll({ + top: current.scrollHeight - scrollBottom, + behavior: 'smooth', + }) + } + + setLoading(false) }, 500) } function onObserverMounted() { - if (!refScroll.current) return + setMessages([]) + + const currentObserver = + deviceType === 'desktop' ? refScrollDesktop.current : refScrollMobile.current + + if (!currentObserver || observer.current) return - const observer = new IntersectionObserver(callback, { - rootMargin: '400px', - }) + observer.current = new IntersectionObserver(callback, { rootMargin: '400px' }) - observer.observe(refScroll.current) + observer.current.observe(currentObserver!) } + function isHiddenHandler() { + if (document.visibilityState === 'hidden') return setIsHidden(true) + setIsHidden(false) + } + + useEffect(() => { + document.addEventListener('visibilitychange', isHiddenHandler) + return () => document.removeEventListener('visibilitychange', isHiddenHandler) + }, []) + return { - refScroll, + refScrollMobile, + refScrollDesktop, onObserverMounted, messages, loading, setLoading, + offset, + setMessages, fetchMessages, + mobileScrollContainer, } } @@ -4,4 +4,3 @@ gap: 16px; padding-right: 8px; } - @@ -1,4 +1,4 @@ -import React, { useMemo, useRef } from 'react' +import React from 'react' import styles from './image-bot-params-map.module.scss' import { SwitchFilter } from '#/features/switch-filter/' @@ -7,28 +7,20 @@ import { useChatBotParams, useImageBotParams } from '#/entities/model-entity' import { CommonTooltip } from '#/shared/ui/tooltip' import { RangeSlider } from '#/shared/ui/range-slider' import { CommonSelect } from '#/shared/ui/common-select' -import { c } from '#/shared' interface ImageBotParamsMap {} export function ImageBotParamsMap({}: ImageBotParamsMap) { const { infrerenceValues, setInferenceValueByKey, inferenceParams } = useImageBotParams() - const sortedInferenceParams = useMemo( - () => inferenceParams.sort((a, b) => (a.type === 'choices' ? -1 : 1)), - [inferenceParams] - ) - - const containerRef = useRef(null) - return ( -
- {sortedInferenceParams.map(({ key, type, name, description, values }, idx) => { +
+ {inferenceParams.map(({ key, type, name, description, values }) => { if (type == 'floatrange' || type == 'intrange') { return ( { - const { current } = containerRef - if (!current || !current.parentElement) return - current.parentElement!.style.overflow = state ? 'visible' : 'auto' - }} - classNameList={c(styles.select__list)} value={infrerenceValues[key]} setValue={(value) => setInferenceValueByKey(key, value)} withoutTooltip @@ -20,20 +20,9 @@ interface IProps { reverse?: boolean images: Message[] current: string | null - total?: number - offset?: number - onImageError?: (message: Message) => void } -export default function FullScreenModal({ - images, - onSlideFalse, - total, - offset, - reverse = false, - current, - onImageError, -}: IProps) { +export default function FullScreenModal({ images, onSlideFalse, reverse = false, current }: IProps) { const modal = getModalById(GALLERY_IMAGES) const { currentIndex } = useImagesLibrary(current, images) @@ -44,8 +33,6 @@ export default function FullScreenModal({ const { downloadFile } = useImageIcons() - const [index, setIndex] = useState(0) - useEffect(() => { if (reverse) setTimeout(() => { @@ -59,10 +46,6 @@ export default function FullScreenModal({ }, 400) }, [images]) - useEffect(() => { - setIndex(currentIndex) - }, [modal.state]) - return (
@@ -130,17 +113,15 @@ export default function FullScreenModal({
- {(reverse ? index > 0 : offset && total && (index === 0 ? offset < total : true)) && ( - - )} + { - setIndex(s.activeIndex) - }} onSwiper={(swiper) => setSwiper(swiper)} > {images.map((image, index) => ( - onImageError && onImageError(image)} - {...image} - /> + ))} - {total && - (!reverse - ? index < count.current - 1 - : offset && (index <= count.current - 2 ? true : offset < total)) && ( - - )} +
) @@ -5,11 +5,9 @@ import React, { useEffect } from 'react' import styles from './modal-image.module.scss' -interface ModalImageProps extends Message { - onImageError?: () => void -} +interface ModalImageProps extends Message {} -export const ModalImage = ({ file, onImageError, ...image }: ModalImageProps) => { +export const ModalImage = ({ file, ...image }: ModalImageProps) => { const [state, updateImageState] = React.useState(false) return ( @@ -22,7 +20,6 @@ export const ModalImage = ({ file, onImageError, ...image }: ModalImageProps) => onLoadingComplete={() => { updateImageState(true) }} - onError={() => onImageError && onImageError()} loading='lazy' src={file} width={'1500'} @@ -32,7 +29,6 @@ export const ModalImage = ({ file, onImageError, ...image }: ModalImageProps) => ) : ( onImageError && onImageError()} onClick={(e) => e.stopPropagation()} onLoad={() => updateImageState(true)} alt='К сожалению, изображение не загрузилось' @@ -0,0 +1,74 @@ +import React, { Dispatch, SetStateAction, useMemo } from 'react' +import Image from 'next/image' + +import styles from './modal-styles.module.scss' + +interface IProps { + modal: boolean + setModal: Dispatch> + image: string | null +} +export default function FullScreenModal({ modal, setModal, image }: IProps) { + const isSvg = useMemo(() => { + if (!image) return false + return image.includes('.svg') + }, []) + + return ( +
+
+
setModal(false)}> + + + +
+
+ {!isSvg && image ? ( + К сожалению, изображение не загрузилось + ) : ( + К сожалению, изображение не загрузилось + )} +
+
+ ) +} @@ -1,23 +0,0 @@ -import { ImageStyle } from '#/entities/image-style' -import { getModalById, PLATE_IMAGE_STYLES } from '#/features/modals' -import { useChosenStyle } from '#/widgets/images-style' -import { useEffect } from 'react' - -export function useImageInputStyles() { - const modal = getModalById(PLATE_IMAGE_STYLES) - - const { setStyle } = useChosenStyle() - - function onSetStyle(data: ImageStyle) { - setStyle(data) - modal.setState(false) - } - - function onStylesButtonClick() { - modal.setState(true, { - callback: onSetStyle, - }) - } - - return { onStylesButtonClick } -} @@ -1,71 +0,0 @@ -import { useParamsStore } from '#/app/store/use-stores' -import { Message, MessageSend, postImageMessage } from '#/entities/message' -import { Model, useImageBotParams } from '#/entities/model-entity' -import { useMessagesStore } from '#/widgets/messages' -import { useSession } from 'next-auth/react' -import { useState } from 'react' - -export function useImageInput(model: Model | null, container: React.RefObject) { - const [text, setText] = useState('') - const [image, setImage] = useState(null) - const [loading, setLoading] = useState(false) - - const { inference } = useImageBotParams() - - const { setMessages, messages, addOptimistic } = useMessagesStore() - - const includeParams = useParamsStore((state) => state.params) - - const { data: session } = useSession() - - function createMessage() { - if (!inference) return - const data = { - file: image, - content: text, - info: { - ...includeParams, - inference: inference.id, - }, - } - - onSend(data) - } - - async function onSend(param: MessageSend) { - if (!model || !session) return - - addOptimistic(param.content, param.info, model.slug) - - setLoading(true) - - setTimeout(() => { - if (!container.current) return - - const scrollBottom = container.current.scrollHeight - container.current.scrollTop - - container.current.scroll({ - top: container.current.scrollHeight + scrollBottom, - behavior: 'smooth', - }) - }, 500) - - const { data } = await postImageMessage(model.slug, param) - - setLoading(false) - - if (typeof data === 'string') return - - setMessages([...(data as Message[]), ...messages]) - } - - return { - onSend, - text, - setText, - image, - setImage, - createMessage, - loading, - } -} @@ -1,2 +0,0 @@ -export * from './image-input-styles' -export * from './image-input' \ No newline at end of file @@ -1,122 +0,0 @@ -.container { - display: flex; - align-items: center; - gap: 22px; -} -.wrapper { - display: flex; - flex-direction: column; - gap: 20px; - padding: 20px; - border-radius: 15px; - border: 1px solid rgba($color: #a4aab5, $alpha: 0.2); - background: var(--new-ui-element-bg); -} - -.controls { - display: flex; - flex-direction: column; - gap: 5px; -} - -.stroke { - height: 60px; - width: 1px; - background-color: #40404e; - - @media screen and (max-width: 800px) { - display: none; - } -} - -.rounded { - background-color: rgba($color: #a4aab5, $alpha: 0.1); - border-radius: 100%; - width: 30px; - height: 30px; - display: flex; - align-items: center; - justify-content: center; - - &__svg { - padding-left: 2px; - padding-top: 2px; - } -} - -.buttons { - display: flex; - align-items: center; - gap: 10px; - - @media screen and (max-width: 800px) { - flex-direction: column; - } -} - -.button { - background-color: rgba($color: #a4aab5, $alpha: 0.05); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - color: #a4aab5; - gap: 5px; - height: 61px; - width: 61px; - font-size: 12px; - font-weight: 500; - border-radius: 15px; -} - -.textarea { - border: none; - outline: none; - min-width: 400px; - resize: none; - padding: 0 10px; - height: 50px !important; - - @media screen and (max-width: 800px) { - height: 70px !important; - min-width: 300px; - } - - @media screen and (max-width: 500px) { - min-width: 200px; - } -} - -.main { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; - @media screen and (max-width: 800px) { - display: none; - } - &__settings { - position: relative; - } -} - -.mobcontols { - display: none; - gap: 10px; - position: relative; - &__generate { - width: 100%; - } - &__settings { - min-width: 50px; - min-height: 50px; - padding: 0px; - display: flex; - justify-content: center; - align-items: center; - } - - @media screen and (max-width: 800px) { - display: flex; - } -} @@ -1,112 +0,0 @@ -import React, { MouseEventHandler, useState } from 'react' -import styles from './image-input.module.scss' -import { c } from '#/shared' -import BranchesSvg from '#/assets/svg/branches.svg?react' -import PaintSvg from '#/assets/svg/paint.svg?react' -import RatioSvg from '#/assets/svg/ratio.svg?react' -import CubesSvg from '#/assets/svg/cubes.svg?react' -import SettingsSvg from '#/assets/svg/settings.svg?react' -import { SendBtn } from '#/shared/ui/send-button' -import { useImageInput, useImageInputStyles } from '../model' -import { CommonButton } from '#/shared/ui/button' -import { ImageSettingsPopup, useImageBotMessages } from '#/entities/message' -import { getPopupById, POPUP_IMAGE_SETTINGS } from '#/shared/ui/popup' -import { Model } from '#/entities/model-entity' -import { useImageBotParams } from '#/entities/model-entity' - -export interface ImageInputProps { - model: Model | null - container: React.RefObject -} - -export const ImageInput = ({ model, container }: ImageInputProps) => { - const { createMessage, text, setText, loading } = useImageInput(model, container) - - const { inferenceParams, inference } = useImageBotParams() - - const { onStylesButtonClick } = useImageInputStyles() - - const imageSettingsPopup = getPopupById(POPUP_IMAGE_SETTINGS) - - return ( -
-
-
- - -
- -
- - -
-
-
-
- - -
- -
-
- -
- - Сгенерировать - - { - if (!model) return - - imageSettingsPopup.toogleState({ - botParams: inferenceParams, - currentVersion: inference?.id, - }) - }} - className={styles.mobcontols__settings} - variant='primary-outline' - > - - - - -
-
- ) -} @@ -1 +0,0 @@ -export * from './image-input' @@ -1,2 +0,0 @@ -export * from './ui' -export * from './model' @@ -1 +0,0 @@ -export * from './use-login-cookies' \ No newline at end of file @@ -1,17 +0,0 @@ -import { useRouter } from 'next/router' -import { useEffect } from 'react' -import { useCookies } from 'react-cookie' - -export function useLoginCookies() { - const [, setCookie] = useCookies() - - const { query } = useRouter() - - function setAllQueryToCookies() { - Object.entries(query).forEach(([key, value]) => setCookie(key, value)) - } - - return { - setAllQueryToCookies - } -} @@ -1 +0,0 @@ -export * from './model' \ No newline at end of file @@ -1,2 +0,0 @@ -export * from './use-login-form' -export * from './use-login-validate' \ No newline at end of file @@ -1,63 +0,0 @@ -import { useRouter } from 'next/router' -import { useForm } from 'react-hook-form' -import { LoginForm } from '../types' -import { useEffect, useState } from 'react' -import { signIn } from 'next-auth/react' -import { useShowDataStore } from '#/shared/lib/hooks' -import { captureMessage } from '@sentry/nextjs' -import { ERROR_MAPPING } from '#/pages/api/auth/constants' -import { keysToValues } from '#/shared' - -export function useLoginForm() { - const { - register, - handleSubmit, - formState: { errors }, - } = useForm() - - const [pending, setPending] = useState(false) - - const { showMessage } = useShowDataStore() - - const { push } = useRouter() - - useEffect(() => { - if (Object.values(errors).length === 0) return - const firstError = Object.values(errors)[0] - if (firstError && firstError.message) { - showMessage(firstError.message) - } else { - showMessage('Неверные данные') - } - }, [errors, showMessage]) - - const onSubmit = handleSubmit(async (data: LoginForm) => { - setPending(true) - - const response = await signIn('credentials', { - username: data.email, - password: data.password, - redirect: false, - }) - - setPending(false) - - const { ok, error } = response! - - if (ok) return push('/') - - if (!error) return showMessage('Не удалось выполнить вход, попробуйте позже') - - const expectedError = keysToValues(ERROR_MAPPING)[error] - - if (!expectedError) return captureMessage(error) - - showMessage(expectedError) - }) - - return { - onSubmit, - register, - pending, - } -} @@ -1,30 +0,0 @@ -import { RegisterOptions } from 'react-hook-form' -import { EMAIL_REGEXP } from '#/shared/lib/constants' -import { LoginForm } from '../types' - -export function useLoginValidate() { - const emailOptions: RegisterOptions = { - required: 'Поле email обязательно к заполенению!', - minLength: { - value: 5, - message: 'Слишком короткий email', - }, - pattern: { - value: EMAIL_REGEXP, - message: 'Введите валидный email', - }, - } - - const passwordOptions: RegisterOptions = { - required: 'Поле пароль обязательно к заполнению!', - minLength: { - value: 5, - message: 'Слишком короткий пароль', - }, - } - - return { - emailOptions, - passwordOptions - } -} @@ -1 +0,0 @@ -export * from './login-form' \ No newline at end of file @@ -1,4 +0,0 @@ -export interface LoginForm { - email: string - password: string -} @@ -1 +0,0 @@ -export * from './model' \ No newline at end of file @@ -1 +0,0 @@ -export * from './use-login-query-errors' \ No newline at end of file @@ -1,23 +0,0 @@ -import { ERRROR_YANDEX_TRANSLATE_MAPPING } from '#/pages/api/auth/constants' -import { useShowDataStore } from '#/shared/lib/hooks' -import { captureMessage } from '@sentry/nextjs' - -export function useLoginQueryErrors() { - const { showMessage } = useShowDataStore() - - function onMounted() { - const params = new URL(window.location.href).searchParams - - const error = params.get('error') - - if (!error || error === '') return - - const expectedError = ERRROR_YANDEX_TRANSLATE_MAPPING[error] - showMessage(expectedError ?? 'Не удалось выполнить вход, попробуйте позже') - if (!expectedError) captureMessage(error) - } - - return { - onMounted - } -} @@ -1 +0,0 @@ -export * from './model' \ No newline at end of file @@ -1 +0,0 @@ -export * from './use-messages-filters' \ No newline at end of file @@ -1,16 +0,0 @@ -import { Message } from '#/entities/message' -import { useState } from 'react' - -export function useMessagesFilters(messages: Message[]) { - const [value, setValue] = useState('') - - const filteredMessages = messages.filter((message) => { - return message.content && message.content.toLowerCase().includes(value.toLowerCase()) - }) - - return { - filteredMessages, - value, - setValue - } -} @@ -1 +0,0 @@ -export * from './message-fast-choice-menu' @@ -1,81 +0,0 @@ -.menu { - display: flex; - flex-direction: column; - gap: 15px; - padding: 10px; - border-radius: 15px; - border: 1px solid rgba($color: #a4aab5, $alpha: 0.2); - background: var(--new-ui-element-bg); - width: fit-content; - transition: all 0.6s ease-in-out; - - &:hover { - width: 280px !important; - .menu__new { - span { - display: inline-block; - } - } - - .menu__input { - display: inline-block; - width: 150px !important; - } - - .menu__inputbox { - justify-content: flex-end; - } - } - - &__new { - display: flex; - align-items: center; - justify-content: center; - gap: 7px; - padding: 10px 15px; - span { - display: none; - color: var(--new-ui-gray-color); - } - } - - &__inputbox { - display: flex; - align-items: center; - justify-content: center !important; - gap: 5px; - padding: 5px 7px; - } - - &__input { - outline: none; - border: none; - background: transparent; - color: var(--text-color-main); - display: none; - &::placeholder { - color: var(--new-ui-gray-color); - } - } -} - -.list { - height: 350px; - overflow-y: scroll; - - &__empty { - color: var(--new-ui-gray-color); - text-align: center; - } -} - -.loader { - text-align: center; - // width: max-content; -} - -@media (max-width: 800px) { - .list { - height: 200px; - } -} @@ -1,64 +0,0 @@ -import React, { MouseEventHandler, useState } from 'react' -import styles from './message-fast-choice-menu.module.scss' -import { c, Loader } from '#/shared' -import { Message } from '#/entities/message' -import PlusSvg from '#/assets/svg/plus.svg?react' -import Image from 'next/image' -import { MessageItem } from './message-item' -import SearchSvg from '#/assets/svg/search.svg?react' -import { useMessagesFilters } from '../model' - -export interface MessageFastChoiceMenuProps { - messages: Message[] - loading: boolean -} - -export const MessageFastChoiceMenu = ({ messages, loading }: MessageFastChoiceMenuProps) => { - const { filteredMessages, value, setValue } = useMessagesFilters(messages) - - const [hovered, setHovered] = useState(false) - - return ( -
setHovered(true)} - onMouseLeave={() => setHovered(false)} - className={styles.menu} - > - -
    - {loading && ( -
    - -
    - )} - {!filteredMessages.length && !loading && ( -
  • Ничего не найдено
  • - )} - {filteredMessages.map((message) => ( -
  • - {}} - {...message} - /> -
  • - ))} -
- -
- - setValue(e.target.value)} - className={styles.menu__input} - placeholder='Поиск генераций' - type='text' - /> -
-
- ) -} @@ -1,58 +0,0 @@ -.item { - display: flex; - align-items: center; - justify-content: space-between; - padding: 7px; - border-radius: 10px; - transition: width 0.6s ease-in-out; - - &_hovered { - .item__desc { - display: block; - opacity: 1; - } - - .item__right { - opacity: 1; - display: block; - } - } - - &:hover { - background-color: var(--new-ui-bg-app-color); - } - - &__desc { - opacity: 0; - transition: opacity 0.6s ease-in-out; - display: none; - } - - &__left { - display: flex; - gap: 7px; - align-items: center; - } - - &__right { - padding-right: 10px; - opacity: 0; - transition: opacity 0.6s ease-in-out; - display: none; - } - - &__img { - border-radius: 5px; - object-fit: cover; - } - - &__content { - font-weight: 500; - font-size: 14px; - } - - &__time { - font-size: 11px; - color: var(--new-ui-gray-color); - } -} @@ -1,48 +0,0 @@ -import { Message, useMessageTime } from '#/entities/message' -import Image from 'next/image' -import React from 'react' - -import styles from './message-item.module.scss' -import { c } from '#/shared' -import TrashSvg from '#/assets/svg/trash.svg?react' - -interface MessageItemProps extends Message { - deleteMessage: () => void - className?: string - hovered?: boolean -} - -export const MessageItem = ({ - created_at, - className, - file, - hovered, - content, - deleteMessage, -}: MessageItemProps) => { - const { formatedDate } = useMessageTime(created_at) - - return ( -
-
- {content -
-

{formatedDate}

-

{content}

-
-
- -
- -
-
- ) -} @@ -1,2 +0,0 @@ -export * from './ui' -export * from './model' @@ -1 +0,0 @@ -export * from './store-message-fullscreen-modal' @@ -1,28 +0,0 @@ -import { create } from 'zustand' - -type TextScaleState = { - scale: number - minScale: number - maxScale: number - increaseScale: () => void - decreaseScale: () => void - resetScale: () => void -} - -export const useTextScaleStore = create((set) => ({ - scale: 1, - minScale: 0.8, - maxScale: 1.5, - - increaseScale: () => - set((state) => ({ - scale: Math.min(state.scale + 0.1, state.maxScale), - })), - - decreaseScale: () => - set((state) => ({ - scale: Math.max(state.scale - 0.1, state.minScale), - })), - - resetScale: () => set({ scale: 1 }), -})) @@ -1,126 +0,0 @@ -.containerScroll { - min-height: 403px; - overflow: auto; - font-size: 15px; - line-height: 150%; - padding-right: 20px; - - width: 100%; - height: 100%; - position: relative; - overscroll-behavior: contain; - - &__scaledContent { - transform-origin: top left; - display: inline-block; - - width: 100%; - transition: transform 0.3s ease; - - display: inline-block; - white-space: normal; - word-wrap: break-word; - } - - &::-webkit-scrollbar { - width: 4px; - height: 4px; - } - - &::-webkit-scrollbar-track { - border-radius: 4px; - } - - &::-webkit-scrollbar-thumb { - background: var(--scrol-bar-color); - border-radius: 4px; - } - - &::-webkit-scrollbar-thumb:hover { - background: #746c6c; - } - - li { - margin-bottom: 6px; - white-space: normal; - } - - ul { - list-style-type: disc; - color: var(--new-ui-message-text-color); - padding: 0 15px 0 20px; - } - - ol { - list-style-type: decimal; - color: var(--new-ui-message-text-color); - padding: 0 15px 0 15px; - } - *:not(ul):not(ol):not(li) { - max-width: 827px; - } - - h1, - h2, - h3, - h4, - h5, - h6 { - color: var(--new-ui-text-color); - } -} - -.modal { - display: flex; - flex-direction: column; - position: relative; - width: 887px; - height: 583px; - min-width: 887px; - max-height: 583px; - - @media screen and (max-width: 600px) { - min-width: 350px; - } -} - -.header { - display: flex; - align-items: center; - column-gap: 10px; - margin: 35px 0px 25px 0px; - letter-spacing: -0.02em; - - &__text { - font-size: 30px; - font-weight: 650; - } -} - -.footer { - display: flex; - column-gap: 10px; - min-height: 85px; - - &__containerButton { - display: flex; - align-items: center; - column-gap: 10px; - } - - &__buttonCnanges { - display: flex; - align-items: center; - justify-content: center; - - width: 42px; - height: 42px; - border-radius: 15px; - padding: 0; - } - - &__scale { - color: var(--new-ui-text-color); - margin-left: 10px; - } -} @@ -1 +0,0 @@ -export * from './message-fullscreen-modal' \ No newline at end of file @@ -1,89 +0,0 @@ -import * as React from 'react' -import styles from './fullscreen-modal.module.scss' -import AvatarIcon from '#/assets/svg/avatar.svg?react' -import ZoomIconMinus from '#/assets/svg/zoom-icon-minus.svg?react' -import ZoomIconPlus from '#/assets/svg/zoom-icon-plus.svg?react' -import { FULLSCREEN_CHAT_MESSAGE, getModalById, PlateTemplate } from '#/features/modals' -import { CommonTextArea } from '#/shared/ui/common-textarea' -import { CommonButton } from '#/shared/ui/button' -import { useChatBotMessages } from '#/entities/message' -import { Message } from '#/entities/message' -import { Markdown } from '#/widgets/markdown/markdown' -import { Skeleton } from '@mui/material' -import { useTextScaleStore } from '../model' - -interface MessageFullscreenModalI { - message: Message -} - -export const MessageFullscreenModal = () => { - const modal = getModalById(FULLSCREEN_CHAT_MESSAGE) - - const { scale, increaseScale, decreaseScale, resetScale } = useTextScaleStore() - const scaleOnProccent = Math.round(scale * 100) - - const message = modal.getStoreProperty('message')! - - React.useEffect(() => { - resetScale() - }, [modal.state]) - - return ( - - {message && ( - <> -
-
-
- - -

{message.model}

-
- -
-
- -
-
- -
-
- - - - - - - - -
{scaleOnProccent}%
-
-
-
-
- - )} -
- ) -} @@ -1 +0,0 @@ - @@ -1,10 +1,7 @@ - -export const PLATE_IMAGE_STYLES = 'plate-image-styles' export const PLATE_CHANGE_PASSWORD = 'plate-change-password' export const RESEND_INVATION_PASSWORD = 'resend-invation-password' export const ERROR_REPORT = 'error-report' export const GALLERY_IMAGES = 'gallery-images' -export const FULLSCREEN_CHAT_MESSAGE = 'fullscreen-chat-message' export const CHANGE_BUSINESS_GROUP = 'change-business-group' @@ -13,4 +10,3 @@ export const INVITE_USER = 'invite-user' export const INVITE_SECURITY_MODAL = 'invite-security' export const LIMIT_MODAL = 'limit-modal' export const LIMIT_SECURITY_MODAL = 'limit-security-modal' -export const ERROR_MESSAGE = 'error-message' @@ -12,15 +12,6 @@ opacity: 0; visibility: hidden; - &_blur { - &-on { - backdrop-filter: blur(15.5px); - } - &-off { - backdrop-filter: none; - } - } - &_visible { opacity: 1; visibility: visible; @@ -87,9 +78,9 @@ } // &__header { - // display: flex; - // justify-content: space-between; - // padding: 25px; + // display: flex; + // justify-content: space-between; + // padding: 25px; // } &__close-button { @@ -102,18 +93,9 @@ &__content-body { transition: all 0.3s ease-in-out; + padding: 0px 32px 32px 32px; overflow: hidden; - &_padding { - &-default { - padding: 0px 32px 32px 32px; - } - - &-small { - padding: 0px 5px 0 30px; - } - } - @media screen and (max-width: 1000px) { padding: 0px 10px 10px 10px; } @@ -9,8 +9,6 @@ import { useThemeAndDevice } from '#/shared/lib/hooks' export type AlignX = 'left' | 'center' | 'right' export type AlignY = 'top' | 'center' | 'bottom' export type Variant = 'primary' | 'secondary' -export type PaddingVariant = 'default' | 'small' -export type BlurToogle = 'on' | 'off' export interface PlatesTemplateProps { id: string @@ -25,11 +23,7 @@ export interface PlatesTemplateProps { animationBehaviorClass?: string headerClassName?: string variant?: Variant - containerClassName?: string - paddingVariant?: PaddingVariant - blurToogle?: BlurToogle - hasCLoseButton?: boolean - hasCloseOnCLickOutside?: boolean + containerClassName?: string } export default function PlatesTemplate({ @@ -43,12 +37,8 @@ export default function PlatesTemplate({ animationClass = styles['template__animation'], animationBehaviorClass = styles['template__animation-behavior'], closeModal = () => {}, - containerClassName, + containerClassName, variant = 'primary', - paddingVariant = 'default', - blurToogle = 'off', - hasCLoseButton = true, - hasCloseOnCLickOutside = true, }: PlatesTemplateProps) { const { setModal, getModal } = usePlatesStore() @@ -63,12 +53,11 @@ export default function PlatesTemplate({ modal.state ? styles['template_visible'] : styles['template_invisible'], hasBg ? styles['template_flex'] : styles['template_w-fit'], styles[`template_align-y-${alignY}`], - styles[`template_blur-${blurToogle}`], hasBg ? styles[`template_align-x-${alignX}`] : '', - containerClassName + containerClassName )} onClick={() => { - if (hasBg && hasCloseOnCLickOutside) modal.setState(false) + if (hasBg) modal.setState(false) }} > {hasTemplate ? ( @@ -81,35 +70,19 @@ export default function PlatesTemplate({ )} onClick={(e) => e.stopPropagation()} > - {hasCLoseButton && ( - - )} -
{ + modal.setState(false) + closeModal() + }} > - {children} -
+ + +
{children}
) : ( -
- {children} -
+
{children}
)}
) @@ -1,8 +1,8 @@ -import { usePlatesStore } from './model' +import { usePlatesStore } from './model'; export function getModalById(id: string) { - const { getModal } = usePlatesStore() - return getModal(id) + const { getModal } = usePlatesStore(); + return getModal(id); } export * from './ui' @@ -1,10 +0,0 @@ - - -export interface NavigationBlock { - title: string, - content: string | React.ReactNode - link?: string - enabled: boolean - image: string - cols: number -} \ No newline at end of file @@ -1 +0,0 @@ -export * from './block' \ No newline at end of file @@ -1 +0,0 @@ -export * from './navigation-main-page-block' \ No newline at end of file @@ -1,85 +0,0 @@ -.block { - padding: 25px 30px; - position: relative; - display: flex; - flex-direction: column; - justify-content: space-between; - cursor: pointer; - - @media screen and (max-width: 768px) { - grid-column: unset !important; - padding: 15px 20px; - } - - &_disabled { - pointer-events: none; - cursor: default; - } - - &__image { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 30px; - } - - &__desc { - position: relative; - z-index: 1; - } - - &__title { - font-size: 40px; - font-weight: 800; - color: white; - margin-bottom: 5px; - - @media screen and (max-width: 768px) { - font-size: 34px; - } - } - - &__content { - font-size: 16px; - font-weight: 400; - color: white; - max-width: 450px; - - @media screen and (max-width: 768px) { - font-size: 16px; - font-weight: 500; - } - } - - &__arrow { - transition: color 0.3s ease-in-out; - } - - &__more { - display: flex; - align-items: center; - gap: 3px; - - &_disabled { - &:hover { - .block__arrow_disabled { - color: white; - } - } - } - - &:hover { - .block__arrow { - color: black; - } - } - } - - &__controls { - position: relative; - z-index: 1; - } -} @@ -1,55 +0,0 @@ -import React from 'react' -import { NavigationBlock } from '../types' - -import styles from './navigation-main-page-block.module.scss' -import { CommonButton } from '#/shared/ui/button' -import Image from 'next/image' -import ArrowSelectSvg from '#/assets/svg/arrow-select.svg?react' -import Link from 'next/link' -import { c } from '#/shared/lib/helpers' - -interface NavigationMainPageBlockProps extends NavigationBlock {} - -export const NavigationMainPageBlock = ({ - title, - cols, - content, - enabled, - link, - image, -}: NavigationMainPageBlockProps) => { - return ( - - {title} -
-

{title}

-

{content}

-
- -
- - {enabled ? 'Попробовать' : 'Скоро будет доступно'} - {enabled && ( - - )} - -
- - ) -} @@ -1,2 +0,0 @@ -export * from './types' -export * from './ui' \ No newline at end of file @@ -1,2 +1,2 @@ -export * from './pending.slice' -export { default as pendingSlice } from './pending.slice' +export * from './pending-store' +export { default as pendingStore } from './pending-store' @@ -0,0 +1,27 @@ +import { create } from 'zustand' + +export interface PendingSlice { + userLoading: boolean + userLoaded: boolean + change: (loading: boolean) => void + setLoaded: (loaded: boolean) => void +} + +const pendingSlice = create((set, get) => { + function change(loading: boolean) { + set({ userLoading: loading }) + } + + function setLoaded(loaded: boolean) { + set({ userLoaded: loaded }) + } + + return { + userLoading: true, + userLoaded: false, + change, + setLoaded, + } +}) + +export default pendingSlice @@ -1 +0,0 @@ -export * from './use-referal-info' \ No newline at end of file @@ -1,12 +0,0 @@ -import { useEffect, useState } from 'react' - -export function useReferrall() { - const [referral, setReferral] = useState(null) - - useEffect(() => setReferral(localStorage.getItem('referral')), []) - - return { - referral, - setReferral, - } -} @@ -1 +0,0 @@ -export * from './model' \ No newline at end of file @@ -0,0 +1,57 @@ +import { create } from 'zustand' + +export interface StepperSlice { + activeStep: number + loadingCreate: 'idle' | 'pending' | 'succeeded' | 'failed' + dataForCreate: any + company: any + switchStep: (step: number) => void + switchPreviousStep: () => void + switchNextStep: () => void + setLoadingCreate: (loading: 'idle' | 'pending' | 'succeeded' | 'failed') => void + setDataForCreate: (data: any) => void + setCompany: (company: any) => void +} + +export const stepperSlice = create((set, get) => { + function switchStep(step: number) { + set({ activeStep: step }) + } + + function switchPreviousStep() { + const currentStep = get().activeStep + if (currentStep > 0) { + set({ activeStep: currentStep - 1 }) + } + } + + function switchNextStep() { + const currentStep = get().activeStep + set({ activeStep: currentStep + 1 }) + } + + function setLoadingCreate(loading: 'idle' | 'pending' | 'succeeded' | 'failed') { + set({ loadingCreate: loading }) + } + + function setDataForCreate(data: any) { + set({ dataForCreate: data }) + } + + function setCompany(company: any) { + set({ company }) + } + + return { + activeStep: 0, + loadingCreate: 'idle', + dataForCreate: {}, + company: null, + switchStep, + switchPreviousStep, + switchNextStep, + setLoadingCreate, + setDataForCreate, + setCompany, + } +}) @@ -1,28 +1,16 @@ import { create } from 'zustand' -interface CompanyData { - value: string - label: string -} - -interface DataForCreate { - companyName?: string - inn?: string - ogrn?: string - [key: string]: any -} - export interface StepperStore { activeStep: number loadingCreate: 'idle' | 'pending' | 'succeeded' | 'failed' - dataForCreate: DataForCreate - company: CompanyData[] | null + dataForCreate: any + company: any switchStep: (step: number) => void switchPreviousStep: () => void switchNextStep: () => void setLoadingCreate: (loading: 'idle' | 'pending' | 'succeeded' | 'failed') => void - setDataForCreate: (data: DataForCreate) => void - setCompany: (company: CompanyData[] | null) => void + setDataForCreate: (data: any) => void + setCompany: (company: any) => void } export const useStepperStore = create((set, get) => { @@ -46,11 +34,11 @@ export const useStepperStore = create((set, get) => { set({ loadingCreate: loading }) } - function setDataForCreate(data: DataForCreate) { + function setDataForCreate(data: any) { set({ dataForCreate: data }) } - function setCompany(company: CompanyData[] | null) { + function setCompany(company: any) { set({ company }) } @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { RegisterOptions, useForm } from 'react-hook-form' +import { useForm } from 'react-hook-form' import { SubmitErrorHandler } from 'react-hook-form/dist/types/form' import { Autocomplete, Box, TextField, Typography } from '@mui/material' @@ -110,7 +110,7 @@ export const StepLegalInformative = () => { }, } } - {...methods.register('companyName', companyNameOptions as any)} + {...methods.register('companyName', companyNameOptions)} /> )} componentsProps={{ @@ -128,7 +128,7 @@ export const StepLegalInformative = () => { @@ -136,7 +136,7 @@ export const StepLegalInformative = () => { @@ -1,2 +1,2 @@ -export { stepperSlice } from './model/stepper-slice' +export { stepperSlice } from './model/stepper-store' export { Stepper } from './ui/stepper/stepper' @@ -1 +0,0 @@ -export * from './register' \ No newline at end of file @@ -1,10 +0,0 @@ -import { CreateUserWithRelations } from '#/entities/user-account' -import { api } from '#/shared/api' - -export async function getWhitelist(email: string) { - return await api.get('/auth/mail/whitelist', { params: { email } }) -} - -export async function apiRegister(data: CreateUserWithRelations) { - return await api.post('/auth/register', data) -} \ No newline at end of file @@ -1,2 +0,0 @@ -export * from './use-register' -export * from './use-register-validate' \ No newline at end of file @@ -3,4 +3,3 @@ export interface IEmailForms { password1: string password2: string } - \ No newline at end of file @@ -1,28 +0,0 @@ -import { EMAIL_REGEXP } from '#/shared/lib/constants' - -export function useRegisterValidate() { - const emailOptions = { - required: 'Поле email обязательно к заполенению!', - minLength: { - value: 5, - message: 'Слишком короткий email', - }, - pattern: { - value: EMAIL_REGEXP, - message: 'Введите валидный email', - }, - } - - const passwordOptions = { - required: 'Поле пароль обязательно к заполнению!', - minLength: { - value: 5, - message: 'Слишком короткий пароль', - }, - } - - return { - emailOptions, - passwordOptions - } -} @@ -1,78 +0,0 @@ -import { useState } from 'react' -import { apiRegister, getWhitelist } from '../api' -import { SubmitErrorHandler, SubmitHandler, useForm } from 'react-hook-form' -import { RegisterForm } from '../types/register-form' -import { useShowDataStore } from '#/shared/lib/hooks' -import { useCookies } from 'react-cookie' -import { useReferrall } from '#/features/referal' -import { useRouter } from 'next/router' - -export function useRegister(successLogin: Function) { - const { register, handleSubmit, reset, setValue, watch } = useForm() - - const [pending, setPending] = useState(false) - - const { showMessage } = useShowDataStore() - - const { referral } = useReferrall() - - const [{ utm_source, utm_medium, utm_campaign }] = useCookies() - - const { push } = useRouter() - - function onSuccess() { - reset() - successLogin() - setTimeout(() => push('/login'), 7000) - } - - async function onRegister(form: RegisterForm) { - const { status, data } = await apiRegister({ - ...form, - utm_source, - utm_medium, - utm_campaign, - utm_term: utm_campaign, - utm_content: utm_campaign, - referer: referral ?? undefined, - }) - - setPending(false) - - if (status === 201) return onSuccess() - - showMessage(data.detail) - } - - const onValid: SubmitHandler = async ({ rules, confirm, password, ...data }) => { - if (password !== confirm) return showMessage('Пароли не совпадают') - - setPending(true) - - if (rules) return onRegister({ ...data, confirm, password }) - - const response = await getWhitelist(data.email) - - if (response.status !== 200) { - showMessage('Примите пользовательское соглашение') - return setPending(false) - } - - onRegister({ ...data, confirm, password }) - } - - const onInvalid: SubmitErrorHandler = (errors) => { - const error = Object.values(errors).at(0) - if (error) return showMessage(error.message as string) - } - - const onSubmit = handleSubmit(onValid, onInvalid) - - return { - onSubmit, - register, - watch, - setValue, - pending, - } -} @@ -1,2 +0,0 @@ -export * from './use-form-fields' -export * from './use-form-fields-change' \ No newline at end of file @@ -1,32 +0,0 @@ -import { fireEvent, screen } from '@testing-library/dom' -import { useFormFields } from '.' - -export function useFormFieldsChange() { - const { emailInput, passwordInput, confirmInput, spamCheckbox, rulesCheckbox, submitButton } = - useFormFields() - - function allInputsFilled() { - fireEvent.change(emailInput, { - target: { value: 'aleksander.freelancer@gmail.com' }, - }) - fireEvent.change(passwordInput, { target: { value: 'geraldisrivii' } }) - fireEvent.change(confirmInput, { target: { value: 'geraldisrivii' } }) - } - - function allFieldsFilled() { - allInputsFilled() - fireEvent.click(rulesCheckbox) - fireEvent.click(spamCheckbox) - } - - function fieldsFilledWithoutSpam() { - allInputsFilled() - fireEvent.click(rulesCheckbox) - } - - return { - allFieldsFilled, - fieldsFilledWithoutSpam, - allInputsFilled, - } -} @@ -1,12 +0,0 @@ -import { screen } from '@testing-library/dom' - -export function useFormFields() { - return { - emailInput: screen.getByTestId('email-input'), - passwordInput: screen.getByTestId('password-input'), - confirmInput: screen.getByTestId('confirm-input'), - rulesCheckbox: screen.getByTestId('rules-checkbox'), - spamCheckbox: screen.getByTestId('spam-checkbox'), - submitButton: screen.getByTestId('submit-button'), - } -} @@ -1 +0,0 @@ -export * from './register-form' \ No newline at end of file @@ -1,7 +0,0 @@ -import { CreateUserDTO } from '#/entities/user-account' - -export interface RegisterForm extends CreateUserDTO { - confirm: string - rules?: boolean - spam?: boolean -} @@ -1 +0,0 @@ -export * from './register-email-form' \ No newline at end of file @@ -1,59 +0,0 @@ -.form { - &__inputs { - display: flex; - flex-direction: column; - gap: 6px; - margin-bottom: 10px; - } - - &__checkboxes { - display: flex; - flex-direction: column; - gap: 8px; - } - - &__navigate { - padding-top: 10px; - text-align: center; - color: #a7a8bb; - font-size: 16px; - } -} - -.input{ - &__pass{ - display: flex; - align-items: center; - } -} - -.controls { - padding-top: 25px; - width: 100%; - - &__progress { - display: flex; - justify-content: center; - - span{ - color: var(--air-color); - } - } - - &__create { - width: 100%; - } -} - -.checkbox { - padding-left: 12px; - &__text { - color: #868686; - line-height: 1.5; - width: max-content; - } - - &__link { - color: var(--air-color); - } -} @@ -1,171 +0,0 @@ -import { RegisterPage } from '#/views/register' -import '@testing-library/jest-dom' -import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { jestRender } from '#/../jest/utils/render' -import { windowMock } from '#/../jest/utils/window-mock' -import { RegisterEmailForm } from './register-email-form' -import { api } from '#/shared/api' -import { useFormFields, useFormFieldsChange } from '../test' -import { useRouter } from '#/../__mocks__/next/router' -import { useShowDataStore } from '#/shared/lib/hooks' - -jest.mock('#/shared/api') - -jest.mock('next/router') -jest.mock('@sentry/nextjs') - -const showMessageMock = jest.fn() - -jest.mock('#/shared/lib/hooks', () => { - return { - useShowDataStore: jest.fn(() => { - return { - showMessage: showMessageMock, - } - }), - } -}) - -windowMock() - -describe('register-email-form', () => { - beforeEach(() => { - ;(api.post as jest.Mock).mockClear() - ;(api.get as jest.Mock).mockClear() - }) - - it('renders in register', () => { - jestRender() - - const form = screen.getByTestId('register-email-form') - - expect(form).toBeInTheDocument() - }) - - it('submit by button click', async () => { - await act(async () => { - jestRender( {}} />) - }) - - const { submitButton } = useFormFields() - - const { allFieldsFilled } = useFormFieldsChange() - - ;(api.post as jest.Mock).mockResolvedValue({ - status: 201, - }) - - allFieldsFilled() - - await act(async () => { - fireEvent.click(submitButton) - }) - - await waitFor(() => { - expect(api.post).toHaveBeenCalledWith('/auth/register', { - confirm: 'geraldisrivii', - email: 'aleksander.freelancer@gmail.com', - password: 'geraldisrivii', - spam: true, - }) - }) - - /** Больно долго его ждать (7000ms по timeout) - замедляет тесты (но работает) */ - // await waitFor(() => { - // const { push } = useRouter() - // expect(push).toHaveBeenCalledWith('/login') - // }, {timeout: 8000}) - }) - - it('submit by Enter', async () => { - await act(async () => { - jestRender( {}} />) - }) - ;(api.post as jest.Mock).mockResolvedValue({ - status: 201, - }) - - const { allFieldsFilled } = useFormFieldsChange() - - const { emailInput } = useFormFields() - - allFieldsFilled() - - await userEvent.type(emailInput, '{enter}') - - await waitFor(() => { - expect(api.post).toHaveBeenCalledWith('/auth/register', { - confirm: 'geraldisrivii', - email: 'aleksander.freelancer@gmail.com', - password: 'geraldisrivii', - spam: true, - }) - }) - }) - - it('submit without rules and white list not include sended email', async () => { - await act(async () => { - jestRender( {}} />) - }) - ;(api.get as jest.Mock).mockResolvedValue({ - status: 400, - }) - ;(useShowDataStore as any as jest.Mock).mockImplementation(() => ({ - showMessage: showMessageMock, - })) - - const { allInputsFilled } = useFormFieldsChange() - - const { emailInput } = useFormFields() - - allInputsFilled() - - await userEvent.type(emailInput, '{enter}') - - await waitFor(() => { - expect(api.get).toHaveBeenCalledWith('/auth/mail/whitelist', { - params: { email: 'aleksander.freelancer@gmail.com' }, - }) - }) - - await waitFor(() => { - expect(showMessageMock).toHaveBeenCalledWith('Примите пользовательское соглашение') - }) - }) - - it('submit without rules and white list included sended email', async () => { - await act(async () => { - jestRender( {}} />) - }) - ;(api.get as jest.Mock).mockResolvedValue({ - status: 200, - }) - ;(api.post as jest.Mock).mockResolvedValue({ - status: 201, - }) - - const { allInputsFilled } = useFormFieldsChange() - - const { emailInput } = useFormFields() - - allInputsFilled() - - await userEvent.type(emailInput, '{enter}') - - await waitFor(() => { - expect(api.get).toHaveBeenCalledWith('/auth/mail/whitelist', { - params: { email: 'aleksander.freelancer@gmail.com' }, - }) - }) - - await waitFor(() => { - expect(api.post).toHaveBeenCalledWith('/auth/register', { - confirm: 'geraldisrivii', - email: 'aleksander.freelancer@gmail.com', - password: 'geraldisrivii', - spam: false, - }) - }) - }) -}) @@ -1,5 +1,12 @@ import React, { useState } from 'react' +import { useCookies } from 'react-cookie' +import { useForm } from 'react-hook-form' +import { SubmitErrorHandler, SubmitHandler } from 'react-hook-form/dist/types/form' +import { Button, Checkbox, InputAdornment, TextField } from '@mui/material' +import Box from '@mui/material/Box' import CircularProgress from '@mui/material/CircularProgress' +import Typography from '@mui/material/Typography' +import axios from 'axios' import Link from 'next/link' import { useRouter } from 'next/router' @@ -15,21 +22,13 @@ import { useThemeAndDevice } from '#/shared/lib/hooks' import OpenedEyeSvg from '#/assets/svg/opened-eye.svg?react' import ClosedEyeSvg from '#/assets/svg/closed-eye.svg?react' import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' -import { SubmitErrorHandler, SubmitHandler, useForm } from 'react-hook-form' -import { useCookies } from 'react-cookie' -import axios from 'axios' -import { c } from '#/shared' -import styles from './register-email-form.module.scss' -import { CommonInput } from '#/shared/ui/common-input' -import { CommonCheckbox } from '#/shared/ui/checkbox' -import { CommonButton } from '#/shared/ui/button' interface IRegisterEmailFormProps { successLogin: () => void } export const RegisterEmailForm: React.FC = ({ successLogin }) => { - const { register, handleSubmit, reset, watch, formState: { errors, isSubmitting } } = useForm() + const { register, handleSubmit, reset, watch } = useForm() const { theme, desktop } = useThemeAndDevice() @@ -114,108 +113,189 @@ export const RegisterEmailForm: React.FC = ({ successLo } return ( -
-
- + + + Email + + - showPassword((x) => !x)} - > - {passwordShowed ? ( - - ) : ( - - )} - - } - /> - + Пароль + + + +
showPassword((x) => !x)} + style={{ + cursor: 'pointer', + display: 'flex', + alignItems: 'center', + }} + > + {passwordShowed ? ( + + ) : ( + + )} +
+ + ), + }} + sx={theme === 'light' ? { ...InputStyleLight } : { ...InputStyleDark }} + {...register('password1', { + ...PasswordOptions, + })} + /> + + + Подтвердите пароль + + + { + if (watch('password1') != val) { + return 'Пароли не совпадают' + } + }, + })} + /> + + + + + -
- -
- - - Я соглашаюсь с условиями  - - - Политики обработки персональных данных  - - и  - - Публичной офертой - - + {' '} + Я соглашаюсь на получение-информационно-рекламных писем + + - - - Я соглашаюсь на получение-информационно-рекламных писем - - -
- -
- {isSubmitting ? ( -
- -
+ + {loading ? ( + + + ) : ( - Создать аккаунт - + )} -
-

- Есть аккаунт?  - + + - Войти - -

+ Есть аккаунт?{' '} + + Войти + + +
) } @@ -1,4 +1 @@ export { RegisterEmailForm } from './ui/register-email-form' -export * from './model' -export * from './ui' -export * from './test' \ No newline at end of file @@ -1 +0,0 @@ -export * from './upscale-settings.popup' \ No newline at end of file @@ -1,4 +0,0 @@ -.popup{ - min-width: 200px; - min-height: 250px; -} \ No newline at end of file @@ -1,15 +0,0 @@ -import { getPopupById, POPUP_UPSCALE_SETTINGS, PopupTemplate } from '#/shared/ui/popup' -import React, { useEffect } from 'react' -import styles from './upscale-settings.popup.module.scss' - -export const UpscaleSettingsPopup = () => { - const popup = getPopupById(POPUP_UPSCALE_SETTINGS) - - return ( - -
-

НАСТРОЙКИ

-
-
- ) -} @@ -1 +0,0 @@ -export * from './ui' \ No newline at end of file @@ -1,5 +1,5 @@ -// TODO: Replace with Zustand store when needed +import { getUserBalance } from '#/entities/balance' import { Message, MessageEventStreamResponse, @@ -9,7 +9,6 @@ import { useChatBotMessages, useChatMessagesEvents, } from '#/entities/message' -import { useBalanceStore } from '#/entities/balance/model/use-balance-store' import { useChatBotParams } from '#/entities/model-entity' import { useChatBotPagination } from '#/features/chat-bot-pagination' import { useCurrentChat } from '#/features/chats' @@ -38,8 +37,6 @@ export function useChatMessageActions() { const { makeEvent } = useChatMessagesEvents() - const { getUserBalance } = useBalanceStore() - function getFileLink(file: File) { return URL.createObjectURL(file) + '?type=.' + file.name.split('.')[1] } @@ -110,10 +107,7 @@ export function useChatMessageActions() { ;(result as Message[])[1].content = '' }) - // Обновляем баланс после отправки сообщения - if (session?.access) { - getUserBalance(session.access) - } + // TODO: Add getUserBalance to Zustand store }) const deleteMessage = makePrivateRequest(async (uid: string) => { @@ -1,40 +0,0 @@ -import { create } from 'zustand' - -import { CopywriteProxy } from '#/domains/copywrite/proxy/copywrite-proxy' -import { Message } from '#/entities/message' - -interface CopyState { - templates: any[] - generation: Message[] - loading: boolean - loadTemplates: (token?: string) => Promise - loadGeneration: (token?: string) => Promise -} - -export const useCopyStore = create((set, get) => ({ - templates: [], - generation: [], - loading: false, - - loadTemplates: async (token?: string) => { - set({ loading: true }) - try { - const templates = await CopywriteProxy.getTemplates(token) - set({ templates, loading: false }) - } catch (error) { - console.error('Error loading templates:', error) - set({ loading: false }) - } - }, - - loadGeneration: async (token?: string) => { - set({ loading: true }) - try { - const generation = await CopywriteProxy.getGeneration(token) - set({ generation, loading: false }) - } catch (error) { - console.error('Error loading generation:', error) - set({ loading: false }) - } - }, -})) \ No newline at end of file @@ -12,8 +12,8 @@ gap: 5px; width: max-content; padding: 8px 14px; - transition: all 0.3s ease; - width: 100%; + transition: all 0.3s ease; + width: 100%; &:hover { backdrop-filter: brightness(90%); @@ -1,36 +1,22 @@ +import { PopupTemplate, PoputTemplateHorizontal, getPopupById } from '#/shared/ui/popup' import React from 'react' import CopySvg from '#/assets/svg/copy.svg?react' import TrashSvg from '#/assets/svg/trash.svg?react' -import FullscreeenSvg from '#/assets/svg/fullscreen-icon.svg?react' import styles from './user-message-popup.module.scss' - import { useChatMessageActions } from '#/features/use-chat-message-actions' -import { FULLSCREEN_CHAT_MESSAGE, getModalById } from '#/features/modals' -import { Message } from '#/entities/message' -import { getPopupById, PopupTemplate, PoputTemplateHorizontal } from '#/shared/ui/popup' interface UserMessageActionsPopupProps { id: string horizontal?: PoputTemplateHorizontal - message: Message } -export const UserMessageActionsPopup = ({ - id, - horizontal = 'right', - message, -}: UserMessageActionsPopupProps) => { +export const UserMessageActionsPopup = ({ id, horizontal = 'right' }: UserMessageActionsPopupProps) => { const { deleteMessage } = useChatMessageActions() + const popup = getPopupById(id) - const content = popup.getStoreProperty('content')! - const modal = getModalById(FULLSCREEN_CHAT_MESSAGE) - const handleAction = (e: React.MouseEvent, callback: () => void) => { - e.stopPropagation() - callback() - popup.setState(false) - } + const content = popup.getStoreProperty('content')! return (
- -
- -
- - @@ -1,25 +0,0 @@ -.button { - background-color: #f1faff; - color: rgb(43, 43, 66); - width: 100%; - display: flex; - align-items: center; - justify-content: center; - padding: 10px 16px; - border-radius: 13px; - transition: opacity 0.3s ease-in-out; - gap: 15px; - font-size: 16px; - font-weight: 500; - - &:hover { - opacity: 0.8; - } -} - -html[data-theme='dark'] { - .button { - background-color: #1C1C1E; - color: white; - } -} @@ -1,45 +0,0 @@ -import { LoginPage } from '#/views/login' -import { RegisterPage } from '#/views/register' -import '@testing-library/jest-dom' -import { screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { jestRender } from '#/../jest/utils/render' -import { YandexAuthButton } from './yandex-auth-button' -import { windowMock } from '#/../jest/utils/window-mock' -import { fetchToCrossfetch } from '#/../jest/utils/fetch-to-crossfetch' - -jest.mock('next/router') -jest.mock('@sentry/nextjs') - -windowMock() -fetchToCrossfetch() - -describe('yandex-auth-button', () => { - it('renders in login', () => { - jestRender() - - const button = screen.getByTestId('yandex-auth-button') - - expect(button).toBeInTheDocument() - }) - - it('renders in register', () => { - jestRender() - - const button = screen.getByTestId('yandex-auth-button') - - expect(button).toBeInTheDocument() - }) - - it('opened signin url', async () => { - jestRender() - - const button = screen.getByTestId('yandex-auth-button') - - await userEvent.click(button) - - await waitFor(() => { - expect(window.location.href).toContain('api/auth/signin?csrf=true') - }) - }) -}) @@ -1,19 +1,51 @@ -import React from 'react' -import YandexSvg from '#/assets/svg/yandex.svg?react' -import styles from './yandex-auth-button.module.scss' +import theme from '#/entities/theme/model/theme' +import { useThemeAndDevice } from '#/shared/lib/hooks' +import { Button } from '@mui/material' import { signIn } from 'next-auth/react' +import Image from 'next/image' +import React, { useState } from 'react' interface YandexAuthButtonProps {} export const YandexAuthButton = ({}: YandexAuthButtonProps) => { + const { theme } = useThemeAndDevice() + + const [hovered, setHovered] = useState(false) + return ( - + {''} + Войти с Яндекс ID + ) } @@ -1,70 +0,0 @@ -import React, { useEffect, useMemo } from 'react' -import { Avatar, Box, Button, Typography } from '@mui/material' -import Image from 'next/image' -import Link from 'next/link' -import LockSvg from '#/assets/svg/lock.svg?react' -import BlockedSvg from '#/assets/svg/blocked.svg?react' - -import styles from './card.module.scss' -import { useThemeAndDevice } from '#/shared/lib/hooks' - -export type CardProps = { - title: string - icon: string - text: string - uid: string - blocked?: boolean - slug: string - accessed_models?: string[] | null -} - -const ChatCard = ({ text, icon, title, uid, slug, accessed_models, blocked }: CardProps) => { - const link = useMemo(() => { - return accessed_models && !accessed_models.includes(slug) ? '/account?scope=subscribe' : `chat-bot/${slug}` - }, [accessed_models]) - - const { theme } = useThemeAndDevice() - - return ( - - - - - - - {title} - {text} - - - {blocked ? ( -
- - - Модель недоступна - -
- ) : ( - accessed_models && - !accessed_models.includes(slug) && ( -
- - Недоступно в текущем тарифе -
- ) - )} -
- - ) -} - -export default ChatCard @@ -1,8 +0,0 @@ -interface ApiKeyDTO { - created_at: string // ISO 8601 format - name: string - key: string - expires_at: string | null - user: User - token_limit: string -} @@ -1,136 +0,0 @@ -import NextAuth, { NextAuthOptions, User } from 'next-auth' -import CredentialsProvider from 'next-auth/providers/credentials' -import YandexProvider from 'next-auth/providers/yandex' - -import { AuthConstants, ERROR_MAPPING, ERROR_YANDEX_MAPPING } from './constants' -import { AuthorizationProxy } from './proxy' - -import { getAll } from '#/entities/user-account/model/user-type-slice' - -const AuthProxy = new AuthorizationProxy() - -export const authOptions: NextAuthOptions = { - session: { strategy: 'jwt', maxAge: AuthConstants.sessionTime }, - secret: process.env.NEXTAUTH_SECRET, - providers: [ - YandexProvider({ - clientId: AuthConstants.client_id_yandex || '', - clientSecret: AuthConstants.client_secret_yandex || '', - authorization: AuthConstants.redirect_uri_yandex, - checks: ['none'], - }), - CredentialsProvider({ - id: 'credentials', - type: 'credentials', - credentials: {}, - async authorize(credentials, req) { - const { username, password } = credentials as { username: string, password: string } - - const resp = await AuthProxy.loginByEmail(username, password) - const data = await resp.json() - - if (resp.status >= 400 && resp.status < 500) { - throw new Error( - ERROR_MAPPING[(data as { detail: string }).detail] ?? - JSON.stringify(data as Object) - .replace(/\s+/, '_') - .replace(/[А-Яа-я]/, '') - .toLowerCase() - ) - } - return (await data) as User - }, - }), - CredentialsProvider({ - id: 'email_token', - type: 'credentials', - credentials: {}, - async authorize(credentials, req) { - const { token } = credentials as { token: string } - - const resp = await AuthProxy.loginByEmailToken(token) - - const data = await resp.json() - - if (resp.status >= 400 && resp.status < 500) { - throw new Error( - ERROR_MAPPING[(data as { detail: string }).detail] ?? - JSON.stringify(data as Object) - .replace(/\s+/, '_') - .replace(/[А-Яа-я]/, '') - .toLowerCase() - ) - } - return (await data) as User - }, - }), - ], - callbacks: { - async jwt({ token, user, account, trigger }) { - if (account?.provider === 'yandex') { - const result = await AuthProxy.exchangeTokenYandex(account.access_token || '') - - if (result.status >= 400 && result.status < 500) { - throw new Error('Непредвиденная ошибка') - } - - const info = await getAll( - (result.data as { access_token: string }).access_token - ) - - return { ...info.token, tokenExpiry: AuthConstants.getExpiresDate() } - } - - if (user) { - try { - token.access = user.token.access - token.refresh = user.token.refresh - token.tokenExpiry = AuthConstants.getExpiresDate() - return token - } catch (error) { - return { ...token, ...user } - } - } - - const shouldRefreshTime = Math.round(Date.now() - token.tokenExpiry) >= 0 - - if (shouldRefreshTime) { - return await AuthProxy.refreshToken(token) - } - - return token - }, - signIn: async ({ user, account, ...props }) => { - if (account?.provider === 'yandex') { - const { data: result, status } = await AuthProxy.exchangeTokenYandex( - account.access_token! - ) - - if (status >= 400 && status < 500) { - return Promise.reject( - new Error( - ERROR_YANDEX_MAPPING[ - (result as { error_description: string }).error_description - ] - ) - ) - } - - return Promise.resolve(true) - } - - return Promise.resolve(true) - }, - async session({ session, token }) { - session.access = token.access - session.refresh = token.refresh - return session - }, - }, - pages: { - signIn: '/login', - error: '/login', - }, -} - -export default NextAuth(authOptions) @@ -3,7 +3,7 @@ import { User } from 'next-auth' import { JWT } from 'next-auth/jwt' import * as Sentry from '@sentry/browser' -// TODO: Replace with Zustand store function when needed +import { getAll } from '#/entities/user-account/model/user-type-slice' import { API_URL } from '#/shared/lib/constants' import { AuthConstants } from './constants' @@ -1,6 +0,0 @@ -import { MainPage } from '#/views/index' -import { getDefaultLayout } from '#/widgets/layouts' - -MainPage.getLayout = getDefaultLayout({ titlePage: 'AIR' }) - -export default MainPage @@ -0,0 +1,6 @@ +import { ImageModelsPage } from '#/views/images' +import { getDefaultLayout } from '#/widgets/layouts' + +ImageModelsPage.getLayout = getDefaultLayout({ title: 'Изображения' }) + +export default ImageModelsPage @@ -6,19 +6,18 @@ import * as https from 'https' import { NextPage } from 'next' import type { AppProps } from 'next/app' import { Inter, Raleway } from 'next/font/google' -import { SessionProvider, getSession } from 'next-auth/react' +import { getSession, SessionProvider } from 'next-auth/react' import { appWithTranslation } from 'next-i18next' import ErrorBoundary from './error-boundary' -import '#/app/styles/globals.scss' +import '#/app/styles/globals.css' import '#/app/styles/styles-pages/system.scss' import { Error } from '#/shared' import { pingFangFont } from '#/shared/lib/constants/font/font' import { useBlockTelegram } from '#/shared/lib/hooks/use-block-telegram' import { Providers } from '#/widgets/providers' -import { ERROR_MESSAGE, getModalById } from '#/features/modals' const inter = Raleway({ subsets: ['latin'] }) @@ -32,17 +31,8 @@ export interface AppPropsWithLayout extends AppProps { } function App({ Component, pageProps: { session, ...pageProps } }: AppPropsWithLayout) { - const modal = getModalById(ERROR_MESSAGE) - /* axios.interceptors.response.use( - (response) => response, - (error) => { - if (!error.response) { - modal.setState(true) - } - return error - } - ) */ useBlockTelegram() + const getLayout = Component.getLayout ?? ((page) => page) return ( @@ -2,7 +2,6 @@ import { PopupBackdrop } from '#/shared/ui/popup' import { Head, Html, Main, NextScript } from 'next/document' export default function Document() { - return ( @@ -20,8 +19,8 @@ export default function Document() { trackLinks:true, accurateTrackBounce:true, webvisor:true - }); - `, + }); + `, }} /> @@ -39,7 +38,6 @@ export default function Document() {
- @@ -1,7 +1,7 @@ -import { MainPage } from '#/views/main' +import { MainPage } from '#/views/index' import { getDefaultLayout } from '#/widgets/layouts' -MainPage.getLayout = getDefaultLayout({ titlePage: 'Главная' }) +MainPage.getLayout = getDefaultLayout({ titlePage: 'AIR' }) export default MainPage @@ -1,7 +1,6 @@ import { LoginPage } from '#/views/login' import { getLayout, LayoutWithoutSideMenu } from '#/widgets/layouts' - LoginPage.getLayout = getLayout(LayoutWithoutSideMenu, { titlePage: 'Авторизация' }) export default LoginPage @@ -1,6 +0,0 @@ -import { UpscalePage } from '#/views/upscale' -import { getDefaultLayout } from '#/widgets/layouts' - -UpscalePage.getLayout = getDefaultLayout({ titlePage: 'Upscale' }) - -export default UpscalePage @@ -12,7 +12,6 @@ import { Device } from '#/shared/lib/types/entities' import { IMessageRequest } from '#/shared/lib/types/types-gpt' import { Message, MessageSend } from '#/entities/message' import { Variant } from '#/shared/lib/hooks/use-show-data' -import { useBalanceStore } from '#/entities/balance/model/use-balance-store' const formDataHelper = (file: File, dataForSend: MessageSend): FormData => { const FD = new FormData() @@ -74,7 +73,6 @@ export function useModel( const [messages, setMessages] = useState(null) const [loading, setLoading] = useState(false) const [offset, setOffset] = useState(0) - const { getUserBalance } = useBalanceStore() useEffect(() => { if (currentChat) { @@ -182,9 +180,10 @@ export function useModel( setLoading(false) + // clearTimeout(timeout) + if (status >= 400) { userMessage.is_sent = false - setMessages((prev) => [...prev!, userMessage]) const error = result as { detail: string } if (error.detail) return showMessage(error.detail) @@ -276,7 +275,6 @@ export function useModelImages( const [messages, setMessages] = useState([]) const [loading, setLoading] = useState(false) - const { getUserBalance } = useBalanceStore() const [isComplete, setIsComplete] = useState(false) @@ -360,6 +358,7 @@ export function useModelImages( setMessages([...messagesRef.current, ...answer]) setOffset((prev) => prev + answer.length) } else { + showMessage('Ошибка загрузки сообщений') return } @@ -381,16 +380,14 @@ export function useModelImages( setLoading(false) if (result.hasOwnProperty('error')) { + const message = (result.details as AxiosError).response.data.trim() ?? 'Ошибка отправки сообщения' showMessage(message) return } - // Обновляем баланс после создания изображения - if (data?.access) { - getUserBalance(data.access) - } + // TODO: Add getUserBalance to Zustand store //@ts-ignore setMessages((prev) => { @@ -463,7 +460,6 @@ export function useMedia(showMessage: (message: string) => void, modelType: stri const [loading, setLoading] = useState(false) const [input, setInput] = React.useState('') - const { getUserBalance } = useBalanceStore() useEffect(() => { if (data?.access) { @@ -493,9 +489,9 @@ export function useMedia(showMessage: (message: string) => void, modelType: stri const userMessage: Message = { content: input, - info: {}, - model: modelType, + info: null, is_sent: true, + model: '', file: null, from_model: false, uid: 'new-send', @@ -535,10 +531,7 @@ export function useMedia(showMessage: (message: string) => void, modelType: stri setMessages((prev) => [...prev!, ...(result as Message[])]) setInput('') - // Обновляем баланс после отправки сообщения - if (data?.access) { - getUserBalance(data.access) - } + // TODO: Add getUserBalance to Zustand store } return { messages, sendMessage, loading, input, setInput } @@ -2,7 +2,7 @@ import axios, { AxiosResponse } from 'axios' import { User } from 'next-auth' import { API_URL } from '#/shared/lib/constants' -import { IOffer } from '#/widgets/payment/ui/payment' +import { IOffer } from '#/widgets/payment/model/payment' interface IUserBalance { current_token_balance: number @@ -1,2 +1,2 @@ export * from './instance' -export * from './private-request' +export * from './private-request' \ No newline at end of file @@ -3,7 +3,6 @@ import { useRouter } from 'next/navigation' import { api } from './instance' import axios, { InternalAxiosRequestConfig } from 'axios' import { useCallback } from 'react' -import { ERROR_MESSAGE, getModalById } from '#/features/modals' export function makePrivateRequest( callback: (...params: Params) => Promise @@ -12,8 +11,6 @@ export function makePrivateRequest( const { push } = useRouter() - const modal = getModalById(ERROR_MESSAGE) - const onRequest = async (config: any) => { if (config.headers.Authorization) return config @@ -29,8 +26,6 @@ export function makePrivateRequest( api.interceptors.response.use( async ({ status, ...r }) => { - if ([402, 403, 404].includes(status)) modal.setState(true) - if (![401].includes(status)) return { status, ...r } const session = await update('refresh') @@ -44,7 +39,7 @@ export function makePrivateRequest( return { status, ...r } }, (error) => { - if (!error.respose) return modal.setState(true) + if (!error.respose) return (window.location.href = '/network-error') } ) @@ -1,11 +1,10 @@ import { FieldValues, Path } from 'react-hook-form' import { RegisterOptions } from 'react-hook-form/dist/types/validator' -export const EMAIL_REGEXP = +const EMAIL_REGEXP = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/iu -export const PHONE_REGEXP = /^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$/ - +const PHONE_REGEXP = /^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$/ export const emailOptions: RegisterOptions = { required: 'Поле email обязательно к заполенению!', @@ -1,2 +1 @@ export { API_HOST, API_URL, ModelPagesList, surpriseMePrompts } from './constants' -export * from './hook-form-options' \ No newline at end of file @@ -1,18 +1,5 @@ export function formatAndSortDates(inputArray: { date: string; value: number }[]) { - const monthNames = [ - 'янв', - 'фев', - 'мар', - 'апр', - 'май', - 'июн', - 'июл', - 'авг', - 'сен', - 'окт', - 'ноя', - 'дек', - ] + const monthNames = ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'] const formattedData = inputArray.map((item: any) => { const date = new Date(item.date) @@ -36,14 +23,14 @@ export function formatAndSortDates(inputArray: { date: string; value: number }[] } export function formatDate( - date: string | number | Date, - options: Intl.DateTimeFormatOptions, - lang?: string + date: string | number | Date, + options: Intl.DateTimeFormatOptions, + lang?: string ) { - if (typeof date !== 'object') { - date = new Date(typeof date === 'number' ? date : Date.parse(date)) - } + if (typeof date !== "object") { + date = new Date(typeof date === "number" ? date : Date.parse(date)) + } - const formatter = Intl.DateTimeFormat('ru', options) - return formatter.format(date) + const formatter = Intl.DateTimeFormat("ru", options) + return formatter.format(date) } @@ -5,8 +5,7 @@ export * from './get-type-device' export * from './get-random-image' export * from './string' export * from './date-helper' -export * from './object' export * from './image' export * from './file' export * from './pending' -export * from './context' +export * from './context' \ No newline at end of file @@ -1,6 +0,0 @@ -export function keysToValues(obj: Record) { - return Object.keys(obj).reduce( - (prev, curr) => ({ ...prev, [obj[curr]]: curr }), - {} as Record - ) -} @@ -2,7 +2,6 @@ import React from 'react' import { ModelInputs } from '#/shared/api/models/models' import { Device, DeviceOs } from '#/shared/lib/types/entities' -import { Message } from '#/entities/message' export type MessageSend = { content: string @@ -10,6 +9,18 @@ export type MessageSend = { info: T } +export type Message = { + content: string + created_at: string + elapsed_time: string + file: File | null | string + from_model: boolean + info: null + is_favourite: boolean + is_sent: boolean + uid: string +} + /* Дополнительные элементы в Инпуте **/ type Elements = { element: React.ReactElement @@ -1,44 +0,0 @@ -.main { - width: 100%; - display: flex; - justify-content: flex-start; - gap: 20px; - margin-bottom: 24px; - - .chatWindow { - width: 70%; - } - - .settings { - width: 25%; - } - - @media (max-width: 768px) { - width: 100%; - display: flex; - - flex-direction: column-reverse; - - .chatWindow { - width: 100%; - } - - .settings { - width: 100%; - } - } -} -.wrapModelTitle { - margin-bottom: 20px; - margin-top: 15px; - @media (max-width: 768px) { - margin: 0; - margin-top: 15px; - } -} - -.bigTitle { - @media (max-width: 768px) { - font-size: 26px !important; - } -} @@ -2,11 +2,11 @@ border: none; outline: none; background-color: transparent; - padding: 16px 25px; - cursor: pointer; display: flex; align-items: center; justify-content: center; + padding: 15px 25px; + cursor: pointer; &_outline { border-radius: 15px; @@ -50,10 +50,13 @@ color: white; border-radius: 12px; font-weight: 500; - font-size: 16px; + font-size: 15px; transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out; &:hover { background-color: var(--text-color-purple); + &:hover { + opacity: 0.7; + } } } @@ -73,6 +76,6 @@ html[data-theme='dark'] { .button_gray { color: white !important; - background-color: #D9D9D91A !important; + background-color: #5d5a5a !important; } } @@ -1,5 +1,4 @@ import { c } from '#/shared/lib/helpers' -import { forwardRef } from 'react' import styles from './common-button.module.scss' export type ButtonVariant = 'outline' | 'primary' | 'primary-outline' | 'gray' @@ -9,22 +8,19 @@ export interface CommonButtonProps extends React.ButtonHTMLAttributes( - ({ children, variant = 'outline', className, disabled, ...props }, ref) => { - return ( - - ) - } -) +export const CommonButton = ({ children, variant = 'outline', className, disabled, ...props }: CommonButtonProps) => { + return ( + + ) +} @@ -1,50 +0,0 @@ -.input { - display: none; -} - -.checkbox { - display: flex; - align-items: center; - gap: 10px; - - &__iconbox { - &_primary { - border-radius: 3px; - border: 2px solid var(--air-color); - min-width: 22px; - min-height: 22px; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.2s ease-in-out; - } - - &_active { - background-color: var(--air-color); - } - } - - &__icon { - transition: all 0.1s ease-in; - opacity: 0; - - &_primary { - color: #151518; - } - - &_active { - opacity: 1; - } - } - - &__text { - - } -} - - -html[data-theme='light'] { - .checkbox__icon_primary{ - color: white; - } -} \ No newline at end of file @@ -1,83 +0,0 @@ -import { c } from '#/shared/lib/helpers' -import DoneIcon from '#/assets/svg/done.svg?react' -import styles from './common-checkbox.module.scss' -import { forwardRef } from 'react' - -export type CheckboxVariant = 'primary' - -export type CheckboxSize = 'md' - -export interface CheckboxProps - extends Omit, 'size' | 'placeholder'> { - name: string - value: boolean - className?: string - variant?: CheckboxVariant - placeholder?: string | React.ReactNode - required?: boolean - size?: CheckboxSize - withoutAnimation?: boolean - children?: React.ReactNode -} - -export const CommonCheckbox = forwardRef( - ( - { - id, - name, - className, - placeholder, - children, - value, - variant = 'primary', - size = 'md', - required = false, - withoutAnimation = false, - ...props - }, - ref - ) => { - return ( - <> - - - - ) - } -) @@ -1 +0,0 @@ -export * from './common-checkbox' \ No newline at end of file @@ -1,2 +0,0 @@ - -export * from "./ui" \ No newline at end of file @@ -8,13 +8,11 @@ import { CommonTooltip } from '#/shared/ui/tooltip' import { SelectItem } from '../types/select-item' import { CSSTransition } from 'react-transition-group' -interface CommonSelectProps extends HtmlHTMLAttributes { +interface CommonSelectProps extends HtmlHTMLAttributes { value: string | null | undefined setValue: (value: string) => void items: SelectItem[] withoutTooltip?: boolean - classNameList?: string - onSetState?: (state: boolean) => void } export const CommonSelect = ({ @@ -22,8 +20,6 @@ export const CommonSelect = ({ setValue, items, withoutTooltip = false, - classNameList, - onSetState, ...props }: CommonSelectProps) => { const ref = useRef(null) @@ -41,8 +37,6 @@ export const CommonSelect = ({ [ref] ) - useEffect(() => onSetState && onSetState(opened), [opened]) - useEffect(() => { window.addEventListener('click', callback) return () => window.removeEventListener('click', callback) @@ -56,6 +50,7 @@ export const CommonSelect = ({ e.stopPropagation() setOpened((x) => !x) }} + {...props} >

{item?.label}

-
    +
      {items.map(({ label, description, ...item }) => (
    • { @@ -3,6 +3,7 @@ import { FieldError } from 'react-hook-form' import styles from './common-textarea.module.scss' import React, { ForwardedRef, forwardRef, useEffect, useImperativeHandle } from 'react' import { Raleway } from 'next/font/google' +import { useMask } from '@react-input/mask' export type TextAreaVariant = 'default' | 'outline' @@ -1,16 +1,14 @@ import React from 'react' -import CircularProgress, { CircularProgressProps } from '@mui/material/CircularProgress' +import CircularProgress from '@mui/material/CircularProgress' -export interface LoaderProps extends CircularProgressProps {} - -export const Loader = ({ size = 25, thickness = 2, ...props }: LoaderProps) => { +export const Loader = (props: any) => { return ( ) @@ -1,25 +0,0 @@ -@keyframes scroll { - 0% { - transform: translateY(0); - } - 100% { - transform: translateY(-100%); - } -} - -.marque{ - display: flex; - flex-direction: column; - width: 100%; - overflow: hidden; - max-height: 100dvh; - gap: 10px; - &__wrap{ - width: 100%; - height: max-content; - gap: 10px; - display: flex; - flex-direction: column; - animation: scroll var(--scroll-time) linear infinite; - } -} \ No newline at end of file @@ -1,30 +0,0 @@ -import React, { useEffect, useRef } from 'react' -import styles from './common-marque.module.scss' -import { c } from '#/shared/lib/helpers' - -interface CommonMarqueProps { - children: React.ReactNode - className?: string - speed?: number - scrollTime?: number -} - -export const CommonMarque = ({ - children, - className, - scrollTime = 20, -}: CommonMarqueProps) => { - const container = useRef(null) - - useEffect(() => { - if(!container.current) return - container.current.style.setProperty('--scroll-time', `${scrollTime}s`) - }, []) - - return ( -
      -
      {children}
      -
      {children}
      -
      - ) -} @@ -1 +0,0 @@ -export * from './common-marque' \ No newline at end of file @@ -1 +0,0 @@ -export * from './ui' \ No newline at end of file @@ -15,7 +15,7 @@ export const Modal: FC = ({ open, onClose, children }) => { const theme = useThemeStore((state) => state.theme) return ( - = (e) => { e.stopPropagation() - // document.body.style.overflow = 'hidden' + document.body.style.overflow = 'hidden' setHovered(true) } const onMouseLeave: MouseEventHandler = (e) => { e.stopPropagation() - // document.body.style.overflow = 'visible' + document.body.style.overflow = 'visible' setHovered(false) } @@ -211,6 +211,7 @@ export function useListenersWheel( clampTranslateY() applyTransform() + onScrolling && onScrolling(translateYRef.current) }, [clampTranslateY, applyTransform] @@ -244,6 +245,7 @@ export function useListenersWheel( clampTranslateY() targetTranslateYRef.current = translateYRef.current applyTransform() + onScrolling && onScrolling(translateYRef.current) } @@ -85,7 +85,7 @@ export const CommonScrollbar = forwardRef { e.preventDefault() - // document.body.style.overflow = 'hidden' + document.body.style.overflow = 'hidden' }} className={c('container', styles.scroll__container)} > @@ -1 +0,0 @@ -export * from './send-button' \ No newline at end of file @@ -1,9 +0,0 @@ -.button{ - background-color: var(--air-color); - width: 30px; - height: 30px; - border-radius: 100%; - display: flex; - align-items: center; - justify-content: center; -} \ No newline at end of file @@ -1,20 +0,0 @@ -import React from 'react' -import CircularProgress from '@mui/material/CircularProgress' -import SendSvg from '#/assets/svg/send.svg?react' -import { Loader } from '#/shared/ui/loader' -import styles from './send-button.module.scss' - -interface SendButtonProps extends React.ButtonHTMLAttributes { - loading: boolean -} - -export const SendBtn = ({ loading, ...props }: SendButtonProps) => { - if (loading) { - return - } - return ( - - ) -} @@ -1 +0,0 @@ -export * from './ui' \ No newline at end of file @@ -5,13 +5,12 @@ border-radius: 9px; background: #ececff; color: var(--air-color); - padding: 5px 10px; + padding: 6px 12px; max-width: 340px; width: max-content; position: absolute; left: 50%; font-weight: 500; - z-index: 1000000; transition: all 0.3s ease-in-out; top: 140%; @@ -84,10 +83,9 @@ } &_left { - font-size: 13px; background-color: white; top: 50%; - right: calc(100% + 20px); + right: 100%; left: unset; padding: 12px 16px; transform: translateY(-50%) scale(0.9); @@ -119,42 +117,6 @@ } } - &_right { - background-color: white; - top: 50%; - left: 210%; // Появляется справа от элемента - right: unset; - padding: 12px 16px; - transform: translateY(-50%) scale(0.9); - - &_exiting { - opacity: 0; - } - - &_entered { - transform: translateY(-50%) scale(1); - opacity: 1; - } - - &_entering { - transform: translateY(-50%) scale(1); - opacity: 1; - } - - &::after { - content: ''; - position: absolute; - top: 50%; - right: 100%; - left: unset; - transform: translateY(-50%); - width: 12px; - height: 12px; - background-color: #ececff; - clip-path: polygon(100% 0, 0% 50%, 100% 100%); - } - } - &__heading { font-size: 17px; line-height: 1.5; @@ -12,11 +12,7 @@ interface IAccountMenu { device?: 'mobile' | 'desktop' } -export const AccountMenu: React.FC = ({ - anchorEl, - changeVisible, - device = 'desktop', -}) => { +export const AccountMenu: React.FC = ({ anchorEl, changeVisible, device = 'desktop' }) => { const { data } = useSession() const goAccount = async () => { await Router.push('/account') @@ -8,7 +8,8 @@ interface ICheckBoxAgreeWithRulesProps { changeAgree?: () => void isAgreeError?: boolean register?: UseFormRegister - name: string + name?: string + isEmailWhite: boolean } export const CheckBoxAgreeWithRules: React.FC = ({ @@ -17,13 +18,16 @@ export const CheckBoxAgreeWithRules: React.FC = ({ isAgreeError, name, register, + isEmailWhite, }) => { return ( <> void - device: 'mobile' | 'desktop' -} - -const ErrorModal: React.FC = ({ open, handleClose, device }) => { - const [errorMessage, setErrorMessage] = React.useState('') - - const [error, setError] = React.useState(false) - - const [isSend, setIsSend] = React.useState(false) - - const [file, setFile] = React.useState() - - const { data: session } = useSession() - - const getUser = useUserStore((state) => state.getUser) - const email = getUser()?.email || '' - - const theme = useThemeStore((state) => state.theme) - - const handleFileChange = (e: ChangeEvent) => { - if (e.target.files) { - if (4500000 > e.target.files[0].size) setFile(e.target.files[0]) - } - } - const sendError = async () => { - if (errorMessage.trim() === '') { - setError(true) - setTimeout(() => setError(false), 3000) - return - } - - let formData: any = new FormData() - - formData.append('report_text', `${email}: ${errorMessage}`) //append the values with key, value pair - if (file) { - formData.append('images', file) - } - - try { - const { status } = await axios.post(API_URL + '/reports/', formData, { - headers: { - 'content-type': 'multipart/form-data ', - 'content-length': file ? `${file.size}` : '', - - Authorization: `Bearer ${session?.access}`, - }, - }) - - if (status === 201) { - setErrorMessage('') - setIsSend(true) - setTimeout(() => { - setIsSend(false) - handleClose() - }, 4000) - } - } catch (err) { - setError(true) - setTimeout(() => setError(false), 3000) - } - } - - return ( - - {isSend ? ( - - - Спасибо! - - - Ваше сообщение направлено нашим специалистам. Ответ придет на почту, - указанную при регистрации - - - ) : ( - - - Сообщить об ошибке - - setErrorMessage(evt.target.value)} - InputProps={{ - startAdornment: ( - <> - - - ), - }} - sx={{ - marginTop: 2.5, - marginBottom: 1.2, - fontSize: 13, - '& label': { color: '#8853FA' }, - backgroundColor: theme === 'light' ? 'transparent' : '#3D3D3D', - '& .MuiOutlinedInput-input': { - color: theme === 'light' ? '#272727' : '#E1E1E1', - }, - }} - /> - {file && ( - - - Добавлено 1 изображение: {file.name} - - setFile(undefined)} - sx={{ - width: '18px', - height: '18px', - cursor: 'pointer', - marginLeft: '3px', - marginTop: '2px', - }} - /> - - )} - - - - - - - )} - - ) -} - -export default ErrorModal @@ -1,5 +1,4 @@ export { emailOptions, onlyNumbersOption } from './lib/constants/hook-form-options' -export { useConcat } from './lib/helpers' export { translateTypeModel } from './lib/helpers/model-helpers' export { useAutoLoad } from './lib/hooks/use-auto-load' export { AccountMenu } from './ui/account-menu' @@ -17,6 +16,7 @@ export { Input, InputStyleDark, InputStyleLight } from './ui/input' export { InputImagesModels } from './ui/input-images-models/input-images-models' export { Loader } from './ui/loader/ui/loader' export type { ModalProps } from './ui/modal/modal' +export { useConcat } from './lib/helpers' export { Modal } from './ui/modal/modal' export { NotificationMenu } from './ui/notification-menu' export { RandomImage } from './ui/random-image' @@ -0,0 +1,2 @@ +export * from './payment.routes' +export * from './settings.routes' \ No newline at end of file @@ -0,0 +1,11 @@ +import { api } from '#/shared/api' +import { IOffer } from '#/widgets/payment/model/payment' +import { PayProductResponse } from '../types' + +export function getPaymentsPlans() { + return api.get('/payments/plans') +} + +export function payProduct(plan: string) { + return api.post('/payments/plans', { uid: plan, is_test: 1 }) +} @@ -0,0 +1,23 @@ +import { api } from '#/shared/api' +import { objectToFormdata } from '#/shared/lib/helpers/form' +import { ChangePassword, ChangePicture, UpdateUserSettings } from '../types' + +export function putUserSettings(email: string, dto: UpdateUserSettings) { + return api.put('/auth/user-data', { email: email, ...dto }) +} + +export function changePassword(dto: ChangePassword) { + return api.put('/auth/reset-pass', dto) +} + +export function putProfilePicture(dto: ChangePicture) { + return api.put('/auth/reset-profile-pic', objectToFormdata(dto)) +} + +export function deleteAccount() { + return api.delete('/auth/remove') +} + +export function activePromocode(code: string) { + return api.post('/payments/promocode', { code }) +} @@ -0,0 +1,49 @@ +import { useForm } from 'react-hook-form' +import { makePrivateRequest } from '#/shared/api' +import { useShowDataStore } from '#/shared/lib/hooks' +import { withPending } from '#/shared' +import { ChangePasswordForm } from '../types' +import { changePassword } from '../api' + +export function useAccountChangePasswordForm(onClose?: Function) { + const { + handleSubmit, + register, + reset, + setValue, + getValues, + watch, + formState: { errors, isDirty }, + } = useForm() + + const { showMessage } = useShowDataStore() + + const [onSubmit, loading] = withPending( + handleSubmit( + makePrivateRequest(async (dto) => { + const { data, status } = await changePassword(dto) + + if (![201, 200].includes(status)) return showMessage((data as { detail: string }).detail) + + showMessage('Пароль успешно изменен', 'success') + + onClose && onClose() + + reset() + }), + (errors) => showMessage(Object.values(errors)[0].message ?? 'Неверные данные') + ) + ) + + return { + register, + reset, + setValue, + getValues, + onSubmit, + loading, + watch, + errors, + isDirty, + } +} @@ -0,0 +1,4 @@ +export * from './use-payment-page' +export * from './use-settings-page' +export * from './use-account-settings.form' +export * from './change-password.form' \ No newline at end of file @@ -0,0 +1,58 @@ +import { useForm } from 'react-hook-form' +import { makePrivateRequest } from '#/shared/api' +import { useShowDataStore } from '#/shared/lib/hooks' +import { withPending } from '#/shared' +import { AccountSettingsForm } from '../types' +import { putUserSettings } from '../api' +import { useUser } from '#/entities/user-account' + +export function useAccountSettingsForm(onClose?: Function) { + const { + handleSubmit, + register, + reset, + setValue, + getValues, + watch, + formState: { errors, isDirty }, + } = useForm() + + const { showMessage } = useShowDataStore() + + const { getUser, setUser } = useUser() + + const { email } = getUser() + + const [onSubmit, loading] = withPending( + handleSubmit( + makePrivateRequest(async (dto) => { + // if (isDirty) return showMessage('Вы не изменили каких либо данных') + + const { data, status } = await putUserSettings(email, dto) + + if (![201, 200].includes(status)) return showMessage((data as { detail: string }).detail) + + setUser({ ...getUser(), ...dto }) + + showMessage('Данные успешно обновлены', 'success') + + onClose && onClose() + + reset() + }), + (errors) => showMessage(Object.values(errors)[0].message ?? 'Неверные данные') + ) + ) + + return { + register, + reset, + setValue, + getValues, + onSubmit, + loading, + watch, + errors, + isDirty, + } +} @@ -0,0 +1,34 @@ +import { makePrivateRequest } from '#/shared/api' +import { useShowDataStore } from '#/shared/lib/hooks' +import { useState } from 'react' +import { getPaymentsPlans, payProduct } from '../api' +import { IOffer } from '#/widgets/payment/model/payment' + +export function usePaymentPage() { + const { showMessage } = useShowDataStore() + + const [offers, setOffers] = useState(null) + + const fetchPaymentPlans = makePrivateRequest(async () => { + const { data, status } = await getPaymentsPlans() + + if (status !== 200) return showMessage('Ошибка получения платежных планов') + + setOffers(data) + }) + + const pay = makePrivateRequest(async (uid: string) => { + const { data, status } = await payProduct(uid) + + if (status >= 400) return showMessage('Ошибка создания платежа') + + window.open(data.payment_url, '_blank') + }) + + return { + fetchPaymentPlans, + pay, + offers, + setOffers + } +} @@ -0,0 +1,70 @@ +import { withPending } from '#/shared' +import { makePrivateRequest } from '#/shared/api' +import { useRef, useState } from 'react' +import { activePromocode, deleteAccount, putProfilePicture } from '../api' +import { useUser } from '#/entities/user-account' +import { useShowDataStore } from '#/shared/lib/hooks' +import { signOut } from 'next-auth/react' +import { useBalance } from '#/entities/balance' + +export function useSettingsPage() { + const fileInputRef = useRef(null) + + const { setUser, getUser } = useUser() + + const { showMessage } = useShowDataStore() + + const [promocode, setPromocode] = useState('') + + const { fetchUserBalance } = useBalance() + + const [handleFileChange, loading] = withPending( + makePrivateRequest(async (event: any) => { + const { current } = fileInputRef + + if (!current || !current.files) return + + const { status, data } = await putProfilePicture({ new_picture: current.files[0] }) + + if (status >= 400) return showMessage('Ошибка загрузки изображения на сервере') + + setUser({ ...getUser(), profile_picture_link: URL.createObjectURL(event.target.files[0]) }) + + showMessage('Изображение успешно загружено!', 'success') + }) + ) + + const removeAccount = makePrivateRequest(async () => { + const { status } = await deleteAccount() + + if (status === 200) return await signOut() + + showMessage('Ошибка удаления аккаунта') + }) + + const statuses: Record = { + 200: 'Промокод успешно активирован! Токены уже зачислены!', + 403: 'Промокод уже был активирован!', + 404: 'Промокод не найден!', + } + + const promocodeActivate = makePrivateRequest(async () => { + if (promocode.trim() === '') return showMessage('Введите корректный промокод') + + const { status } = await activePromocode(promocode) + + if (status === 200) fetchUserBalance() + + statuses[status] && showMessage(statuses[status]) + }) + + return { + fileInputRef, + handleFileChange, + loading, + removeAccount, + promocode, + setPromocode, + promocodeActivate, + } +} @@ -0,0 +1,4 @@ +import { UpdateUserSettings } from './account-settings' + +export interface AccountSettingsForm extends UpdateUserSettings {} + \ No newline at end of file @@ -0,0 +1,15 @@ +export interface UpdateUserSettings { + username: string + first_name: string + last_name: string +} + +export interface ChangePassword { + password_1: string + password_2: string + current_password: string +} + +export interface ChangePicture { + new_picture: File +} \ No newline at end of file @@ -0,0 +1,4 @@ +import { ChangePassword } from './account-settings' + +export interface ChangePasswordForm extends ChangePassword {} + \ No newline at end of file @@ -1 +1,4 @@ -export * from './payments' \ No newline at end of file +export * from './payments' +export * from './account-settings-form' +export * from './account-settings' +export * from './change-password-form' \ No newline at end of file @@ -3,3 +3,7 @@ export interface IPaymentsPlan { price: string tokens_per_plan: string } + +export interface PayProductResponse { + payment_url: string +} @@ -0,0 +1,129 @@ +.toggle_button { + padding: 0; + margin-right: 12px; + border: none; +} + +.toggle_button:hover { + background-color: transparent; +} + +.wrap_toggle_button { + border: none; + border-radius: 13px; + text-transform: none; + font-weight: 500; + font-size: 15px; + /*white-space: nowrap;*/ + color: var(--new-ui-gray-color); +} + +.wrap_toggle_button_active { + border: none; + background-color: var(--new-ui-main-color); + border-radius: 13px; + text-transform: none; + font-weight: 500; + font-size: 15px; + color: var(--text-color-main); +} + +.toggle_text_active { + font-weight: 500; + font-size: 15px; + color: var(--text-color-main); +} + +.wrap_toggle_button_active_chat { + border: none; + background-color: #f2f2ff; + border-radius: 13px; + padding: 10px 15px; + text-transform: none; +} + +.toggle_text_active_chat { + font-weight: 500; + font-size: 15px; + color: #8280ff; +} + +.chat-item { + width: 100%; + border: none; + background-color: white; + border-radius: 13px; + padding: 10px 15px; + text-transform: none; +} +.chat-item_active { + width: 100%; + border: none; + background-color: #f2f2ff; + border-radius: 13px; + padding: 10px 15px; + text-transform: none; +} + +.chat-text { + font-weight: 500; + font-size: 15px; + color: var(--new-ui-main-color); +} + +.toggle_text { + font-weight: 500; + font-size: 15px; + /*white-space: nowrap;*/ + color: var(--new-ui-gray-color); + text-transform: none; +} + +.wrap { + display: flex; + flex-direction: column; + gap: 20px; +} + +.wrap_block { + width: 100%; + border-radius: 13px; + background-color: var(--new-ui-main-color); + padding: 30px; +} + +.mainform { + width: 100%; + margin-left: 30px; + + @media screen and (max-width: 1000px) { + margin-left: 0px; + } +} + +@media (max-width: 768px) { + .main_block { + width: 100%; + display: flex; + flex-direction: column; + } + + .main_block > div { + margin: 0; + } +} + +.main_block { + display: flex; + align-items: flex-start; + // justify-content: space-between; + margin-top: 20px; +} + +.input_title { + font-size: 15px; + margin-bottom: 5px; + margin-left: 3px; + font-weight: 400; + color: var(--new-ui-gray-color); +} @@ -1,21 +1,42 @@ import React, { useEffect, useRef, useState } from 'react' import { Avatar, Box, Button, Stack, Typography } from '@mui/material' +import axios from 'axios' import Image from 'next/image' import { signOut, useSession } from 'next-auth/react' -import styles2 from '#/app/styles/accountTabs.module.css' +import styles from './account-settings.module.scss' import { ButtonUI, Input, Loader, Modal, SwitchCustom } from '#/shared' -import { makePrivateRequest } from '#/shared/api' import { accountApi } from '#/shared/api/account-endpoints' import { API_URL } from '#/shared/lib/constants/constants' import { getDeviceType } from '#/shared/lib/helpers' import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' import { useUser } from '#/entities/user-account' +import { useAccountChangePasswordForm, useAccountSettingsForm, useSettingsPage } from '../model' +import { CommonInput } from '#/shared/ui/common-input' +import { CommonButton } from '#/shared/ui/button' -const AccountSettings: React.FC = () => { +const AccountSettings = () => { const { getUser, loaded, unfollowEmail, setUser } = useUser() + const { watch, register, onSubmit } = useAccountSettingsForm() + + const { onSubmit: onSubmitPass, register: registerPassword } = useAccountChangePasswordForm() + + const [confirmDeleteModal, setConfirmDeleteModal] = useState(false) + + const { showMessage } = useShowDataStore() + + const { + handleFileChange, + fileInputRef, + loading, + removeAccount, + promocode, + promocodeActivate, + setPromocode, + } = useSettingsPage() + const { email, is_subscribed_to_emails, @@ -26,176 +47,15 @@ const AccountSettings: React.FC = () => { is_social, } = getUser() - const device = getDeviceType() - const desktop = device === 'desktop' - - const [name, setName] = useState('') - const [lastName, setLastName] = useState('') - const [userName, setUserName] = useState('') - const fileInputRef = useRef(null) - const [loading, setLoading] = useState(false) - const { data } = useSession() - - const [currentPassword, setCurrentPassword] = useState('') - const [newPassword1, setNewPassword1] = useState('') - const [newPassword2, setNewPassword2] = useState('') - const [promocode, setPromocode] = useState('') - const [success, setSuccess] = useState('') - const [confirmDeleteModal, setConfirmDeleteModal] = useState(false) - - const { showMessage } = useShowDataStore() - - const handleDivClick = () => { - ;(fileInputRef.current! as any).click() - } - - const handleFileChange = makePrivateRequest(async (event: any) => { - const formData = new FormData() - formData.append('new_picture', event.target.files[0]) - - try { - setLoading(true) - const response = await fetch(API_URL + '/auth/reset-profile-pic', { - method: 'PUT', - headers: { - Authorization: `Bearer ${data?.access}`, - }, - body: formData, - }) - - if (response.ok) { - setUser({ ...getUser(), profile_picture_link: URL.createObjectURL(event.target.files[0]) }) - showMessage('Изображение успешно загружено!') - } else { - showMessage('Ошибка загрузки изображения на сервере!', 'error') - } - } catch (e) { - showMessage('Ошибка загрузки изображения на сервере!', 'error') - } finally { - setLoading(false) - } - }) - - const changePasswordHandler = makePrivateRequest(async () => { - if (newPassword1 !== newPassword2) { - showMessage('Укажите одинаковые новы пароли!') - return - } - - const status = await accountApi.changePassword( - data?.access || '', - newPassword1, - newPassword2, - currentPassword - ) - - if (status === 200) { - showMessage('Пароль успешно изменён!') - setNewPassword1('') - setNewPassword2('') - setCurrentPassword('') - setTimeout(() => setSuccess(''), 6000) - } else { - showMessage('К сожалению, произошла ошибка') - } - }) - - const isUserDataChange = React.useMemo( - () => name !== first_name || last_name !== lastName || username !== userName, - [name, lastName, userName] - ) - - const promocodeActivate = makePrivateRequest(async () => { - if (!promocode.trim()) { - showMessage('Введите корректный промокод') - return - } - - try { - const response = await fetch(API_URL + '/payments/promocode', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${data?.access}`, - }, - body: JSON.stringify({ code: promocode }), - }) - - if (response.status === 200) { - showMessage('Промокод успешно активирован! Токены уже зачислены!') - } else if (response.status === 403) { - showMessage('Промокод уже был активирован!') - } else if (response.status === 404) { - showMessage('Промокод не найден!') - } - } catch (e) { - showMessage('Ошибка активации промокода', 'error') - } - }) - - const changeUserData = makePrivateRequest(async () => { - if (!isUserDataChange) { - showMessage('Вы не изменили данные', 'success') - return - } - - try { - const response = await fetch(API_URL + '/auth/user-data', { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${data?.access}`, - }, - body: JSON.stringify({ - username: userName, - email: email, - first_name: name, - last_name: lastName, - }), - }) - - if (response.ok) { - showMessage('Данные успешно изменены!') - setUser({ ...getUser(), username: userName, email, first_name: name, last_name: lastName }) - } - } catch (e) { - showMessage('Ошибка изменения данных', 'error') - } - }) - - const deleteAccount = makePrivateRequest(async () => { - try { - const response = await fetch(API_URL + '/auth/remove', { - method: 'DELETE', - headers: { - Authorization: `Bearer ${data?.access}`, - }, - }) - - if (response.status === 200) { - await signOut() - } - } catch (err) { - showMessage('Ошибка удаления аккаунта', 'error') - } - }) - - useEffect(() => { - setName(first_name) - setLastName(last_name) - setUserName(username) - }, [first_name, last_name, username]) - return ( - <> - +
      + Основные - + - fileInputRef.current?.click()} + style={{ position: 'relative', }} > @@ -235,37 +95,37 @@ const AccountSettings: React.FC = () => { > {''} - + - +
      - Имя - setName(e.target.value)} - fullWidth + Имя + - Фамилия - setLastName(e.target.value)} - fullWidth + Фамилия + + - Email + Email { - if (!data) return await unfollowEmail() - showMessage('Данные изменены!') + showMessage('Данные изменены!', 'success') }} /> { - Никнейм - setUserName(e.target.value)} - fullWidth + Никнейм + - - + + Сохранить + +
      - + Активация промокода { {!is_social && ( - +
      Изменить пароль - + - Текущий пароль - setCurrentPassword(e.target.value)} - fullWidth + Текущий пароль + { }} > - Новый пароль - setNewPassword1(e.target.value)} - fullWidth + Новый пароль + - + Подтвердить пароль - setNewPassword2(e.target.value)} - fullWidth + - + + + Изменить пароль + - +
      )} - + Удаление аккаунта Удаление аккаунта приведет к потере всех настроек @@ -386,7 +239,7 @@ const AccountSettings: React.FC = () => { Вы действительно хотите удалить ваш аккаунт? - +
      ) } @@ -118,9 +118,7 @@ const Account: NextPageWithLayout = () => { height: '100%', }} > - - Ваш аккаунт - + Ваш аккаунт { - const [offers, setOffers] = useState(null) - const [selectedOffer, setSelectedOffer] = useState('') - const { data } = useSession() - const { showMessage } = useShowDataStore() - const { getUser } = useUserStore() - - const fetchPaymentsPlans = makePrivateRequest(async () => { - const result = await accountApi.getPaymentsPlans(data?.access || '') - - if (!result) return showMessage('Ошибка загрузки тарифов', 'error') - - setOffers(result) - if (result && result.length > 0) { - setSelectedOffer(result[0].uid) - } - }) - - const pay = makePrivateRequest(async (uid: string) => { - const urlForPay = await accountApi.payProduct(data?.access || '', uid) - - if (!urlForPay) return showMessage('Ошибка создания платежа', 'error') + const { offers, setOffers, fetchPaymentPlans, pay } = usePaymentPage() - window.open(urlForPay, '_blank') - }) + const device = getDeviceType() useEffect(() => { - if (data?.access) { - fetchPaymentsPlans() - } - }, [data?.access]) + fetchPaymentPlans() + }, []) const info = [ { @@ -63,7 +43,7 @@ const PaymentPage: NextPageWithLayout = () => { { }} > {offers?.map((offer) => { - return ( - setSelectedOffer(uid)} - key={offer.uid} - /> - ) + return })} @@ -1,12 +1,11 @@ import React from 'react' import { Box, CircularProgress } from '@mui/material' -import UserSettings from './ui/user-settings' - import styles from '#/app/styles/business.module.scss' import { useUserStore } from '#/entities/user-account' import { NextPageWithLayout } from '#/pages/_app' +import AccountSettings from './ui/account-settings' export const Settings: NextPageWithLayout = () => { const { getUser, loaded } = useUserStore() @@ -21,7 +20,7 @@ export const Settings: NextPageWithLayout = () => { return ( - + ) } @@ -1,73 +1,151 @@ -.model { - padding: 10px 12px; +.container { + width: 100%; border-radius: 15px; - display: flex; - align-items: center; - gap: 10px; - background-color: var(--new-ui-main-color); - width: max-content; + height: 100%; position: absolute; - top: 0; - left: 50%; - transform: translateX(-50%); - z-index: 3; + bottom: 0; + left: 0; + background-color: var(--new-ui-main-color); + opacity: 0; + z-index: -1; + transition: all 0.3s ease-in-out; - @media screen and (max-width: 1200px) { - top: 30px; + &_active { + opacity: 1; + z-index: 100; } } -.popup { - position: absolute; - top: 50%; - right: 20px; - transform: translateY(-50%); - z-index: 2; +.header { + width: 70%; + margin-bottom: 50px; + + @media screen and (max-width: 768px) { + width: 100%; + margin-bottom: 0px; + } } -.messages { - z-index: 2; - height: calc(100dvh - 20px - 20px - 40px - 25px); - overflow-y: scroll; +@keyframes fadein { + 0% { + opacity: 0; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } } -.input { - position: absolute; - bottom: 20px; - left: 50%; - transform: translateX(-50%); - z-index: 2; +// .blocked { +// display: flex; +// align-items: center; +// justify-content: center; +// background-color: white; +// border-radius: 100px; +// padding-right: 20px; +// padding: 8px 12px; +// width: max-content; + +// span { +// color: #ff2372; +// font-weight: 500; +// padding-left: 10px; +// font-size: 14px; +// width: max-content; +// } +// } + +.icon { +} - @media screen and (max-width: 800px) { - bottom: -10px; +.tags { + min-width: 100%; + display: flex; + gap: 8px; + align-items: center; + justify-content: flex-end; + + @media screen and (max-width: 768px) { + justify-content: flex-start; } } -.shape { - height: 100px; - position: absolute; - filter: blur(10px); - width: 100%; - left: 0; - right: 0; - background: linear-gradient( - 180deg, - var(--new-ui-bg-app-color) 0%, - var(--new-ui-bg-app-color) 30%, - rgba(255, 255, 255, 0) 100% - ); - z-index: 1; - &_top { - top: 0px; +.tag { + display: flex; + align-items: center; + justify-content: center; + background-color: white; + border-radius: 100px; + width: 50px; + height: 50px; + box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.1); + transition: width 0.3s ease-in-out; + + @media screen and (max-width: 768px) { + height: 40px; + width: 40px; + } + + &__icon { + color: var(--air-color); + } + + &:hover { + padding: 12px; + width: 200px; + + .tag__icon { + animation: fadein 0.6s ease-in-out; + } + + .tag__text { + opacity: 1; + position: static; + animation: fadein 0.6s ease-in-out; + display: block; + } } - &_bottom { - bottom: -20px; - transform: rotate(180deg); + &__text { + position: absolute; + color: var(--air-color); + font-weight: 500; + padding-left: 10px; + font-size: 14px; + opacity: 0; + display: none; + min-width: max-content !important; } } -.container { - padding-top: 20px; - position: relative; +.blocked { + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background-color: #c32528; + padding: 20px; + gap: 10px; + position: absolute; + + left: 0; + + width: 100%; + border-radius: 15px; + top: 0; + + @media screen and (max-width: 768px) { + top: unset; + // bottom: -22px; + z-index: 1; + border-radius: 15px; + } + + &__text { + color: white !important; + font-size: 16px; + font-weight: 600; + } } @@ -1,78 +1,249 @@ -import * as React from 'react' -import { useRouter } from 'next/router' -import { useSession } from 'next-auth/react' -import { Error } from '#/shared' -import { ImageMessagesList } from '#/widgets/messages/ui/image-messages-list' -import { c, getDeviceType } from '#/shared/lib/helpers' +import { useEffect } from 'react' +import { Box, Stack } from '@mui/material' import Head from 'next/head' +import { useRouter } from 'next/router' import styles from './image-model.module.scss' -import { NextPageWithLayout } from '#/pages/_app' -import { useImageBot } from '#/entities/model-entity/model/use-image-bot' -import { ImageModelsSelect } from '#/widgets/image-models-popup' -import { ImageInput } from '#/features/image-models-input' -import { useEffect, useRef } from 'react' -import { useMessagesStore } from '#/widgets/messages' -import { ImagesEmpty } from '#/widgets/image-messages' -import { MessageFastChoiceMenu } from '#/features/message-fast-choice-menu' -import { useShowDataStore } from '#/shared/lib/hooks' +import BlockedSvg from '#/assets/svg/blocked.svg?react' +import { useImageBot } from '#/entities/model-entity/model/use-image-bot' +import { useImageBotCreateImage } from '#/features/image-bot-create-image' +import { useImagesBotFilters } from '#/features/image-bot-filters' +import { useImageBotPagination } from '#/features/image-bot-pagination' +import { NextPageWithLayout } from '#/pages/_app' +import { Loader } from '#/shared' +import { c, getDeviceType, getOs } from '#/shared/lib/helpers' +import { useThemeAndDevice } from '#/shared/lib/hooks' +import { SvgIcon } from '#/shared/ui/svg' +import { ImageMessagesList } from '#/widgets/messages' +import { ModelInput } from '#/features/model-input' +import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' +import { CommonTitle } from '#/shared/ui/title' +import { ImageModelOptions } from '#/widgets/image-model-options' +import { useImageBotInput } from '#/features/image-bot-input' +import { POPUP_IMAGE_BOT_PARAMS, getPopupById } from '#/shared/ui/popup' const ImageModelPage: NextPageWithLayout = () => { - const { query } = useRouter() + const { botParams, fetchBotParams } = useImageBot() + + const deviceType = getDeviceType() - const { botParams, inference, fetchBotParams } = useImageBot() + const deviceOs = getOs() - const container = useRef(null) + const { desktop } = useThemeAndDevice(deviceType, deviceOs) - const deviceType = getDeviceType() + const { + refScrollMobile, + refScrollDesktop, + mobileScrollContainer, + onObserverMounted, + fetchMessages, + loading, + offset, + messages, + } = useImageBotPagination(deviceType) - const { data: session } = useSession() + const { createImage } = useImageBotCreateImage(deviceType, mobileScrollContainer, offset) - const { messages, loading } = useMessagesStore() + const { onSendMessage, file, setFile, valueInput, setValueInput, inputTypes, requiredTypes } = + useImageBotInput(createImage) async function onFetch() { await Promise.all([fetchBotParams()]) } + const popup = getPopupById(POPUP_IMAGE_BOT_PARAMS) + useEffect(() => { onFetch() - }, [session, query]) - + onObserverMounted() + }, [botParams?.slug]) return ( -
      + <> - Модель {botParams ? botParams.title : 'Загрузка...'} + {botParams ? botParams?.title : 'Загрузка...'} -
      -

      Модель

      - +
      + + {botParams && + botParams.tags.map((tag, index) => ( +
      + + + {tag.title} +
      + ))} +
      + } + />
      -
      - -
      - {!loading && messages.length === 0 ? ( - - ) : ( - - )} -
      - -
      - -
      - -
      - -
      - -
      -
      + + {desktop ? ( + <> + + popup.toogleState()} + inputTypes={inputTypes} + blocked={botParams ? !botParams.enabled : false} + sendMessage={(message) => onSendMessage(message, requiredTypes)} + /> + + {botParams && !botParams.enabled && ( +
      + + + Модель недоступна + +
      + )} +
      + + + + + + ) : ( + +
      +
      + +
      +
      +
      + +
      + +
      + + + {botParams && ( + popup.toogleState()} + inputTypes={inputTypes} + blocked={botParams ? !botParams.enabled : false} + sendMessage={(message) => + onSendMessage(message, requiredTypes) + } + /> + )} + {botParams && !botParams.enabled && ( +
      + + + Модель недоступна + +
      + )} +
      +
      +
      + )} +
      + {desktop && } +
      + ) } @@ -13,12 +13,9 @@ margin-right: 60px; - @media screen and (min-width: 1820px) { - margin-right: 240px; - grid-template-columns: repeat(auto-fit, 360px); - } - @media screen and (max-width: 1000px) { margin-right: 0px; } } + + @@ -1,21 +1,21 @@ import * as React from 'react' import { useEffect, useState } from 'react' -import { Typography } from '@mui/material' +import { Box, Typography } from '@mui/material' import CircularProgress from '@mui/material/CircularProgress' +import { useSession } from 'next-auth/react' import { useImageBots } from '../model' -import { useUserStore } from '#/entities/user-account' import styles from './image-models.module.scss' import { ImageModelCard, ShortModel } from '#/entities/model-entity' +import { useUserStore } from '#/entities/user-account' import { NextPageWithLayout } from '#/pages/_app' export const ImageModelsPage: NextPageWithLayout = () => { const { getUser } = useUserStore() const user = getUser() - const { payment_plan } = user || { payment_plan: null } const { bots, fetchImageBots } = useImageBots() @@ -33,7 +33,7 @@ export const ImageModelsPage: NextPageWithLayout = () => { bots.map((item) => { return ( @@ -1 +1,2 @@ +export { default as ImageModelsPage } from './image-models' export { default as ImageModelPage } from './image-model' @@ -1,136 +1,11 @@ .imagebox { - position: relative; - background-color: var(--air-color); - width: 100%; - @media screen and (max-width: 1000px) { display: none; } - - &__image { - position: absolute; - right: -530px; - bottom: -490px; - transform: rotate(-13deg); - border: 10px solid rgba(255, 255, 255, 0.3); - border-radius: 20px; - } - - &__logo { - position: absolute; - left: 35px; - top: 35px; - } } -.login { - display: grid; - grid-template-columns: 1fr 1fr; - min-height: 100dvh; - background-color: white; - overflow: hidden; - - @media screen and (max-width: 1000px) { - grid-template-columns: 1fr; - grid-auto-rows: max-content; - overflow: scroll; - } - - &__left { - margin: 20px 0px; - @media screen and (max-width: 1000px) { - height: max-content; - } - } - - &__or { - padding-top: 16px; - text-align: center; - color: #a4aab5; - } - - &__title { - font-weight: 700; - font-size: 26px; - text-align: center; - margin-bottom: 16px; - } - - &__form { - width: 320px; - height: 100%; - display: flex; - align-items: center; - margin: 0 auto; - @media screen and (max-width: 1000px) { - width: 90%; - } - } - - &__active { - width: 100%; - } - - &__logo { - display: none; - margin: 0 auto; - margin-bottom: 40px; - @media screen and (max-width: 1000px) { - display: block; - } - } -} - -html[data-theme='dark'] { - .login { - background-color: var(--new-ui-bg-app-color); - } -} - - -.form { - width: 100%; - &__inputs { - display: flex; - flex-direction: column; - gap: 14px; - margin-bottom: 10px; - } - - &__navigate { - padding-top: 10px; - text-align: center; - font-size: 16px; - } -} - -.input{ - &__pass{ - display: flex; - align-items: center; - } - &__label{ - display: flex; - align-items: center; - justify-content: space-between; +.form{ + @media screen and (max-width: 1000px) { width: 100%; - } -} - -.controls { - padding-top: 25px; - width: 100%; - - &__progress { - display: flex; - justify-content: center; - span{ - color: var(--air-color); - } } - - &__create { - width: 100%; - } -} - +} \ No newline at end of file @@ -1,128 +0,0 @@ -import { RegisterPage } from '#/views/register' -import '@testing-library/jest-dom' -import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' -import { jestRender } from '#/../jest/utils/render' -import { windowMock } from '#/../jest/utils/window-mock' -import fetchMock from 'jest-fetch-mock' -import Login from './login' -import { signIn } from 'next-auth/react' -import { useShowDataStore } from '#/shared/lib/hooks' -import { create } from 'zustand' -import { useRouter } from '#/../__mocks__/next/router' - -jest.mock('next-auth/react') - -jest.mock('zustand', () => { - return { - create: jest.fn(), - } -}) - -const showMessageMock = jest.fn() - -jest.mock('#/shared/lib/hooks', () => { - return { - useShowDataStore: jest.fn(() => { - return { - showMessage: showMessageMock, - } - }), - } -}) - -jest.mock('next/router') -jest.mock('@sentry/nextjs') - -fetchMock.enableMocks() -windowMock() - -describe('login-page', () => { - beforeEach(() => { - fetchMock.resetMocks() - }) - - it('renders in register', () => { - jestRender() - - const form = screen.getByTestId('register-email-form') - - expect(form).toBeInTheDocument() - }) - - it('submit by button click', async () => { - await act(async () => { - jestRender() - }) - - const submitButton = screen.getByTestId('submit-button') - const emailInput = screen.getByTestId('email-input') - const passwordInput = screen.getByTestId('password-input') - - ;(signIn as jest.Mock).mockResolvedValue({ - error: null, - status: 200, - ok: true, - url: '', - }) - - fireEvent.change(emailInput, { target: { value: 'aleksander.freelancer@gmail.com' } }) - fireEvent.change(passwordInput, { target: { value: 'geraldisrivii' } }) - - await act(async () => { - fireEvent.click(submitButton) - }) - - await waitFor(() => { - expect(signIn).toHaveBeenCalledWith('credentials', { - username: 'aleksander.freelancer@gmail.com', - password: 'geraldisrivii', - redirect: false, - }) - }) - - await waitFor(() => { - const { push } = useRouter() - expect(push).toHaveBeenCalledWith('/') - }) - }) - - it('submit by button click with some error (email in example)', async () => { - await act(async () => { - jestRender() - }) - ;(useShowDataStore as any as jest.Mock).mockImplementation(() => ({ - showMessage: showMessageMock, - })) - - const submitButton = screen.getByTestId('submit-button') - const emailInput = screen.getByTestId('email-input') - const passwordInput = screen.getByTestId('password-input') - - ;(signIn as jest.Mock).mockResolvedValue({ - error: 'email_not_correct', - status: 400, - ok: false, - url: '', - }) - - fireEvent.change(emailInput, { target: { value: 'aleksander.freelancer@gmail.com' } }) - fireEvent.change(passwordInput, { target: { value: 'geraldisrivii' } }) - - await act(async () => { - fireEvent.click(submitButton) - }) - - await waitFor(() => { - expect(signIn).toHaveBeenCalledWith('credentials', { - username: 'aleksander.freelancer@gmail.com', - password: 'geraldisrivii', - redirect: false, - }) - }) - - await waitFor(() => { - expect(showMessageMock).toHaveBeenCalledWith('Неверный email') - }) - }) -}) @@ -1,68 +1,222 @@ import * as React from 'react' -import { Link } from '@mui/material' +import { useEffect } from 'react' +import { useCookies } from 'react-cookie' +import { useForm } from 'react-hook-form' +import { SubmitErrorHandler } from 'react-hook-form/dist/types/form' +import { Box, Button, InputAdornment, Link, Stack, TextField, Typography } from '@mui/material' import CircularProgress from '@mui/material/CircularProgress' +import * as Sentry from '@sentry/nextjs' import Image from 'next/image' -import { c } from '#/shared/lib/helpers' -import { NextPageWithLayout } from '#/pages/_app' +import { useRouter } from 'next/router' +import { signIn } from 'next-auth/react' + import styles from './login.module.scss' -import OpenedEyeSvg from '#/assets/svg/opened-eye.svg?react' + import ClosedEyeSvg from '#/assets/svg/closed-eye.svg?react' -import { useEffect, useState } from 'react' +import OpenedEyeSvg from '#/assets/svg/opened-eye.svg?react' +import { useThemeStore } from '#/entities/theme/model/use-theme-store' +import { PasswordOptions } from '#/features/register-by-email/lib/constants' +import { IEmailForms } from '#/features/register-by-email/model/types' import { YandexAuthButton } from '#/features/yandex-auth-button' -import { useLoginCookies } from '#/features/login-cookies' -import { useLoginForm, useLoginValidate } from '#/features/login-form' -import { useLoginQueryErrors } from '#/features/login-query-errors' -import LogoSvg from '#/assets/svg/logo.svg?react' -import { CommonInput } from '#/shared/ui/common-input' -import { CommonButton } from '#/shared/ui/button' +import { NextPageWithLayout } from '#/pages/_app' +import { ERROR_MAPPING, ERRROR_YANDEX_TRANSLATE_MAPPING } from '#/pages/api/auth/constants' +import { emailOptions } from '#/shared' +import { getDeviceType } from '#/shared/lib/helpers' +import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' +import { InputStyleDark, InputStyleLight } from '#/shared/ui/input' const Login: NextPageWithLayout = () => { - const { setAllQueryToCookies } = useLoginCookies() + const device = getDeviceType() + + const { query, push } = useRouter() + + const [, setCookie] = useCookies() + + React.useEffect(() => { + Object.entries(query).forEach(([key, value]) => setCookie(key, value)) + }, []) + + const { showMessage } = useShowDataStore() - const { passwordOptions, emailOptions } = useLoginValidate() + const [loading, setLoading] = React.useState(false) - const { onMounted } = useLoginQueryErrors() + const [passwordShowed, showPassword] = React.useState(false) - const [passwordShowed, showPassword] = useState(false) + const desktop = device === 'desktop' - const { register, onSubmit, pending } = useLoginForm() + const { register, handleSubmit } = useForm() useEffect(() => { - setAllQueryToCookies() - onMounted() + const params = new URL(window.location.href).searchParams + + const error = params.get('error') + + if (!error || error === '') return + + const expectedError = ERRROR_YANDEX_TRANSLATE_MAPPING[error] + showMessage(expectedError ?? 'Не удалось выполнить вход, попробуйте позже') + if (!expectedError) Sentry.captureMessage(error) }, []) + async function onSubmit(data: any) { + setLoading(true) + + const resp = await signIn('credentials', { + username: data.email, + password: data.password, + redirect: false, + }) + if (resp && !resp.ok && resp.error && resp.error !== '') { + const expectedError = Object.keys(ERROR_MAPPING).reduce( + (prev, curr) => ({ ...prev, [ERROR_MAPPING[curr]]: curr }), + {} as Record + )[resp.error] + showMessage(expectedError ?? 'Не удалось выполнить вход, попробуйте позже') + if (!expectedError) Sentry.captureMessage(resp.error) + setLoading(false) + } else { + push('/') + } + } + + const checkError: SubmitErrorHandler = (data) => { + showMessage(Object.values(data)[0].message || 'Неверные данные') + } + + const handleKeyDown = (event: any) => { + if (event.key === 'Enter') { + handleSubmit(onSubmit)() + } + } + + const handleInputChangeTrim = (event: any) => { + event.target.value = event.target.value.trim() + } + + const theme = useThemeStore((state) => state.theme) + return ( <> -
      -
      - + {!desktop && ( + {''} -
      -
      -

      Вход

      - - -

      или email

      -
      - + + { + if (e.key === 'Enter') { + await handleSubmit(onSubmit, checkError) + } + }} + > + + + Вход + + + + или email + + + Email + + - - Пароль + + + + Пароль + + + + { > Забыли пароль? -
      - } - className={styles.input} - {...register('password', passwordOptions as any)} - data-testid='password-input' + + + + showPassword((x) => !x)} - > - {passwordShowed ? ( - - ) : ( - - )} - + fullWidth + InputProps={{ + endAdornment: ( + +
      showPassword((x) => !x)} + style={{ + cursor: 'pointer', + display: 'flex', + alignItems: 'center', + }} + > + {passwordShowed ? ( + + ) : ( + + )} +
      +
      + ), + }} + sx={ + theme === 'light' + ? { ...InputStyleLight } + : { ...InputStyleDark } } + {...register('password', { + ...PasswordOptions, + })} /> -
      - -
      - {pending ? ( -
      - -
      - ) : ( - + {!loading ? ( + + ) : ( + + + + )} + - Войти - - )} -
      -

      - - Зарегистрироватся - -

      - -
      -
      -
      - - dashboard -
      -
+ + Зарегистрироваться + + + + + + + + {desktop && ( + + {''} + {''} + + )} + ) } @@ -1,56 +0,0 @@ -import { NavigationBlock } from '#/features/navigation-blocks' - -export const mainPageBlocks: NavigationBlock[] = [ - { - title: 'Flux 1.1', - content: ( - - Современная нейросеть, способная анализировать данные, обрабатывать информацию и генерировать - уникальный контент для различных задач. - - ), - enabled: true, - cols: 2, - link: '/images/flux', - image: '/pages/main/flux', - }, - { - title: 'Чат-боты', - content: Получите доступ к последним версиям самых передовых текстовых моделей., - enabled: true, - cols: 1, - link: '/chat-bot', - image: '/pages/main/chat-bots', - }, - { - title: 'Stable Diffusion', - content: Превращайте текстовые описания в реалистичные или художественные изображения., - enabled: true, - cols: 1, - link: '/images/stablediffusion', - image: '/pages/main/lion', - }, - { - title: 'Создание видео', - content: Генерируйте и редактируйте видео с помощью передовых технологий ИИ., - enabled: false, - cols: 2, - image: '/pages/main/capibara', - }, - { - title: 'Копирайтинг', - content: Создавайте уникальные, качественные тексты для бизнеса, блогов и рекламы., - enabled: true, - cols: 2, - link: '/copywriting', - image: '/pages/main/copywriting', - }, - { - title: 'Улучшение фото', - content: Улучшайте качество, устраняйте шум и добавляйте детали с помощью ИИ., - enabled: true, - cols: 1, - link: '/images/upscaleai', - image: '/pages/main/woman', - }, -] @@ -1 +0,0 @@ -export * from './blocks' \ No newline at end of file @@ -1 +0,0 @@ -export * from './main' \ No newline at end of file @@ -1,16 +0,0 @@ -.grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); - gap: 30px; - grid-auto-rows: 400px; - padding-top: 72px; - - @media screen and (min-width: 1800px) { - grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); - } - - @media screen and (max-width: 768px) { - grid-template-columns: 1fr; - grid-auto-rows: 340px; - } -} @@ -1,19 +0,0 @@ -import { getDeviceType } from '#/shared/lib/helpers/get-type-device' -import React from 'react' -import styles from './main.module.scss' -import { NavigationMainPageBlock } from '#/features/navigation-blocks' -import { mainPageBlocks } from '../config' -import { NextPageWithLayout } from '#/pages/_app' - -interface MainPageProps {} - -export const MainPage: NextPageWithLayout = ({}: MainPageProps) => { - const device = getDeviceType() - return ( -
- {mainPageBlocks.map((item, index) => ( - - ))} -
- ) -} @@ -1,3 +0,0 @@ -export * from './ui' -export * from '../../features/navigation-blocks/types' -export * from './config' @@ -1,151 +0,0 @@ -.container { - width: 100%; - border-radius: 15px; - height: 100%; - position: absolute; - bottom: 0; - left: 0; - background-color: var(--new-ui-main-color); - opacity: 0; - z-index: -1; - transition: all 0.3s ease-in-out; - - &_active { - opacity: 1; - z-index: 100; - } -} - -.header { - width: 70%; - margin-bottom: 50px; - - @media screen and (max-width: 768px) { - width: 100%; - margin-bottom: 0px; - } -} - -@keyframes fadein { - 0% { - opacity: 0; - } - 50% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -// .blocked { -// display: flex; -// align-items: center; -// justify-content: center; -// background-color: white; -// border-radius: 100px; -// padding-right: 20px; -// padding: 8px 12px; -// width: max-content; - -// span { -// color: #ff2372; -// font-weight: 500; -// padding-left: 10px; -// font-size: 14px; -// width: max-content; -// } -// } - -.icon { -} - -.tags { - min-width: 100%; - display: flex; - gap: 8px; - align-items: center; - justify-content: flex-end; - - @media screen and (max-width: 768px) { - justify-content: flex-start; - } -} - -.tag { - display: flex; - align-items: center; - justify-content: center; - background-color: white; - border-radius: 100px; - width: 50px; - height: 50px; - box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.1); - transition: width 0.3s ease-in-out; - - @media screen and (max-width: 768px) { - height: 40px; - width: 40px; - } - - &__icon { - color: var(--air-color); - } - - &:hover { - padding: 12px; - width: 200px; - - .tag__icon { - animation: fadein 0.6s ease-in-out; - } - - .tag__text { - opacity: 1; - position: static; - animation: fadein 0.6s ease-in-out; - display: block; - } - } - - &__text { - position: absolute; - color: var(--air-color); - font-weight: 500; - padding-left: 10px; - font-size: 14px; - opacity: 0; - display: none; - min-width: max-content !important; - } -} - -.blocked { - height: 100%; - display: flex; - align-items: center; - justify-content: center; - background-color: #c32528; - padding: 20px; - gap: 10px; - position: absolute; - - left: 0; - - width: 100%; - border-radius: 15px; - top: 0; - - @media screen and (max-width: 768px) { - top: unset; - // bottom: -22px; - z-index: 1; - border-radius: 15px; - } - - &__text { - color: white !important; - font-size: 16px; - font-weight: 600; - } -} @@ -1,265 +0,0 @@ -import { useEffect } from 'react' -import { Box, Stack } from '@mui/material' -import Head from 'next/head' -import { useRouter } from 'next/router' - -import styles from './image-model.module.scss' - -import BlockedSvg from '#/assets/svg/blocked.svg?react' -import { useImageBot } from '#/entities/model-entity/model/use-image-bot' -import { useImageBotCreateImage } from '#/features/image-bot-create-image' -import { useImagesBotFilters } from '#/features/image-bot-filters' -import { useImageBotPagination, useImageBotPaginationOld } from '#/features/image-bot-pagination' -import { NextPageWithLayout } from '#/pages/_app' -import { Loader } from '#/shared' -import { c, getDeviceType, getOs } from '#/shared/lib/helpers' -import { useThemeAndDevice } from '#/shared/lib/hooks' -import { SvgIcon } from '#/shared/ui/svg' -import { ImageMessagesList, ImageMessagesListOld } from '#/widgets/messages' -import { ModelInput } from '#/features/model-input' -import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' -import { CommonTitle } from '#/shared/ui/title' -import { ImageModelOptions } from '#/widgets/image-model-options' -import { useImageBotInput } from '#/features/image-bot-input' -import { POPUP_IMAGE_BOT_PARAMS, getPopupById } from '#/shared/ui/popup' -import { useEventSource } from '#/shared/lib/event-source' -import { useImageMessagesEvents } from '#/entities/message' - -const ImageModelPage: NextPageWithLayout = () => { - const deviceType = getDeviceType() - const deviceOs = getOs() - const { desktop } = useThemeAndDevice(deviceType, deviceOs) - - const { - refScrollMobile, - refScrollDesktop, - mobileScrollContainer, - onObserverMounted, - fetchMessages, - loading, - offset, - messages, - count, - loaded, - setLoaded, - } = useImageBotPaginationOld(deviceType) - - const { createImage } = useImageBotCreateImage(deviceType, mobileScrollContainer, offset) - - const { onSendMessage, file, setFile, valueInput, setValueInput, inputTypes, requiredTypes } = - useImageBotInput(createImage) - - const { botParams, fetchBotParams } = useImageBot() - - async function onFetch() { - await Promise.all([fetchBotParams()]) - } - - const popup = getPopupById(POPUP_IMAGE_BOT_PARAMS) - - useEffect(() => { - onFetch() - onObserverMounted() - }, [botParams?.slug]) - - const { closeEvent } = useEventSource() - - const { makeEvent } = useImageMessagesEvents() - - useEffect(() => { - if (!loaded) return - closeEvent('images') - makeEvent('images') - - return () => { - closeEvent('images') - setLoaded(false) - } - }, [loaded]) - - return ( - <> - - {botParams ? botParams?.title : 'Загрузка...'} - -
- - {botParams && - botParams.tags.map((tag, index) => ( -
- - - {tag.title} -
- ))} -
- } - /> - - - - - {desktop ? ( - <> - - popup.toogleState()} - inputTypes={inputTypes} - blocked={botParams ? !botParams.enabled : false} - sendMessage={(message) => onSendMessage(message, requiredTypes)} - /> - - {botParams && !botParams.enabled && ( -
- - - Модель недоступна - -
- )} -
- - - - - ) : ( - -
-
- -
-
-
- - - - - - {botParams && ( - popup.toogleState()} - inputTypes={inputTypes} - blocked={botParams ? !botParams.enabled : false} - sendMessage={(message) => - onSendMessage(message, requiredTypes) - } - /> - )} - {botParams && !botParams.enabled && ( -
- - - Модель недоступна - -
- )} -
-
-
- )} -
- {desktop && } -
- - ) -} - -export default ImageModelPage @@ -1 +0,0 @@ -export { default as ImageModelPage } from './image-model' @@ -1 +0,0 @@ -export * from './ui' @@ -1,88 +1,11 @@ .imagebox { - position: relative; - background-color: var(--air-color); - width: 100%; - - @media screen and (max-width: 1000px) { - display: none; - } - - &__image { - position: absolute; - right: -530px; - bottom: -490px; - transform: rotate(-13deg); - border: 10px solid rgba(255, 255, 255, 0.3); - border-radius: 20px; - } - - &__logo { - position: absolute; - left: 35px; - top: 35px; - } -} - -.register { - display: grid; - grid-template-columns: 1fr 1fr; - min-height: 100dvh; - background-color: white; - overflow: hidden; - @media screen and (max-width: 1000px) { - grid-template-columns: 1fr; - grid-auto-rows: max-content; - overflow: scroll; - } - - &__left { - margin: 20px 0px; - @media screen and (max-width: 1000px) { - height: max-content; - } - } - - &__or { - padding-top: 16px; - text-align: center; - color: #a4aab5; - } - - &__title { - font-weight: 700; - font-size: 26px; - text-align: center; - margin-bottom: 16px; - } - - &__form { - width: 320px; - height: 100%; - display: flex; - align-items: center; - margin: 0 auto; - @media screen and (max-width: 1000px) { - width: 90%; - } - } - - &__active { - width: 100%; - } - - &__logo { display: none; - margin: 0 auto; - margin-bottom: 40px; - @media screen and (max-width: 1000px) { - display: block; - } } } -html[data-theme='dark'] { - .register { - background-color: var(--new-ui-bg-app-color); +.form{ + @media screen and (max-width: 1000px) { + width: 100%; } -} +} \ No newline at end of file @@ -17,6 +17,10 @@ import { getDeviceType } from '#/shared/lib/helpers' import { RegisterEmailForm } from '#/features/register-by-email' const Register: NextPageWithLayout = () => { + const device = getDeviceType() + + const desktop = device === 'desktop' + const [success, setSuccess] = useState(false) const [isReferral, setIsReferral] = useState(true) @@ -25,7 +29,6 @@ const Register: NextPageWithLayout = () => { const { getUser } = useUserStore() const user = getUser() - const desktop = getDeviceType() === 'desktop' const { push } = useRouter() @@ -35,16 +38,26 @@ const Register: NextPageWithLayout = () => { } return ( -
-
+ + {!desktop && ( Logo -
+ )} { {isReferral && ( <> -

или email

+ + или email + )} - setSuccess(true)} /> + )}
@@ -144,7 +159,7 @@ const Register: NextPageWithLayout = () => { /> )} -
+ ) } @@ -1 +0,0 @@ -export * from './upscale-page' \ No newline at end of file @@ -1,129 +0,0 @@ -.main { - margin-right: 60px; - position: relative; - height: 100%; -} - -.lottie { - &__wrapper { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - display: flex; - align-items: center; - justify-content: center; - } -} - -.loading { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - object-fit: contain; - - > canvas{ - object-fit: contain; - width: 40% !important; - height: 40% !important; - } -} - -.controls { - position: absolute; - bottom: 20px; - left: 50%; - transform: translateX(-50%); - display: flex; - z-index: 100; - align-items: center; - gap: 10px; - - &__settings { - height: 50px; - width: 50px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 13px; - border: 1px solid var(--new-ui-gray-color); - } -} - -.general { - display: flex; - align-items: center; - justify-content: center; - padding-top: 60px; - - &__accent { - color: var(--air-color); - } - - &__text { - display: flex; - flex-wrap: wrap; - gap: 0.7ch; - align-items: center; - justify-content: center; - text-align: center; - color: white; - - font-size: 18px; - font-weight: 600; - margin-bottom: 20px; - } - - &__desc { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - display: flex; - z-index: 1; - align-items: center; - flex-direction: column; - } - - &__settings { - display: flex; - gap: 4px; - align-items: center; - color: var(--air-color); - } - - &__imgbox { - width: 900px; - position: relative; - border-radius: 20px; - overflow: hidden; - - &::after { - content: ''; - display: block; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - - background-color: rgba(52, 52, 52, 0.2); - - [data-theme='dark'] & { - background-color: rgba(0, 0, 0, 0.2); - } - } - } - - &__img { - width: 100%; - height: auto; - } -} @@ -1,103 +0,0 @@ -import { NextPageWithLayout } from '#/pages/_app' -import React, { useEffect, useRef, useState } from 'react' - -import styles from './upscale-page.module.scss' -import { DotLottieReact } from '@lottiefiles/dotlottie-react' - -import { c, Loader } from '#/shared' -import Image from 'next/image' -import { UpscaleEmpty } from '#/widgets/upscale-empty' -import SettingsSvg from '#/assets/svg/settings.svg?react' -import ArrowDropDownSvg from '#/assets/svg/arrow-dropdown.svg?react' -import { CommonButton } from '#/shared/ui/button' -import StarsSvg from '#/assets/svg/stars.svg?react' -import { UpscaleSettingsPopup } from '#/features/upscale-settings' -import { getPopupById, POPUP_UPSCALE_SETTINGS } from '#/shared/ui/popup' -import AnimationBgSvg from '#/assets/svg/animation-bg.svg?react' - -interface UpscalePageProps {} - -export const UpscalePage: NextPageWithLayout = ({}: UpscalePageProps) => { - const [images, setImages] = useState([]) - - const [pending, setPending] = useState(false) - - const popup = getPopupById(POPUP_UPSCALE_SETTINGS) - - function onUpscalePhoto() { - const file = images[0] - - setPending(true) - - // ждем бек - } - - useEffect(() => { - console.log(images) - }, [images]) - - return ( -
- {!images.length && } - - {images.length > 0 && ( -
-
- initial - {!pending ? ( -
-
- Выберите нужные -
- - параметры -
- улучшения -
- и нажмите - Улучшить фото -
- -
- ) : ( -
- - -
- )} -
- -
- - {pending ? ( - - ) : ( - - )} - {pending ? 'Улучшение фото...' : 'Улучшить фото'} - -
-
- )} - - -
- ) -} @@ -1 +0,0 @@ -export * from './ui' \ No newline at end of file @@ -1,268 +0,0 @@ -// import * as React from 'react' -// import { useEffect, useState } from 'react' -// import { Box, Button, TextField, Typography } from '@mui/material' -// import axios from 'axios' -// import { Dayjs } from 'dayjs' -// import { useSession } from 'next-auth/react' - -// import { ResponseGetPersons } from '#/features/invite-person-in-business' -// import { useAppSelector } from '#/app/store/store' -// import styles from '#/app/styles/business.module.scss' -// import { InputStyleDark, InputStyleLight } from '#/shared' -// import { API_URL } from '#/shared/lib/constants' -// import { DateInput } from '#/shared/ui/date-input/date-input' -// import { Info } from '#/widgets/business-info' -// import { getInfo, InfoBusiness } from '#/widgets/business-info/api/get-info' -// import { ModelsList } from '#/widgets/business-models' -// import styles2 from '#/widgets/business-models/ui/models-list/models-list.module.scss' -// import { PersonsList } from '#/widgets/business-persons' -// import { getPersons } from '#/widgets/business-persons/api/get-persons' -// import { BusinessGroups } from '#/widgets/business-persons/ui/persons-list/business-group' -// import { IpList } from '#/widgets/business-persons/ui/persons-list/ip-list' -// import { LogList } from '#/widgets/business-persons/ui/persons-list/log-list' -// import { SecurityList } from '#/widgets/business-persons/ui/persons-list/security-list' -// import ArrowUpOrDown from '#/widgets/top-bar-model/ui/arrow-up-or-down' -// import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' - -// type ListType = 'personal' | 'security' - -// export default function BusinessHost() { -// const [securityList, setSecurityList] = useState([]) -// const [personsList, setPersonsList] = useState([]) -// const [info, setInfo] = useState() -// const [showPersons, setShowPersons] = useState(true) -// const [fromDate, setFromDate] = useState('') -// const [mailing, setMailing] = useState() -// const [toDate, setToDate] = useState('') -// const { data } = useSession() -// const { message, isOpened } = useShowDataStore() - -// useEffect(() => { -// getPersons(data?.access, true).then((res) => setSecurityList(res ? res?.reverse() : null)) -// getPersons(data?.access).then((res) => setPersonsList(res ? res?.reverse() : null)) -// getInfo(data?.access).then((res) => { -// setInfo(res) -// if (res) setMailing(res?.token_cap_enabled) -// }) -// }, [data?.access]) - -// const addList = (newUser: ResponseGetPersons, list: ListType) => { -// if (list === 'personal') { -// if (personsList?.length !== 0) { -// setPersonsList((prev) => [...prev!, newUser]) -// } else { -// setPersonsList([newUser]) -// } -// } -// if (list === 'security') { -// if (securityList?.length !== 0) { -// setSecurityList((prev) => [...prev!, newUser]) -// } else { -// setSecurityList([newUser]) -// } -// } -// } - -// const download = () => { -// axios.get( -// API_URL + -// `/auth/business-host/download-expenses?type=employees&from_date=${fromDate}&to_date=${toDate}`, -// { -// responseType: 'arraybuffer', -// headers: { Authorization: `Bearer ${data?.access}` }, -// } -// ).then((res) => { -// const file = new Blob([res.data], { -// type: 'application/ms-excel;charset=utf-8', -// }) -// const link = document.createElement('a') -// link.href = window.URL.createObjectURL(file) -// link.download = 'Expenses.xlsx' -// document.body.appendChild(link) -// link.click() -// document.body.removeChild(link) -// }) -// } - -// useEffect(() => { -// axios.put( -// API_URL + '/auth/business-host', -// { token_cap_enabled: mailing }, -// { headers: { Authorization: `Bearer ${data?.access}` } } -// ) -// }, [mailing]) - -// return ( -// -// -// -// {info?.is_ip_whitelist_enabled ? : <>} -// -// -// -// -// -// -// Затраты -// setShowPersons((prev) => !prev)} -// className={styles2.arrow} -// /> -// -// -// {showPersons && ( -// -// -// -// -// -// )} -// -// -// -// -// ) -// } - -// const MailingBlock = ({ -// info, -// mailing, -// }: { -// info: InfoBusiness | null | undefined -// mailing: boolean | undefined -// }) => { -// const [showPersons, setShowPersons] = useState(true) -// const [newMail, setNewMail] = useState('') -// const theme = useAppSelector((state) => state.theme.theme) -// const [allMails, setAllMails] = useState() -// const [isMailing, setIsMailing] = useState(false) -// const { data } = useSession() - -// useEffect(() => { -// if (info) { -// setAllMails(info?.token_cap_emails) -// setIsMailing(info?.token_cap_enabled) -// } -// }, [info]) - -// useEffect(() => { -// if (allMails) { -// req(allMails).then((res) => { -// setNewMail('') -// }) -// } -// }, [allMails]) - -// const addMailingUser = async () => { -// if (newMail !== '') { -// setAllMails((emails) => [...(emails ?? []), newMail]) -// } -// } - -// const req = async (mailingArr: string[]) => { -// await axios.put( -// API_URL + '/auth/business-host', -// { token_cap_emails: mailingArr }, -// { headers: { Authorization: `Bearer ${data?.access}` } } -// ) -// } - -// return ( -// <> -// {mailing && ( -// -// -// -// -// Уведомления о низком балансе -// -// setShowPersons((prev) => !prev)} -// className={styles2.arrow} -// /> -// -// -// {showPersons && ( -// <> -// -// -// setNewMail(e.target.value)} -// fullWidth -// sx={ -// theme === 'light' -// ? { ...InputStyleLight } -// : { ...InputStyleDark } -// } -// /> -// - -// -// -// -// {allMails?.map((el) => ( -//
-//

{el}

-// { -// setAllMails( -// allMails.filter( -// (item) => item !== el -// ) -// ) -// }} -// > -// -// -// -//
-// ))} -//
-// -// )} -//
-// )} -// -// ) -// } @@ -1 +0,0 @@ -export { default as BusinessHost } from './ui/business-host-optimized' @@ -27,19 +27,11 @@ export const Info = ({ const { getUser } = useUserStore() const [data, setData] = useState(null) - const user = getUser() - const { account_type: type } = user || { account_type: 'regular' } + const { account_type: type } = getUser() const balance = useBalanceStore((state) => state.balance) - const { getUserBalance } = useBalanceStore() const [value, setValue] = useState(false) const { data: session } = useSession() - useEffect(() => { - if (session?.access) { - getUserBalance(session.access) - } - }, [session?.access, getUserBalance]) - useEffect(() => { if (security) { getInfo(session?.access).then((res) => { @@ -83,10 +75,7 @@ export const Info = ({ : 'Участник'} {type !== 'business_security' ? ( - + Режим валидации по IP :{' '} {data?.is_ip_whitelist_enabled ? 'включен' : 'выключен'} @@ -96,10 +85,7 @@ export const Info = ({ <> )} {value !== undefined && type !== 'business_security' ? ( - + Уведомления о низком балансе :{' '} br { - display: none; - } - - @media screen and (max-width: 1200px) { - font-size: 36px; - text-align: center; - - > br { - display: block; - } - } - - @media screen and (max-width: 800px) { - font-size: 28px; - } - - - span { - color: var(--air-color); - } - } - - &__group { - display: flex; - flex-direction: column; - gap: 15px; - transition: all 0.5s ease-in-out; - } - - &__marquee { - height: calc(100dvh - 20px - 20px - 40px - 27px); - min-width: 280px; - } -} - -.item { - width: 100%; - height: 280px; - position: relative; - - &::after { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba($color: #000000, $alpha: 0.7); - border-radius: 18px; - } - - &__skeleton { - width: 100%; - height: 100%; - border-radius: 10px; - background-color: rgba($color: #a4aab5, $alpha: 0.1); - animation: skeleton 1s infinite ease-in-out alternate; - position: absolute; - top: 0; - left: 0; - } - - &__img { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 20px; - } -} @@ -1,38 +0,0 @@ -import Image from 'next/image' -import React, { useState } from 'react' - -import styles from './image-list.module.scss' - -interface ValuesListProps { - values: string[] -} - -export const ValuesList = ({ values }: ValuesListProps) => { - const [imageLoadStates, setImageLoadStates] = useState( - Array(values.length).fill(false) - ) - return ( - <> - {values.map((image, index) => ( -
- { - setImageLoadStates((prev) => { - const newState = [...prev] - newState[index] = true - return newState - }) - }} - width={200} - height={200} - loading='lazy' - className={styles.item__img} - src={image} - alt={`image-${index}`} - /> - {!imageLoadStates[index] &&
} -
- ))} - - ) -} @@ -1,105 +0,0 @@ -@keyframes skeleton { - 0% { - background-color: rgba($color: #a4aab5, $alpha: 0.1); - } - 100% { - background-color: rgba($color: #a4aab5, $alpha: 0.3); - } -} - -.empty { - display: flex; - gap: 15px; - - &__center { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - - z-index: 1; - - display: flex; - flex-direction: column; - align-items: center; - - @media screen and (max-width: 1200px) { - top: 40%; - } - } - - &__title { - margin-bottom: 20px; - - font-size: 44px; - - > br { - display: none; - } - - @media screen and (max-width: 1200px) { - font-size: 36px; - text-align: center; - - > br { - display: block; - } - } - - @media screen and (max-width: 800px) { - font-size: 28px; - } - - - span { - color: var(--air-color); - } - } - - &__group { - display: flex; - flex-direction: column; - gap: 15px; - transition: all 0.5s ease-in-out; - } - - &__marquee { - height: calc(100dvh - 20px - 20px - 40px - 27px); - min-width: 280px; - } -} - -.item { - width: 100%; - height: 280px; - position: relative; - - &::after { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba($color: #000000, $alpha: 0.7); - border-radius: 18px; - } - - &__skeleton { - width: 100%; - height: 100%; - border-radius: 10px; - background-color: rgba($color: #a4aab5, $alpha: 0.1); - animation: skeleton 1s infinite ease-in-out alternate; - position: absolute; - top: 0; - left: 0; - } - - &__img { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 20px; - } -} @@ -1,34 +0,0 @@ -import React, { useEffect, useState } from 'react' -import styles from './images-empty.module.scss' -import * as exampleImages from '../config/example-images' -import Image from 'next/image' -import { CommonMarque } from '#/shared/ui/marque' -import ArrowLongSvg from '#/assets/svg/arrow-long.svg?react' -import { c } from '#/shared' -import { ValuesList } from './image-list' - -interface ImagesEmptyProps {} - -export const ImagesEmpty = ({}: ImagesEmptyProps) => { - return ( -
-
-

- Шедевры
в один клик -

- -
- {Object.values(exampleImages).map((images, index) => { - return ( - - - - ) - })} -
- ) -} @@ -1,2 +0,0 @@ -export * from './images-empty' -export * from './image-list' \ No newline at end of file @@ -1,2 +0,0 @@ -export * from './config' -export * from './ui' \ No newline at end of file @@ -7,7 +7,6 @@ border-radius: 15px; width: 30%; margin-left: 20px; - max-height: calc(100vh - 230px); @media screen and (max-width: 1000px) { width: 100%; @@ -42,10 +41,8 @@ flex-direction: column; transition: max-height 0.25s; max-height: 100dvh; - padding-bottom: 10px; &_close { max-height: 0px; - padding-bottom: 0px; overflow: hidden; } } @@ -1,3 +1,4 @@ +import BotParamsMap from '#/features/bot-params/ui/bot-params-map' import { c } from '#/shared' import styles from './image-model-options.module.scss' import ArrowDownSvg from '#/assets/svg/arrow-down.svg?react' @@ -1 +0,0 @@ -export * from './use-image-models-popup' \ No newline at end of file @@ -1,13 +0,0 @@ -import { useImagesBots } from '#/entities/model-entity' -import { useMemo, useState } from 'react' - -export function useImageModelsPopup() { - const { bots, fetchBots, setBots } = useImagesBots() - - - return { - bots, - setBots, - fetchBots, - } -} @@ -1 +0,0 @@ -export type CostZones = 30 | 60 | 90 @@ -1 +0,0 @@ -export * from './cost' \ No newline at end of file @@ -1,74 +0,0 @@ -.container { - position: relative; - - @media (max-width: 768px) { - position: static; - } -} -.wrapper { - background: rgba($color: #000000, $alpha: 0.4); - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 104; - visibility: hidden; - opacity: 0; - transition: all 0.3s ease-in-out; - - &_open { - visibility: visible; - opacity: 1; - } -} -.select { - padding: 5px 12px; - background: rgba(#8280ff, 0.1); - border-radius: 10px; - display: flex; - align-items: center; - width: max-content; - gap: 10px; - cursor: pointer; - - &__arrow { - padding-top: 5px; - @media (max-width: 768px) { - width: 15px; - height: 15px; - } - } - - &__title { - color: var(--air-color); - } -} - -.popup { - background: var(--new-ui-main-color); - border-radius: 15px; - width: max-content; - position: absolute; - z-index: 105; - transform: translateY(20px); - visibility: hidden; - opacity: 0; - transition: all 0.3s ease-in-out; - border: 1px solid #40404e4b; - max-height: 70vh; - overflow-y: scroll; - top: calc(100% + 10px); - - @media (max-width: 768px) { - left: 0; - right: 0; - width: fit-content; - } - - &_open { - visibility: visible; - opacity: 1; - transform: translateY(0); - } -} @@ -1,41 +0,0 @@ -import { Typography } from '@mui/material' -import React, { useEffect } from 'react' -import styles from './image-models-select.module.scss' -import { c } from '#/shared/lib/helpers' -import { useImageModelsPopup } from '../model' -import { ImagePopupModel } from './image-popup-model' -import { useRouter } from 'next/router' -import ArrowDownSvg from '#/assets/svg/arrow-down.svg?react' -import { getPopupById, POPUP_IMAGE_MODEL } from '#/shared/ui/popup' -import { ImageModelsPopup } from './image-models.popup' -import { Model } from '#/entities/model-entity' - -export interface ImageModelsPopupProps { - model: Model | null - className?: string -} - -export const ImageModelsSelect = ({ model, className }: ImageModelsPopupProps) => { - const popup = getPopupById(POPUP_IMAGE_MODEL) - - return ( - <> -
-
popup.toogleState()} className={c(styles.select)}> -

- {model ? model.title : 'Загрузка...'} -

- -
- - -
- - ) -} @@ -1,25 +0,0 @@ - -.popup { - display: flex; - flex-direction: column; - width: max-content; - - max-height: 60dvh; - overflow-y: scroll; - overflow-x: hidden; - border-radius: 15px; - - @media screen and (max-width: 600px) { - width: 100vw; - max-height: 70dvh; - } - - > div:first-child { - border-radius: 15px 15px 0px 0px !important; - } -} - -.template{ - padding: 0px; - border-radius: 15px; -} \ No newline at end of file @@ -1,47 +0,0 @@ -import React, { useEffect } from 'react' -import { useImageModelsPopup } from '../model' -import styles from './image-models.popup.module.scss' -import { c } from '#/shared' -import { ImagePopupModel } from './image-popup-model' -import { getPopupById, POPUP_IMAGE_MODEL, PopupTemplate } from '#/shared/ui/popup' -import { useRouter } from 'next/router' -import { Model } from '#/entities/model-entity' - -interface ImageModelsPopupProps { - model: Model | null -} - -export const ImageModelsPopup = ({ model, ...props }: ImageModelsPopupProps) => { - const { fetchBots, bots } = useImageModelsPopup() - - const popup = getPopupById(POPUP_IMAGE_MODEL) - - const { push } = useRouter() - - async function onFetch() { - await fetchBots() - } - - useEffect(() => { - onFetch() - }, []) - - return ( - -
- {bots.map((item, index) => ( - { - popup.setState(false) - push(`/images/${slug}`) - }} - /> - ))} -
-
- ) -} @@ -1,99 +0,0 @@ -.model { - // font-family: Inter; - padding: 15px 20px; - cursor: pointer; - display: flex; - align-items: center; - gap: 22px; - justify-content: space-between; - max-width: 500px; - transition: background-color 0.3s ease; - position: relative; - - &:hover { - background-color: rgba($color: #a4aab5, $alpha: 0.1); - } - - @media (max-width: 768px) { - // max-width: calc(100% - 100px) !important; - width: 100%; - // max-width: unset; - } - - &_blocked { - &:hover { - background-color: transparent; - } - } - - &__blocked { - background-color: rgba($color: #000000, $alpha: 0.7); - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - padding-right: 10px; - span { - color: white; - font-weight: 600; - padding-left: 8px; - } - } - - &__locked { - background-color: rgba($color: #000000, $alpha: 0.7); - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - padding-right: 10px; - span { - color: white; - font-weight: 600; - padding-left: 8px; - } - } - &__title { - font-weight: 600; - font-size: 18px; - margin-bottom: 4px; - } - - &__description { - font-size: 14px; - color: #a4aab5; - margin-bottom: 7px; - } - - &__badges { - display: flex; - gap: 10px; - } - - &__badge { - padding: 4px 6px; - font-size: 13px; - display: flex; - align-items: center; - gap: 2px; - background-color: rgba($color: #a4aab5, $alpha: 0.1); - color: white; - font-weight: 500; - border-radius: 5px; - } - - &__time { - gap: 6px; - color: var(--new-ui-gray-color); - } - &__cost { - } -} @@ -1,3 +1,4 @@ +import { ShortModel } from '#/entities/model-entity' import React, { useMemo } from 'react' import styles from './image-popup-model.module.scss' @@ -6,9 +7,6 @@ import SuccessRoundedSvg from '#/assets/svg/success-rounded.svg?react' import ClockSvg from '#/assets/svg/clock.svg?react' import LightningSvg from '#/assets/svg/lightning.svg?react' import LockSvg from '#/assets/svg/lock.svg?react' -import BlockedSvg from '#/assets/svg/blocked.svg?react' -import { ShortModel } from '#/entities/model-entity' -import { useUserStore } from '#/entities/user-account' interface ImagePopupModelProps extends ShortModel { active: boolean @@ -36,41 +34,54 @@ export const ImagePopupModel = ({ averageTokenCost, setActive, }: ImagePopupModelProps) => { - const { getUser } = useUserStore() - const user = getUser() + // жесткий костыль))) - временный + // const formatedTime = useMemo(() => { + // if (!actual_stat) return null - const accessed_models = useMemo( - () => (user.payment_plan ? user.payment_plan.plan.accessed_models : []), - [user] - ) + // const seconds = Number(actual_stat.generation_time.split(':')[2]) + + // const range = Math.ceil(seconds - seconds / 3) + + // return `${range} - ${seconds} сек.` + // }, [actual_stat]) + + // const costZone = useMemo(() => { + // if (!actual_stat) return null - const isAccess = useMemo(() => accessed_models && accessed_models.includes(slug), [accessed_models]) + // const remainder = Number(actual_stat.tokens_cost) - averageTokenCost + + // return costZoneColors.find((item) => item.remainder > remainder) + // }, [actual_stat, averageTokenCost]) return ( -
{ - if (!enabled || !isAccess) return - setActive(slug) - }} - className={c(styles.model, !enabled && styles.model_blocked)} - > - {!enabled ? ( -
- - Модель недоступна +
enabled && setActive(slug)} className={styles.model}> + {!enabled && ( +
+ + Недоступно в текущем тарифе
- ) : ( - !isAccess && ( -
- - Недоступно в текущем тарифе -
- ) )}

{title}

{description}

+ + {/* {actual_stat && ( +
+
+ + {formatedTime} +
+ +
+ + {Number(actual_stat.tokens_cost)} +
+
+ )} */}
{active && } @@ -1,3 +0,0 @@ -export * from './image-models-select' -export * from './image-popup-model' -export * from './image-models.popup' \ No newline at end of file @@ -1,4 +0,0 @@ -export * from './types' -export * from './ui' -export * from './model' -// export * from './api' \ No newline at end of file @@ -1,2 +0,0 @@ -export * from './styles.categories' -export * from './styles.static' \ No newline at end of file @@ -1,11 +0,0 @@ -export const categories: string[] = [ - 'Ретро', - 'Фотореализм', - 'Винтаж', - 'Мультипликация', - 'Аниме', - 'Ностальгия', - 'Классика', - 'Реалистичное искусство', - 'Анимация', -] @@ -1,28 +0,0 @@ -import { ImageStyle } from "#/entities/image-style"; - -export const imageStyles: ImageStyle[] = [ - { - label: 'Стиль 1', - uid: 'style_1', - category: 'Ретро', - image: 'https://images.unsplash.com/photo-1511367461989-f85a21fda167?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80', - }, - { - label: 'Стиль 2', - uid: 'style_2', - category: 'Мультипликация', - image: 'https://images.unsplash.com/photo-1511367461989-f85a21fda167?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80', - }, - { - label: 'Стиль 3', - uid: 'style_3', - category: 'Фотореализм', - image: 'https://images.unsplash.com/photo-1511367461989-f85a21fda167?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80', - }, - { - label: 'Стиль 4', - uid: 'style_4', - category: 'Винтаж', - image: 'https://images.unsplash.com/photo-1511367461989-f85a21fda167?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80', - }, -] @@ -1,3 +0,0 @@ -export * from './styles.favorites' -export * from './styles.chosen' -export * from './styles.chosen-categories' \ No newline at end of file @@ -1,28 +0,0 @@ -import { useState } from 'react' -import { imageStyles } from '../config' -import { ImageStyle } from '#/entities/image-style' - -export function useChosenCategories() { - const [chosenCategories, setChosenCategories] = useState([]) - - function addCategory(category: string) { - setChosenCategories([...chosenCategories, category]) - } - - function removeCategory(category: string) { - setChosenCategories(chosenCategories.filter((f) => f !== category)) - } - - function toogleCategory(category: string) { - const isCategory = chosenCategories.some((f) => f === category) - isCategory ? removeCategory(category) : addCategory(category) - } - - return { - chosenCategories, - setChosenCategories, - addCategory, - removeCategory, - toogleCategory, - } -} @@ -1,18 +0,0 @@ -import { ImageStyle } from '#/entities/image-style' -import { create } from 'zustand' - -export interface ChosenStyleStore { - style: ImageStyle | null - setStyle: (style: ImageStyle) => void -} - -export const useChosenStyle = create((set, get) => { - function setStyle(style: ImageStyle) { - set({ ...get(), style }) - } - - return { - style: null, - setStyle, - } -}) @@ -1,28 +0,0 @@ -import { useState } from 'react' -import { imageStyles } from '../config' -import { ImageStyle } from '#/entities/image-style' - -export function useStylesFavorites() { - const [favorites, setFavorites] = useState([...imageStyles.slice(0, 2)]) - - function addFavorite(favorite: ImageStyle) { - setFavorites([...favorites, favorite]) - } - - function removeFavorite(uid: string) { - setFavorites(favorites.filter((f) => f.uid !== uid)) - } - - function toogleFavorite(favorite: ImageStyle) { - const isFavorite = favorites.some((f) => f.uid === favorite.uid) - isFavorite ? removeFavorite(favorite.uid) : addFavorite(favorite) - } - - return { - favorites, - setFavorites, - addFavorite, - removeFavorite, - toogleFavorite, - } -} @@ -1 +0,0 @@ -export * from './style.plate' \ No newline at end of file @@ -1,95 +0,0 @@ -'use client' -import { ScopedImageStyle } from '#/entities/image-style' -import { getModalById, PLATE_IMAGE_STYLES, PlateTemplate } from '#/features/modals' -import { c } from '#/shared' -import { CommonBagde } from '#/shared/ui/badge' -import { CommonInput } from '#/shared/ui/common-input' -import { useMemo, useState } from 'react' -import { categories, imageStyles } from '../config' -import { useChosenCategories, useStylesFavorites } from '../model' -import styles from './styles.plate.module.scss' -import { TransitionGroup } from 'react-transition-group' -import { CSSTransition } from 'react-transition-group' -export const PlateImageStyles = () => { - const modal = getModalById(PLATE_IMAGE_STYLES) - - const callback = modal.getStoreProperty('callback') - - const { chosenCategories, toogleCategory } = useChosenCategories() - - const { favorites, toogleFavorite } = useStylesFavorites() - - const [inputValue, setInputValue] = useState('') - - const filteredStyles = useMemo(() => { - return imageStyles.filter((style) => { - return ( - (chosenCategories.length === 0 ? true : chosenCategories.includes(style.category)) && - (inputValue.length > 0 ? (style.label && style.label.toLowerCase().includes(inputValue.toLowerCase())) : true) - ) - }) - }, [chosenCategories, inputValue]) - - return ( - -
-

- Выберите стиль для генерации -

- - setInputValue(e.target.value)} - placeholder='Поиск по стилям...' - variant='primary' - /> - -
- {categories.map((category) => ( - toogleCategory(category)} - className={c( - styles.modal__badge, - chosenCategories.includes(category) && styles.modal__badge_active - )} - variant='outline' - > - {category} - - ))} -
-
0 && styles.like_opened)}> -

Избранное

- - {favorites.map((favorite) => ( - - callback && callback(favorite)} - inFavorites={favorites.some((f) => f.uid === favorite.uid)} - onCnageFavorite={() => toogleFavorite(favorite)} - key={favorite.uid} - {...favorite} - /> - - ))} - -
- - {filteredStyles.map((style) => ( - - callback && callback(style)} - inFavorites={favorites.some((f) => f.uid === style.uid)} - onCnageFavorite={() => toogleFavorite(style)} - {...style} - /> - - ))} - -
-
- ) -} @@ -1,103 +0,0 @@ -.modal { - min-width: 400px; - min-height: 300px; - width: 100dvw; - max-width: 1100px; - max-height: 90dvh; - padding-top: 60px; - overflow-y: scroll; - display: flex; - flex-direction: column; - align-items: center; - transition: all 0.5s ease-in-out; - - @media screen and (max-width: 1000px) { - width: 100%; - min-width: unset; - } - - &__title { - margin-bottom: 50px; - @media screen and (max-width: 1000px) { - text-align: center; - } - - - span { - color: var(--air-color); - } - } - - &__input { - min-width: 346px; - // margin-bottom: 30px; - text-align: center; - - &::placeholder { - text-align: center; - } - } - - &__badges { - display: flex; - max-width: 600px; - align-items: center; - justify-content: center; - flex-wrap: wrap; - gap: 5px; - margin-bottom: 74px; - } - - &__badge { - cursor: pointer; - - &_active { - border-color: var(--air-color); - color: var(--air-color); - } - } -} - -.like { - width: 100%; - display: flex; - flex-direction: column; - transform: translateY(100%) scale(0); - visibility: hidden; - height: 0px; - opacity: 0; - transition: all 0.5s ease-in-out; - - &_opened { - transform: translateY(0) scale(1); - visibility: visible; - height: 100%; - opacity: 1; - } - - &__title { - font-size: 24px; - margin-bottom: 15px; - } - - &__favorites { - display: flex; - gap: 10px; - margin-bottom: 34px; - - transition: all 0.5 ease-in-out; - } - - &__favorite { - width: 127px; - height: 127px; - } -} - -.items { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); - grid-auto-rows: 260px; - width: 100%; - gap: 10px; -} @@ -1,3 +0,0 @@ -export * from './ui' -export * from './model' -export * from './config' \ No newline at end of file @@ -14,12 +14,7 @@ overflow-y: auto; overflow-x: hidden; gap: 8px; - margin-bottom: 30px; - - @media screen and (max-width: 1000px) { - flex-direction: column; - align-items: center; - } + margin-bottom: 30px; &__wrapper { display: flex; @@ -42,6 +37,8 @@ align-items: center; gap: 8px; list-style: none; + overflow-x: auto; + overflow-y: hidden; } &__link { @@ -50,6 +47,8 @@ color: var(--new-ui-gray-color); border-radius: 13px; cursor: pointer; + width: max-content; + text-wrap: nowrap; &_active { background: var(--new-ui-main-color); @@ -23,7 +23,6 @@ export function AdminLayout({ children, ...props }: LayoutProps) {
    {adminLinks.map((item, index) => (
  • push(item.link)} className={c( styles.items__link, @@ -1,6 +1,8 @@ import React, { useEffect, useRef, useState } from 'react' import { Box } from '@mui/material' import Head from 'next/head' +import { useRouter } from 'next/router' +import { getSession, signOut, useSession } from 'next-auth/react' import { useTheme } from '#/entities/theme' import InfoBar from '#/app/layout/ui/info-bar' @@ -21,15 +23,14 @@ import { ChatBotOptionsPopup } from '#/entities/chat/ui/chat-bot-options-popup' import { ImageBotOptionsPopup } from '#/entities/model-entity' import { useAuthSession } from '#/features/auth/model/use-auth-session' import { useUser } from '#/entities/user-account' -import { MessageFullscreenModal } from '#/features/message-fullscreen-modal/ui' -import { ErrorMessageFullscreen } from '#/entities/error-modal/ui/error-message-fullscreen' -import { PlateImageStyles } from '#/widgets/images-style' +import { useBalance } from '#/entities/balance' export const Layout: React.FC = ({ children, titlePage, height, device = getDeviceType() }) => { const { fetchUser, loaded, loading } = useUser() const [requestDelay, setRequestDelay] = useState(false) + const { fetchUserBalance, pending } = useBalance() const desktop = device === 'desktop' @@ -42,6 +43,7 @@ export const Layout: React.FC = ({ children, titlePage, height, dev useEffect(() => { setTimeout(() => setRequestDelay(true), 5000) fetchUser() + fetchUserBalance() }, []) if (!loaded) { @@ -110,13 +112,9 @@ export const Layout: React.FC = ({ children, titlePage, height, dev )} - - - - @@ -1,7 +1,15 @@ import React, { memo, useEffect, useMemo, useState } from 'react' import MenuIcon from '@mui/icons-material/Menu' -import { Avatar, List } from '@mui/material' - +import { + Avatar, + Button, + Divider, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, +} from '@mui/material' import Menu from '@mui/material/Menu' import Typography from '@mui/material/Typography' import { Box, Stack } from '@mui/system' @@ -65,12 +73,7 @@ export const MainMenuMobile = memo(() => { return ( - + setAnchorElNavigate(event.currentTarget)}> { style={{ marginTop: '10px', marginLeft: '20px' }} href={'https://air.fail/requisites'} > - + Реквизиты - Error + Error push('/account')} sx={{ width: 29, height: 29 }} @@ -215,38 +208,26 @@ type MenuItemProps = { theme: string title: string - link: string | null - icon: string | React.ReactNode + link?: string | null + icon: string activeList?: string[] } export function MenuItem(props: MenuItemProps) { const isActive = useMemo( - () => - props.link === props.pathname || - props.activeList?.some((el) => props.pathname.includes(el)), + () => props.link === props.pathname || props.activeList?.some((el) => props.pathname.includes(el)), [props.pathname] ) return ( - {typeof props.icon === 'string' ? ( - {''} - ) : ( -
    - {props.icon} -
    - )} + {''} {props.title}
    {/* { await Router.push('/register') } - const [anchorElNotification, setAnchorElNotification] = React.useState( - null - ) + const [anchorElNotification, setAnchorElNotification] = React.useState(null) const openNotification = Boolean(anchorElNotification) @@ -82,12 +83,7 @@ export const MainMenu: React.FC = memo(() => { return ( - + {status !== 'authenticated' && } { open={openNotification} anchorEl={anchorElNotification} /> - @@ -275,8 +261,7 @@ export const MainMenu: React.FC = memo(() => { - + + +
    +

    ГЕНЕРАЦИИ

    + +
    + {images.map((message, index) => ( + { + message.file && modal.setState(true) + }} + key={message.uid} + {...message} + /> ))} - +
    ) @@ -5,9 +5,4 @@ export * from '../../../entities/message/ui/bot-message' export * from '../../preview-view/ui/preview-view' export * from '../../../entities/message/ui/user-message' export * from './is-next-day' -export * from './chat-messages-list' -export * from './chat-messages-list' -export * from './image-messages-list' -export * from './answer-wrap' -export * from './is-next-day' -export * from './image-messages-list-old' +export * from '../../../entities/message/ui/image-icons' @@ -20,7 +20,6 @@ import { Loader, c } from '#/shared' import styles from './is-next-day.module.scss' import { CommonTooltipPosition } from '#/shared/ui/tooltip' import { CommonScrollbarRef } from '#/shared/ui/scrollbar' -import { MessageFullscreenModal } from '#/features/message-fullscreen-modal/ui' interface IsNextDayProps { message: Message @@ -29,8 +28,6 @@ interface IsNextDayProps { translate: number setCurrentSrc: (current: string) => void scrollBarRef: RefObject - tooltipPosition?: CommonTooltipPosition - } export const IsNextDay = forwardRef( @@ -2,7 +2,6 @@ import { NavigationSearchModelLink } from './types' import { API_URL } from '#/shared/lib/constants' import axios from 'axios' - export const getModelChatLinks = async (token: string) => { return await axios.get(API_URL + '/api/chats/links', { headers: { Authorization: `Bearer ${token}` }, @@ -1,14 +1,9 @@ import { NavigationSearchLink } from '../api/types' export const staticLinks: NavigationSearchLink[] = [ - { - label: 'Главная', - url: '/', - category: 'Навигация', - }, { label: 'Дашборд', - url: '/dashboard', + url: '/', category: 'Навигация', }, { @@ -1,5 +1,5 @@ -import React from 'react' import { Box, Typography } from '@mui/material' +import React from 'react' import styles from './key-for-search.module.scss' @@ -7,12 +7,9 @@ import { staticLinks } from '../config' import { InputStyleDark, InputStyleLight, useConcat } from '#/shared' import { useThemeStore } from '#/entities/theme/model/use-theme-store' import { useRouter } from 'next/router' - - import { NavigationSearchLink } from '../api/types' import { useNavigationSearchMediaLinks } from '../model/use-media-links' - interface SearchProps { device: string } @@ -108,10 +105,6 @@ export const Search = ({ device }: SearchProps) => { } : { ...InputStyleDark, - fieldset: { - border: '1px solid rgba(64, 64, 78, 0.12)', - borderRadius: '15px', - }, } } className='bg-color-block' @@ -1,2 +1,2 @@ export * from './ui' -export * from './config' +export * from './config' \ No newline at end of file @@ -14,9 +14,7 @@ import Router, { useRouter } from 'next/router' import { useSession } from 'next-auth/react' import { CheckBoxAgreeWithRules, Loader, Select } from '#/shared' -import { makePrivateRequest } from '#/shared/api' import { accountApi } from '#/shared/api/account-endpoints' -import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' interface PaymentHistory { uid: string @@ -68,44 +66,22 @@ export const Payment: React.FC = ({ device, changeClose }) const [messages, setMessages] = useState(null) - const { showMessage } = useShowDataStore() - - const fetchPaymentsHistory = makePrivateRequest(async () => { - const result = await accountApi.getPaymentsHistory(data?.access || '') - - if (!result) return showMessage('Ошибка загрузки истории платежей', 'error') - - setMessages(result) - }) - - const fetchPaymentsPlans = makePrivateRequest(async () => { - const result = await accountApi.getPaymentsPlans(data?.access || '') - - if (!result) return showMessage('Ошибка загрузки тарифов', 'error') - - setOffers(result) - }) - - const pay = makePrivateRequest(async (uid: string) => { - const urlForPay = await accountApi.payProduct(data?.access || '', uid) - - if (!urlForPay) return showMessage('Ошибка создания платежа', 'error') - - await Router.push(urlForPay) - }) - useEffect(() => { if (data?.access) { - fetchPaymentsHistory() + accountApi.getPaymentsHistory(data.access).then((res) => setMessages(res)) } }, [data?.access]) useEffect(() => { - if (data?.access) { - fetchPaymentsPlans() - } + if (data?.access) accountApi.getPaymentsPlans(data?.access).then((res) => setOffers(res)) }, [data?.access]) + const pay = async (uid: string) => { + const urlForPay = await accountApi.payProduct(data!.access, uid) + + urlForPay ? await Router.push(urlForPay) : null + } + return ( @@ -1,22 +1,19 @@ import React from 'react' -import { IOffer } from '#/widgets/payment/ui/payment' import styles from './offer.module.scss' import { CommonBagde } from '#/shared/ui/badge' import LightningSvg from '#/assets/svg/lightning.svg?react' import { CommonButton } from '#/shared/ui/button' import { c, commaSeparated } from '#/shared/lib/helpers' +import { IOffer } from '../model/payment' interface IOfferProps extends IOffer { - pickOffer: (uid: string) => void - selectedOffer: string - device: 'desktop' | 'mobile' pay: (uid: string) => void } -const Offer: React.FC = ({ pickOffer, uid, tokens_per_plan, price, points, pay }) => { +const Offer: React.FC = ({ uid, tokens_per_plan, price, points, pay }) => { return ( -
    pickOffer(uid)}> +
    @@ -37,7 +34,11 @@ const Offer: React.FC = ({ pickOffer, uid, tokens_per_plan, price,

    {commaSeparated(parseInt(price) ?? 0)}₽

    - pay(uid)} variant={'primary-outline'}> + pay(uid)} + variant={'primary-outline'} + > Оплатить
    @@ -8,7 +8,7 @@ flex-direction: column; } .main { - width: 100%; + width: 69%; @media (max-width: 768px) { width: 100%; @@ -1 +1 @@ -export { Payment } from './ui/payment' +export { Payment } from './model/payment' @@ -1 +0,0 @@ -export * from './side-menu' \ No newline at end of file @@ -1,8 +0,0 @@ -import React from "react" - -export interface SideMenuItem { - title: string - link: string - icon: string | React.ReactNode - activeList: string[] -} @@ -20,17 +20,9 @@ import { useThemeStore } from '#/entities/theme/model/use-theme-store' import { useUserSettingsContext } from '#/entities/user-account' import { ERROR_REPORT, getModalById } from '#/features/modals' import { Device } from '#/shared/lib/types/entities' -import { SideMenuItem } from '../types' -import InterfaceSvg from '#/assets/svg/interface.svg?react' -export const menuListTop: SideMenuItem[] = [ - { - title: 'Главная', - link: '/', - icon: , - activeList: [], - }, - { title: 'Дашборд', link: '/dashboard', icon: '/svg/side-menu/market', activeList: [] }, +export const menuListTop = [ + { title: 'Дашборд', link: '/', icon: '/svg/side-menu/market', activeList: [] }, { title: 'Оплата', link: '/account/subscribe', @@ -48,22 +40,10 @@ export const menuListMiddle = [ }, { title: 'Изображения', - link: '/images/flux', + link: '/images', icon: '/svg/side-menu/image', activeList: ['images'], }, - { - title: 'Апскейл', - link: '/upscale', - icon: '/svg/side-menu/image', - activeList: ['upscale'], - }, - { - title: 'Олд мод изображений', - link: '/deprecated', - icon: '/svg/side-menu/image', - activeList: ['deprecated'], - }, // { title: 'Копирайтинг', link: '/copywriting/my', icon: '/svg/side-menu/copyrating', activeList: ['copywriting'] }, // { title: 'Видео', link: '/video', icon: '/svg/side-menu/video', activeList: [] }, // { title: 'Аудио', link: '/audio', icon: '/svg/side-menu/audio', activeList: [] }, @@ -102,22 +82,20 @@ const closedMixin = (theme: Theme): CSSObject => ({ }, }) -const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })( - ({ theme, open }) => ({ - width: drawerWidth, - flexShrink: 0, - whiteSpace: 'nowrap', - boxSizing: 'border-box', - ...(open && { - ...openedMixin(theme), - '& .MuiDrawer-paper': openedMixin(theme), - }), - ...(!open && { - ...closedMixin(theme), - '& .MuiDrawer-paper': closedMixin(theme), - }), - }) -) +const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })(({ theme, open }) => ({ + width: drawerWidth, + flexShrink: 0, + whiteSpace: 'nowrap', + boxSizing: 'border-box', + ...(open && { + ...openedMixin(theme), + '& .MuiDrawer-paper': openedMixin(theme), + }), + ...(!open && { + ...closedMixin(theme), + '& .MuiDrawer-paper': closedMixin(theme), + }), +})) export const SideMenu = ({}) => { const { status } = useSession() @@ -283,15 +261,13 @@ type MenuItemProps = { title: string link: string | null - icon: string | React.ReactNode + icon: string activeList?: string[] } export function MenuItem(props: MenuItemProps) { const isActive = useMemo( - () => - props.link === props.pathname || - props.activeList?.some((el) => props.pathname.includes(el)), + () => props.link === props.pathname || props.activeList?.some((el) => props.pathname.includes(el)), [props.pathname] ) const theme = useThemeStore((state) => state.theme) @@ -313,8 +289,7 @@ export function MenuItem(props: MenuItemProps) { '& .MuiTooltip-arrow': { color: theme === 'light' ? '#E8E8FA' : '#4B4B4B', }, - boxShadow: - '0px 0px 4px rgba(0, 0, 0, 0.04), 0px 4px 32px rgba(0, 0, 0, 0.16)', + boxShadow: '0px 0px 4px rgba(0, 0, 0, 0.04), 0px 4px 32px rgba(0, 0, 0, 0.16)', }, }, }} @@ -342,9 +317,7 @@ export function MenuItem(props: MenuItemProps) { @@ -357,11 +330,7 @@ export function MenuItem(props: MenuItemProps) { > {typeof props.icon === 'string' ? ( {''} = memo(({ device, token, favorit const desktop = device === 'desktop' - const { status, data } = useSession() + const { status } = useSession() const { pathname } = useRouter() const balance = useBalanceStore((state) => state.balance) - const { getUserBalance } = useBalanceStore() - - // Инициализация баланса при загрузке компонента - useEffect(() => { - if (data?.access) { - getUserBalance(data.access) - } - }, [data?.access, getUserBalance]) const closeMenuModel = () => setAnchorElModel(null) const openMenuModel = (event: React.MouseEvent) => { @@ -1,2 +0,0 @@ - -export * from './upscale-empty' \ No newline at end of file @@ -1,67 +0,0 @@ -.imgbox { - margin-top: 24px; - position: relative; - border-radius: 20px; - overflow: hidden; - width: max-content; -} -.empty { - display: flex; - flex-direction: column; - align-items: center; -} -.resultbox { - position: absolute !important; - top: 0; - left: 0; - // overflow: hidden; - bottom: 0; - height: 100%; - display: flex; -} -.title { - font-size: 48px; - padding: 40px 0px; - text-align: center; - @media screen and (max-width: 768px) { - font-size: 32px; - } - span { - color: var(--air-color); - } -} -.arrow { - margin-bottom: 20px; -} -.resized { - display: flex; - height: 100%; - - img { - height: 100%; - width: calc(100% - 2px); - object-fit: cover; - object-position: left; - } -} - -.slider { - height: 100%; - width: 3px; - background-color: white; - position: relative; - - &__track { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 30px; - height: 30px; - border-radius: 100%; - display: flex; - align-items: center; - justify-content: center; - background-color: white; - } -} @@ -1,54 +0,0 @@ -import React from 'react' - -import styles from './upscale-empty.module.scss' -import { c } from '#/shared' -import Image from 'next/image' -import { Resizable } from 're-resizable' -import ArrowsSvg from '#/assets/svg/arrows.svg?react' -import ArrowSvg from '#/assets/svg/arrow.svg?react' -import { ImageArea } from '#/features/image-area' - -interface UpscaleEmptyProps { - images: File[] - setImages: React.Dispatch> -} - -export const UpscaleEmpty = ({ images, setImages }: UpscaleEmptyProps) => { - return ( -
    -
    - initial - -
    - result -
    -
    - -
    -
    -
    -
    -
    - -

    - Теперь без мыльных
    изображений -

    - - - - -
    - ) -} @@ -1 +0,0 @@ -export * from './ui' \ No newline at end of file @@ -0,0 +1,32 @@ +{ + "plugins": ["prettier", "simple-import-sort"], + "extends": ["next/core-web-vitals"], + "rules": { + "no-console": "warn", + "quotes": ["warn", "single"], + "indent": "off", + "jsx-quotes": ["warn", "prefer-single"], + "react/display-name": "off", + "simple-import-sort/imports": [ + "warn", + { + "groups": [ + // Packages `react` related packages come first. + ["^react", "^@?\\w"], + // Internal packages. + ["^(@|components)(/.*|$)"], + // Side effect imports. + ["^\\u0000"], + // Parent imports. Put `..` last. + ["^\\.\\.(?!/?$)", "^\\.\\./?$"], + // Other relative imports. Put same-folder imports and `.` last. + ["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"], + // Style imports. + ["^.+\\.?(css)$"] + ] + } + ], + "simple-import-sort/exports": "off", + "react-hooks/rules-of-hooks": "off" + } +} @@ -10,8 +10,6 @@ default: build_staging: stage: Build image: docker:cli - services: - - docker:dind script: - export RELEASE=$(echo -n $(date '+%D %X') | md5sum | awk '{print $1}') - echo -e "\nNEXT_PUBLIC_RELEASE=$RELEASE" >> $ENV @@ -12,20 +12,14 @@ services: labels: - traefik.enable=true - traefik.docker.network=infrastructure - - - traefik.http.routers.frontend-web-http.rule=Host(`$DOMAIN`) - - traefik.http.routers.frontend-web-http.entrypoints=web - - traefik.http.routers.frontend-web-http.tls=false - - traefik.http.routers.frontend-web-http.service=frontend - - traefik.http.routers.frontend-web-http.middlewares=sts-header@file,https-redirect@file - - - traefik.http.routers.frontend-web-https.rule=Host(`$DOMAIN`) - - traefik.http.routers.frontend-web-https.entrypoints=websecure - - traefik.http.routers.frontend-web-https.tls=true - - traefik.http.routers.frontend-web-https.tls.certresolver=defaultresolver - - traefik.http.routers.frontend-web-https.service=frontend - + - traefik.http.routers.frontend.rule=Host(`$DOMAIN`) + - traefik.http.routers.frontend.entrypoints=web,websecure + - traefik.http.routers.frontend.tls=true + - traefik.http.routers.frontend.tls.certresolver=defaultresolver + - traefik.http.routers.frontend.service=frontend - traefik.http.services.frontend.loadbalancer.server.port=3000 + - traefik.http.middlewares.frontend.redirectscheme.scheme=https + - traefik.http.middlewares.frontend.redirectscheme.permanent=true networks: infrastructure: @@ -1,6 +1,5 @@ /** @type {import('next').NextConfig} */ const { i18n } = require('./next-i18next.config') -const path = require('path') const nextConfig = { i18n, @@ -10,11 +9,6 @@ const nextConfig = { layers: true, } - config.resolve.alias = { - ...config.resolve.alias, - '#': path.join(__dirname, 'src'), - } - const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.('.svg')) config.module.rules.push( @@ -9,11 +9,11 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@dqbd/tiktoken": "^1.0.21", + "@babel/eslint-parser": "7.23.3", + "@dqbd/tiktoken": "^1.0.7", "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", "@fontsource/roboto": "^4.5.8", - "@lottiefiles/dotlottie-react": "^0.13.5", "@mui/icons-material": "^5.11.11", "@mui/material": "^5.11.12", "@mui/styled-engine-sc": "^5.11.11", @@ -40,12 +40,13 @@ "cross-env": "^7.0.3", "dayjs": "^1.11.8", "draft-js": "^0.11.7", - "draft-js-import-html": "^1.4.1", - "draftjs-to-html": "^0.9.1", + "eslint": "^8.7.0", + "eslint-config-next": "13.2.4", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-simple-import-sort": "^10.0.0", "event-source-polyfill": "^1.0.31", "husky": "^8.0.0", "i18next": "^23.4.1", - "intro.js": "^8.3.2", "intro.js-react": "^1.0.0", "lint-staged": "^13.2.2", "lodash.debounce": "^4.0.8", @@ -53,10 +54,8 @@ "next-auth": "^4.24.11", "next-i18next": "^14.0.0", "prettier": "^2.8.8", - "re-resizable": "^6.11.2", "react": "18.2.0", "react-chartjs-2": "^5.2.0", - "react-color": "^2.19.3", "react-cookie": "^4.1.1", "react-dom": "18.2.0", "react-draft-wysiwyg": "^1.15.0", @@ -78,23 +77,19 @@ "zustand": "^5.0.3" }, "devDependencies": { - "@eslint/js": "^9.31.0", "@svgr/webpack": "^8.1.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", - "@types/draftjs-to-html": "^0.8.4", "@types/intro.js": "^5.1.1", "@types/jest": "^29.5.14", "@types/lodash": "^4.14.195", - "@types/react-color": "^3.0.13", "@types/react-draft-wysiwyg": "^1.13.8", - "@types/react-lottie": "^1.2.10", "@types/react-syntax-highlighter": "^15.5.7", "cross-fetch": "^4.1.0", + "eslint-config-prettier": "^8.8.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "jest-fetch-mock": "^3.0.3", "lint-staged": "^13.2.2", "prettier": "^2.8.8", "ts-node": "^10.9.2", @@ -104,6 +99,14 @@ "node": ">=12.0.0" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@adobe/css-tools": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.2.tgz", @@ -176,6 +179,23 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/eslint-parser": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.23.3.tgz", + "integrity": "sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw==", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, "node_modules/@babel/generator": { "version": "7.27.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", @@ -2001,10 +2021,19 @@ } }, "node_modules/@dqbd/tiktoken": { - "version": "1.0.21", - "resolved": "https://registry.npmjs.org/@dqbd/tiktoken/-/tiktoken-1.0.21.tgz", - "integrity": "sha512-grBxRSY9+/iBM205EWjbMm5ySeXQrhJyXWMP38VJd+pO2DRGraDAbi4n8J8T9M4XY1M/FHgonMcmu3J+KjcX0Q==", - "license": "MIT" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@dqbd/tiktoken/-/tiktoken-1.0.7.tgz", + "integrity": "sha512-bhR5k5W+8GLzysjk8zTMVygQZsgvf7W1F0IlL4ZQ5ugjo5rCyiwGM5d8DYriXspytfu98tv59niang3/T+FoDw==" + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", @@ -2149,17 +2178,92 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, - "node_modules/@eslint/js": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", - "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", - "dev": true, - "license": "MIT", + "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==", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=10" }, "funding": { - "url": "https://eslint.org/donate" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", + "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@floating-ui/core": { @@ -2201,15 +2305,36 @@ "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz", "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA==" }, - "node_modules/@icons/material": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", - "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==", - "license": "MIT", - "peerDependencies": { - "react": "*" + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==" + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz", @@ -2232,6 +2357,28 @@ "@img/sharp-libvips-darwin-arm64": "1.1.0" } }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz", + "integrity": "sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, "node_modules/@img/sharp-libvips-darwin-arm64": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", @@ -2248,106 +2395,423 @@ "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config": { + "node_modules/@img/sharp-libvips-darwin-x64": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config/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" - }, - "engines": { - "node": ">=8" + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config/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" - }, - "engines": { - "node": ">=8" + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config/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" - }, - "engines": { - "node": ">=6" - }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/libvips" } }, - "node_modules/@istanbuljs/load-nyc-config/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", + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz", + "integrity": "sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz", + "integrity": "sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz", + "integrity": "sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz", + "integrity": "sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz", + "integrity": "sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz", + "integrity": "sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz", + "integrity": "sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz", + "integrity": "sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz", + "integrity": "sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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" }, @@ -2819,6 +3283,17 @@ "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==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -2831,32 +3306,14 @@ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@kurkle/color": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", - "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" - }, - "node_modules/@lottiefiles/dotlottie-react": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/@lottiefiles/dotlottie-react/-/dotlottie-react-0.13.5.tgz", - "integrity": "sha512-4U5okwjRqDPkjB572hfZtLXJ/LGfCo6vDwUB2KIPEUoSgqbIlw+UrbnaqVp3GS+dRvhMD27F2JObpHpYRlpF0Q==", - "license": "MIT", - "dependencies": { - "@lottiefiles/dotlottie-web": "0.44.0" - }, - "peerDependencies": { - "react": "^17 || ^18 || ^19" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@lottiefiles/dotlottie-web": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@lottiefiles/dotlottie-web/-/dotlottie-web-0.44.0.tgz", - "integrity": "sha512-IUWKVciDJI/BMWDWnh7j0Ngd0N8q9ySRAwm84aDqIE07qpmdZ7x1rkIpBaU1yHSNqNYHeh1Rxsl+LC3CY4f0KA==", - "license": "MIT" + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" }, "node_modules/@mui/base": { "version": "5.0.0-beta.24", @@ -3207,6 +3664,33 @@ "resolved": "https://registry.npmjs.org/@next/env/-/env-13.2.4.tgz", "integrity": "sha512-+Mq3TtpkeeKFZanPturjcXt+KHfKYnLlX6jMLyCrmpq6OOs4i1GqBOAauSkii9QeKCMTYzGppar21JU57b/GEA==" }, + "node_modules/@next/eslint-plugin-next": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.2.4.tgz", + "integrity": "sha512-ck1lI+7r1mMJpqLNa3LJ5pxCfOB1lfJncKmRJeJxcJqcngaFwylreLP7da6Rrjr6u2gVRTfmnkSkjc80IiQCwQ==", + "dependencies": { + "glob": "7.1.7" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@next/swc-android-arm-eabi": { "version": "13.2.4", "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.2.4.tgz", @@ -3402,6 +3886,46 @@ "node": ">= 10" } }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "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==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@opentelemetry/api": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", @@ -4057,128 +4581,367 @@ } } }, - "node_modules/@reduxjs/toolkit": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", - "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", - "dependencies": { - "immer": "^9.0.21", - "redux": "^4.2.1", - "redux-thunk": "^2.4.2", - "reselect": "^4.1.8" - }, - "peerDependencies": { - "react": "^16.9.0 || ^17.0.0 || ^18", - "react-redux": "^7.2.1 || ^8.0.2" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-redux": { - "optional": true - } - } + "node_modules/@reduxjs/toolkit": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz", + "integrity": "sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==", + "dependencies": { + "immer": "^9.0.21", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.8" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "28.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz", + "integrity": "sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", + "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", + "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", + "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", + "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", + "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", + "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", + "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", + "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", + "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", + "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", + "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz", - "integrity": "sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==", + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", + "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.2.0", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=16.0.0 || 14 >= 14.17" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@rollup/plugin-commonjs/node_modules/fdir": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", + "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", + "cpu": [ + "riscv64" + ], "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", + "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", + "cpu": [ + "s390x" + ], "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", - "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", + "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", + "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", + "cpu": [ + "x64" + ], "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@rollup/rollup-darwin-arm64": { + "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", - "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", + "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "darwin" + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", + "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", + "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" ] }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz", + "integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==" + }, "node_modules/@sentry-internal/browser-utils": { "version": "9.12.0", "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.12.0.tgz", @@ -4270,58 +5033,160 @@ "unplugin": "1.0.1" }, "engines": { - "node": ">= 14" + "node": ">= 14" + } + }, + "node_modules/@sentry/bundler-plugin-core/node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sentry/cli": { + "version": "2.42.2", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.42.2.tgz", + "integrity": "sha512-spb7S/RUumCGyiSTg8DlrCX4bivCNmU/A1hcfkwuciTFGu8l5CDc2I6jJWWZw8/0enDGxuj5XujgXvU5tr4bxg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.7", + "progress": "^2.0.3", + "proxy-from-env": "^1.1.0", + "which": "^2.0.2" + }, + "bin": { + "sentry-cli": "bin/sentry-cli" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@sentry/cli-darwin": "2.42.2", + "@sentry/cli-linux-arm": "2.42.2", + "@sentry/cli-linux-arm64": "2.42.2", + "@sentry/cli-linux-i686": "2.42.2", + "@sentry/cli-linux-x64": "2.42.2", + "@sentry/cli-win32-i686": "2.42.2", + "@sentry/cli-win32-x64": "2.42.2" + } + }, + "node_modules/@sentry/cli-darwin": { + "version": "2.42.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.42.2.tgz", + "integrity": "sha512-GtJSuxER7Vrp1IpxdUyRZzcckzMnb4N5KTW7sbTwUiwqARRo+wxS+gczYrS8tdgtmXs5XYhzhs+t4d52ITHMIg==", + "license": "BSD-3-Clause", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-arm": { + "version": "2.42.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.42.2.tgz", + "integrity": "sha512-7udCw+YL9lwq+9eL3WLspvnuG+k5Icg92YE7zsteTzWLwgPVzaxeZD2f8hwhsu+wmL+jNqbpCRmktPteh3i2mg==", + "cpu": [ + "arm" + ], + "license": "BSD-3-Clause", + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-arm64": { + "version": "2.42.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.42.2.tgz", + "integrity": "sha512-BOxzI7sgEU5Dhq3o4SblFXdE9zScpz6EXc5Zwr1UDZvzgXZGosUtKVc7d1LmkrHP8Q2o18HcDWtF3WvJRb5Zpw==", + "cpu": [ + "arm64" + ], + "license": "BSD-3-Clause", + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@sentry/cli-linux-i686": { + "version": "2.42.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.42.2.tgz", + "integrity": "sha512-Sw/dQp5ZPvKnq3/y7wIJyxTUJYPGoTX/YeMbDs8BzDlu9to2LWV3K3r7hE7W1Lpbaw4tSquUHiQjP5QHCOS7aQ==", + "cpu": [ + "x86", + "ia32" + ], + "license": "BSD-3-Clause", + "optional": true, + "os": [ + "linux", + "freebsd" + ], + "engines": { + "node": ">=10" } }, - "node_modules/@sentry/bundler-plugin-core/node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, + "node_modules/@sentry/cli-linux-x64": { + "version": "2.42.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.42.2.tgz", + "integrity": "sha512-mU4zUspAal6TIwlNLBV5oq6yYqiENnCWSxtSQVzWs0Jyq97wtqGNG9U+QrnwjJZ+ta/hvye9fvL2X25D/RxHQw==", + "cpu": [ + "x64" + ], + "license": "BSD-3-Clause", + "optional": true, + "os": [ + "linux", + "freebsd" + ], "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/@sentry/cli": { + "node_modules/@sentry/cli-win32-i686": { "version": "2.42.2", - "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.42.2.tgz", - "integrity": "sha512-spb7S/RUumCGyiSTg8DlrCX4bivCNmU/A1hcfkwuciTFGu8l5CDc2I6jJWWZw8/0enDGxuj5XujgXvU5tr4bxg==", - "hasInstallScript": true, + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.42.2.tgz", + "integrity": "sha512-iHvFHPGqgJMNqXJoQpqttfsv2GI3cGodeTq4aoVLU/BT3+hXzbV0x1VpvvEhncJkDgDicJpFLM8sEPHb3b8abw==", + "cpu": [ + "x86", + "ia32" + ], "license": "BSD-3-Clause", - "dependencies": { - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.7", - "progress": "^2.0.3", - "proxy-from-env": "^1.1.0", - "which": "^2.0.2" - }, - "bin": { - "sentry-cli": "bin/sentry-cli" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@sentry/cli-darwin": "2.42.2", - "@sentry/cli-linux-arm": "2.42.2", - "@sentry/cli-linux-arm64": "2.42.2", - "@sentry/cli-linux-i686": "2.42.2", - "@sentry/cli-linux-x64": "2.42.2", - "@sentry/cli-win32-i686": "2.42.2", - "@sentry/cli-win32-x64": "2.42.2" + "node": ">=10" } }, - "node_modules/@sentry/cli-darwin": { + "node_modules/@sentry/cli-win32-x64": { "version": "2.42.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.42.2.tgz", - "integrity": "sha512-GtJSuxER7Vrp1IpxdUyRZzcckzMnb4N5KTW7sbTwUiwqARRo+wxS+gczYrS8tdgtmXs5XYhzhs+t4d52ITHMIg==", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.42.2.tgz", + "integrity": "sha512-vPPGHjYoaGmfrU7xhfFxG7qlTBacroz5NdT+0FmDn6692D8IvpNXl1K+eV3Kag44ipJBBeR8g1HRJyx/F/9ACw==", + "cpu": [ + "x64" + ], "license": "BSD-3-Clause", "optional": true, "os": [ - "darwin" + "win32" ], "engines": { "node": ">=10" @@ -4954,7 +5819,6 @@ "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", @@ -4974,7 +5838,6 @@ "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" @@ -4987,7 +5850,6 @@ "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", @@ -5002,7 +5864,6 @@ "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, "license": "MIT" }, "node_modules/@testing-library/jest-dom": { @@ -5163,7 +6024,6 @@ "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, "license": "MIT" }, "node_modules/@types/babel__core": { @@ -5252,14 +6112,26 @@ "node": ">=0.8.0" } }, - "node_modules/@types/draftjs-to-html": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/@types/draftjs-to-html/-/draftjs-to-html-0.8.4.tgz", - "integrity": "sha512-5FZcjFoJL57N/IttLCTCNI0krX+181oCl5hf76u3TqPkqBAphHrJAO9ReYesx9138kcObaYmpnWC2Yrqxoqd2Q==", - "dev": true, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "license": "MIT", + "peer": true, "dependencies": { - "@types/draft-js": "*" + "@types/eslint": "*", + "@types/estree": "*" } }, "node_modules/@types/estree": { @@ -5385,6 +6257,18 @@ "parse5": "^7.0.0" } }, + "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==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, "node_modules/@types/lodash": { "version": "4.14.202", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", @@ -5458,19 +6342,6 @@ "csstype": "^3.0.2" } }, - "node_modules/@types/react-color": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.13.tgz", - "integrity": "sha512-2c/9FZ4ixC5T3JzN0LP5Cke2Mf0MKOP2Eh0NPDPWmuVH3NjPyhEjqNMQpN1Phr5m74egAy+p2lYNAFrX1z9Yrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/reactcss": "*" - }, - "peerDependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-dom": { "version": "18.0.11", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz", @@ -5489,16 +6360,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-lottie": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@types/react-lottie/-/react-lottie-1.2.10.tgz", - "integrity": "sha512-rCd1p3US4ELKJlqwVnP0h5b24zt5p9OCvKUoNpYExLqwbFZMWEiJ6EGLMmH7nmq5V7KomBIbWO2X/XRFsL0vCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-syntax-highlighter": { "version": "15.5.10", "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.10.tgz", @@ -5516,16 +6377,6 @@ "@types/react": "*" } }, - "node_modules/@types/reactcss": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.13.tgz", - "integrity": "sha512-gi3S+aUi6kpkF5vdhUsnkwbiSEIU/BEJyD7kBy2SudWBUuKmJk8AQKE0OVcQQeEy40Azh0lV6uynxlikYIJuwg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "*" - } - }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", @@ -5537,55 +6388,372 @@ "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", "license": "MIT" }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "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==" + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "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==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "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==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "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==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "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==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/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==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } }, - "node_modules/@types/tedious": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", - "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", + "peer": true, "dependencies": { - "@types/node": "*" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "dev": true, - "license": "MIT" + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } }, - "node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } }, - "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==" + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "dev": true, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", + "peer": true, "dependencies": { - "@types/yargs-parser": "*" + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" } }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" + "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==", + "license": "BSD-3-Clause", + "peer": true + }, + "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==", + "license": "Apache-2.0", + "peer": true }, "node_modules/abab": { "version": "2.0.6", @@ -5627,6 +6795,14 @@ "acorn": "^8" } }, + "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==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/acorn-walk": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", @@ -5647,6 +6823,63 @@ "node": ">= 6.0.0" } }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, "node_modules/ansi-escapes": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", @@ -5666,7 +6899,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -5708,29 +6940,181 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, "dependencies": { "dequal": "^2.0.3" } }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", + "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dependencies": { + "has-symbols": "^1.0.3" + } + }, "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/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "engines": { + "node": ">=4" + } + }, "node_modules/axios": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", @@ -5742,6 +7126,14 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dependencies": { + "dequal": "^2.0.3" + } + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -5988,7 +7380,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6075,9 +7466,21 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, "license": "MIT" }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -6271,6 +7674,16 @@ "node": ">= 6" } }, + "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==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -6521,8 +7934,7 @@ "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 + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/convert-source-map": { "version": "2.0.0", @@ -6788,6 +8200,11 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, "node_modules/data-urls": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", @@ -6904,6 +8321,11 @@ } } }, + "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==" + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -6914,6 +8336,35 @@ "node": ">=0.10.0" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6968,11 +8419,32 @@ "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==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "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, "license": "MIT" }, "node_modules/dom-helpers": { @@ -7104,56 +8576,13 @@ "react-dom": ">=0.14.0" } }, - "node_modules/draft-js-import-element": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/draft-js-import-element/-/draft-js-import-element-1.4.0.tgz", - "integrity": "sha512-WmYT5PrCm47lGL5FkH6sRO3TTAcn7qNHsD3igiPqLG/RXrqyKrqN4+wBgbcT2lhna/yfWTRtgzAbQsSJoS1Meg==", - "license": "ISC", - "dependencies": { - "draft-js-utils": "^1.4.0", - "synthetic-dom": "^1.4.0" - }, - "peerDependencies": { - "draft-js": ">=0.10.0", - "immutable": "3.x.x" - } - }, - "node_modules/draft-js-import-html": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/draft-js-import-html/-/draft-js-import-html-1.4.1.tgz", - "integrity": "sha512-KOZmtgxZriCDgg5Smr3Y09TjubvXe7rHPy/2fuLSsL+aSzwUDwH/aHDA/k47U+WfpmL4qgyg4oZhqx9TYJV0tg==", - "license": "ISC", - "dependencies": { - "draft-js-import-element": "^1.4.0" - }, - "peerDependencies": { - "draft-js": ">=0.10.0", - "immutable": "3.x.x" - } - }, - "node_modules/draft-js-utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/draft-js-utils/-/draft-js-utils-1.4.1.tgz", - "integrity": "sha512-xE81Y+z/muC5D5z9qWmKfxEW1XyXfsBzSbSBk2JRsoD0yzMGGHQm/0MtuqHl/EUDkaBJJLjJ2EACycoDMY/OOg==", - "license": "ISC", - "peerDependencies": { - "draft-js": ">=0.10.0", - "immutable": "3.x.x" - } - }, "node_modules/draft-js/node_modules/immutable": { "version": "3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==", "engines": { "node": ">=0.8.0" - } - }, - "node_modules/draftjs-to-html": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/draftjs-to-html/-/draftjs-to-html-0.9.1.tgz", - "integrity": "sha512-fFstE6+IayaVFBEvaFt/wN8vdj8FsTRzij7dy7LI9QIwf5LgfHFi9zSpvCg+feJ2tbYVqHxUkjcibwpsTpgFVQ==", - "license": "MIT" + } }, "node_modules/draftjs-utils": { "version": "0.10.2", @@ -7211,8 +8640,31 @@ "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } }, "node_modules/entities": { "version": "4.5.0", @@ -7235,6 +8687,58 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -7253,6 +8757,34 @@ "node": ">= 0.4" } }, + "node_modules/es-iterator-helpers": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", + "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "license": "MIT", + "peer": true + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -7277,22 +8809,488 @@ "hasown": "^2.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.4" + } + }, + "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==", + "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==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "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" + } + }, + "node_modules/eslint": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", + "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.54.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.2.4.tgz", + "integrity": "sha512-lunIBhsoeqw6/Lfkd6zPt25w1bn0znLA/JCL+au1HoEpSb4/PpsOYsYtgV/q+YPsoKIOzFyU5xnb04iZnXjUvg==", + "dependencies": { + "@next/eslint-plugin-next": "13.2.4", + "@rushstack/eslint-patch": "^1.1.3", + "@typescript-eslint/parser": "^5.42.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.31.7", + "eslint-plugin-react-hooks": "^4.5.0" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", + "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "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==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-simple-import-sort": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-10.0.0.tgz", + "integrity": "sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==", + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "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==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/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==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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", + "node_modules/eslint/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==", "engines": { - "node": ">=6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/eslint/node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", "engines": { "node": ">=10" }, @@ -7300,37 +9298,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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", + "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==", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=6.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "optionalDependencies": { - "source-map": "~0.6.1" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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, + "node_modules/espree/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==", "engines": { - "node": ">=0.10.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -7347,11 +9339,32 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -7366,7 +9379,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7383,6 +9395,16 @@ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/execa": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", @@ -7437,11 +9459,76 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" + }, + "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==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "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==" + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } }, "node_modules/fault": { "version": "1.0.4", @@ -7494,6 +9581,17 @@ "node-fetch": "^2.7.0" } }, + "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==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -7525,6 +9623,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" + }, "node_modules/follow-redirects": { "version": "1.15.9", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", @@ -7545,6 +9661,14 @@ } } }, + "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==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/form-data": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", @@ -7601,6 +9725,31 @@ "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==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "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", @@ -7678,6 +9827,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "9.3.5", "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", @@ -7696,6 +9871,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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==", + "license": "BSD-2-Clause", + "peer": true + }, "node_modules/glob/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -7728,6 +9921,39 @@ "node": ">=4" } }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -7743,8 +9969,12 @@ "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 + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "node_modules/gzip-size": { "version": "6.0.0", @@ -7760,6 +9990,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "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", @@ -7768,6 +10006,28 @@ "node": ">=4" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -8017,7 +10277,7 @@ "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, + "devOptional": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -8046,6 +10306,14 @@ ], "license": "BSD-3-Clause" }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "engines": { + "node": ">= 4" + } + }, "node_modules/immer": { "version": "9.0.21", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", @@ -8055,6 +10323,11 @@ "url": "https://opencollective.com/immer" } }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -8106,7 +10379,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -8125,7 +10397,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -8134,19 +10405,31 @@ "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 + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, + "node_modules/internal-slot": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "dependencies": { + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/intro.js": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/intro.js/-/intro.js-8.3.2.tgz", - "integrity": "sha512-+QsuU8P7Z/O7stAwZ8Uj6CPyKsY6xVx/7hKTVLjlIEPYHaT43XnEUUYHCln6Ehr7GlDuwczh6I8PD/HGf4EG0A==", - "license": "AGPL-3.0" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/intro.js/-/intro.js-7.2.0.tgz", + "integrity": "sha512-qbMfaB70rOXVBceIWNYnYTpVTiZsvQh/MIkfdQbpA9di9VBfj1GigUPfcCv3aOfsbrtPcri8vTLTA4FcEDcHSQ==", + "peer": true }, "node_modules/intro.js-react": { "version": "1.0.0", @@ -8179,11 +10462,49 @@ "url": "https://github.com/sponsors/wooorm" } }, - "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==" - }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==" + }, + "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==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -8195,6 +10516,21 @@ "node": ">=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==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -8217,6 +10553,17 @@ "node": ">=4" } }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -8228,6 +10575,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-decimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", @@ -8245,6 +10606,17 @@ "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==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", @@ -8267,6 +10639,20 @@ "node": ">=6" } }, + "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==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -8287,6 +10673,25 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -8295,6 +10700,28 @@ "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==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, "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", @@ -8311,6 +10738,40 @@ "@types/estree": "*" } }, + "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==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", @@ -8323,6 +10784,84 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -8445,6 +10984,18 @@ "node": ">=8" } }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -8921,27 +11472,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-fetch-mock": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz", - "integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-fetch": "^3.0.4", - "promise-polyfill": "^8.1.3" - } - }, - "node_modules/jest-fetch-mock/node_modules/cross-fetch": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", - "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "node-fetch": "^2.7.0" - } - }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -9581,6 +12111,47 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "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==", + "license": "MIT", + "peer": true, + "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==", + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/jose": { "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", @@ -9599,7 +12170,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -9724,11 +12294,26 @@ "node": ">=6" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, "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==" }, + "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==" + }, + "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==" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -9740,6 +12325,28 @@ "node": ">=6" } }, + "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==", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "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==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -9750,6 +12357,22 @@ "node": ">=6" } }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -9760,6 +12383,18 @@ "node": ">=6" } }, + "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==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -9855,6 +12490,16 @@ } } }, + "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==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -9874,17 +12519,16 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "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==", - "license": "MIT" - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "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==" + }, "node_modules/log-update": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", @@ -9986,7 +12630,6 @@ "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" @@ -10065,12 +12708,6 @@ "css-mediaquery": "^0.1.2" } }, - "node_modules/material-colors": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", - "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==", - "license": "ISC" - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -10304,8 +12941,15 @@ "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 + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } }, "node_modules/micromark": { "version": "3.2.0", @@ -10846,7 +13490,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -10902,7 +13545,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -10910,6 +13552,14 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", @@ -10966,8 +13616,14 @@ "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 + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "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==", + "license": "MIT", + "peer": true }, "node_modules/next": { "version": "13.2.4", @@ -11219,6 +13875,107 @@ "node": ">= 6" } }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/oidc-token-hash": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", @@ -11231,7 +13988,6 @@ "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, "dependencies": { "wrappy": "1" } @@ -11289,6 +14045,22 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -11410,7 +14182,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -11693,11 +14464,18 @@ "preact": ">=10" } }, + "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==", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, "bin": { "prettier": "bin-prettier.js" }, @@ -11708,6 +14486,17 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/pretty-format": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", @@ -11738,13 +14527,6 @@ "asap": "~2.0.3" } }, - "node_modules/promise-polyfill": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.3.0.tgz", - "integrity": "sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==", - "dev": true, - "license": "MIT" - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -11806,7 +14588,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "engines": { "node": ">=6" } @@ -11835,14 +14616,33 @@ "dev": true, "license": "MIT" }, - "node_modules/re-resizable": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-6.11.2.tgz", - "integrity": "sha512-2xI2P3OHs5qw7K0Ud1aLILK6MQxW50TcO+DetD9eIV58j84TqYeHoZcL9H4GXFXXIh7afhH8mv5iUCXII7OW7A==", + "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==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "license": "MIT", - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" } }, "node_modules/react": { @@ -11865,24 +14665,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/react-color": { - "version": "2.19.3", - "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", - "integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==", - "license": "MIT", - "dependencies": { - "@icons/material": "^0.2.4", - "lodash": "^4.17.15", - "lodash-es": "^4.17.15", - "material-colors": "^1.2.1", - "prop-types": "^15.5.10", - "reactcss": "^1.2.0", - "tinycolor2": "^1.4.1" - }, - "peerDependencies": { - "react": "*" - } - }, "node_modules/react-cookie": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.1.1.tgz", @@ -12126,15 +14908,6 @@ "react-dom": ">=16.6.0" } }, - "node_modules/reactcss": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", - "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", - "license": "MIT", - "dependencies": { - "lodash": "^4.0.1" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -12176,6 +14949,25 @@ "redux": "^4" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", + "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/refractor": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", @@ -12233,6 +15025,22 @@ "@babel/runtime": "^7.8.4" } }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpu-core": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", @@ -12338,6 +15146,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-in-the-middle": { "version": "7.5.2", "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", @@ -12434,6 +15252,14 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/resolve.exports": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", @@ -12484,12 +15310,54 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rfdc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", "dev": true }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", @@ -12528,6 +15396,28 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -12539,11 +15429,62 @@ "node": ">=6" } }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/sass": { @@ -12562,12 +15503,6 @@ "node": ">=14.0.0" } }, - "node_modules/sass/node_modules/immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", - "license": "MIT" - }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -12586,9 +15521,66 @@ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dependencies": { - "loose-envify": "^1.1.0" + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" } }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -12597,6 +15589,43 @@ "semver": "bin/semver.js" } }, + "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==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -12690,6 +15719,19 @@ "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", "license": "BSD-2-Clause" }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -12735,7 +15777,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, "engines": { "node": ">=8" } @@ -12795,6 +15836,27 @@ "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==", + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "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==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -12920,11 +15982,71 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -12932,6 +16054,14 @@ "node": ">=8" } }, + "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==", + "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", @@ -12961,7 +16091,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "engines": { "node": ">=8" }, @@ -13129,11 +16258,74 @@ "dev": true, "license": "MIT" }, - "node_modules/synthetic-dom": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/synthetic-dom/-/synthetic-dom-1.4.0.tgz", - "integrity": "sha512-mHv51ZsmZ+ShT/4s5kg+MGUIhY7Ltq4v03xpN1c8T1Krb5pScsh/lzEjyhrVD0soVDbThbd2e+4dD9vnDG4rhg==", - "license": "ISC" + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/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==", + "license": "MIT", + "peer": true }, "node_modules/test-exclude": { "version": "6.0.0", @@ -13172,11 +16364,10 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", - "license": "MIT" + "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==" }, "node_modules/tmpl": { "version": "1.0.5", @@ -13297,11 +16488,63 @@ "node": ">=0.3.1" } }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "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==" + }, + "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==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -13324,11 +16567,71 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -13364,6 +16667,20 @@ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, + "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==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -13583,6 +16900,14 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "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", @@ -13731,11 +17056,72 @@ "makeerror": "1.0.12" } }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, + "node_modules/webpack": { + "version": "5.99.5", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.5.tgz", + "integrity": "sha512-q+vHBa6H9qwBLUlHL4Y7L0L1/LlyBKZtS9FHNCQmtayxjI5RKC9yD8gpvLeqGv5lCQp1Re04yi0MF40pf30Pvg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, "node_modules/webpack-bundle-analyzer": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz", @@ -13827,6 +17213,78 @@ "node": ">= 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==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -13886,8 +17344,7 @@ "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 + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "4.0.2", @@ -25,19 +25,24 @@ }, "keywords": [], "license": "MIT", + "lint-staged": { + "*.{js,ts,jsx,tsx}": [ + "prettier --write", + "eslint --fix" + ] + }, "dependencies": { - "@dqbd/tiktoken": "^1.0.21", + "@babel/eslint-parser": "7.23.3", + "@dqbd/tiktoken": "^1.0.7", "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", "@fontsource/roboto": "^4.5.8", - "@lottiefiles/dotlottie-react": "^0.13.5", "@mui/icons-material": "^5.11.11", "@mui/material": "^5.11.12", "@mui/styled-engine-sc": "^5.11.11", "@mui/x-date-pickers": "^6.6.0", "@next/bundle-analyzer": "^13.4.3", "@react-input/mask": "^2.0.4", - "@reduxjs/toolkit": "^1.9.5", "@sentry/nextjs": "^9.12.0", "@sentry/webpack-plugin": "^3.3.1", "@testing-library/user-event": "^14.6.1", @@ -57,8 +62,10 @@ "cross-env": "^7.0.3", "dayjs": "^1.11.8", "draft-js": "^0.11.7", - "draft-js-import-html": "^1.4.1", - "draftjs-to-html": "^0.9.1", + "eslint": "^8.7.0", + "eslint-config-next": "13.2.4", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-simple-import-sort": "^10.0.0", "event-source-polyfill": "^1.0.31", "husky": "^8.0.0", "i18next": "^23.4.1", @@ -70,17 +77,14 @@ "next-auth": "^4.24.11", "next-i18next": "^14.0.0", "prettier": "^2.8.8", - "re-resizable": "^6.11.2", "react": "18.2.0", "react-chartjs-2": "^5.2.0", - "react-color": "^2.19.3", "react-cookie": "^4.1.1", "react-dom": "18.2.0", "react-draft-wysiwyg": "^1.15.0", "react-hook-form": "^7.61.1", "react-i18next": "^13.0.3", "react-markdown": "^8.0.7", - "react-redux": "^8.0.5", "react-responsive": "^10.0.1", "react-scrollbars-custom": "^4.1.1", "react-syntax-highlighter": "^15.5.0", @@ -95,23 +99,19 @@ "zustand": "^5.0.3" }, "devDependencies": { - "@eslint/js": "^9.31.0", "@svgr/webpack": "^8.1.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", - "@types/draftjs-to-html": "^0.8.4", "@types/intro.js": "^5.1.1", "@types/jest": "^29.5.14", "@types/lodash": "^4.14.195", - "@types/react-color": "^3.0.13", "@types/react-draft-wysiwyg": "^1.13.8", - "@types/react-lottie": "^1.2.10", "@types/react-syntax-highlighter": "^15.5.7", "cross-fetch": "^4.1.0", + "eslint-config-prettier": "^8.8.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "jest-fetch-mock": "^3.0.3", "lint-staged": "^13.2.2", "prettier": "^2.8.8", "ts-node": "^10.9.2", @@ -29,13 +29,21 @@ services: - node.role == worker labels: - traefik.enable=true - - traefik.swarm.network=infrastructure + - traefik.docker.network=infrastructure + + - traefik.http.middlewares.sts-header.headers.stsincludesubdomains=true + - traefik.http.middlewares.sts-header.headers.forceSTSHeader=true + - traefik.http.middlewares.sts-header.headers.stspreload=true + - traefik.http.middlewares.sts-header.headers.stsseconds=31536000 + - traefik.http.middlewares.sts-header.headers.isdevelopment=false + - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https + - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true - traefik.http.routers.frontend-web-http.rule=Host(`$DOMAIN`) - traefik.http.routers.frontend-web-http.entrypoints=web - traefik.http.routers.frontend-web-http.tls=false - traefik.http.routers.frontend-web-http.service=frontend - - traefik.http.routers.frontend-web-http.middlewares=sts-header@file,https-redirect@file + - traefik.http.routers.frontend-web-http.middlewares=sts-header@swarm,https-redirect@swarm - traefik.http.routers.frontend-web-https.rule=Host(`$DOMAIN`) - traefik.http.routers.frontend-web-https.entrypoints=websecure @@ -1,27 +0,0 @@ -diff --cc src/entities/user-account/api/get-user-settings.ts -index e69de29b,f046bf91..00000000 ---- a/src/entities/user-account/api/get-user-settings.ts -+++ b/src/entities/user-account/api/get-user-settings.ts -@@@ -1,0 -1,19 +1,22 @@@ -++<<<<<<< HEAD -++======= -+ import axios from 'axios' -+  -+ import { API_URL } from '#/shared/lib/constants' -+ import { IUserSetting } from '../types' -+  -+  -+ export const getUserSettings = async (token: string): Promise => { -+ try { -+ const { data } = await axios.get(API_URL + '/api/users/settings/', { -+ headers: { -+ Authorization: `Bearer ${token}`, -+ }, -+ }) -+  -+ return data -+ } catch (err) { -+ return [] -+ } -+ } -++>>>>>>> staging @@ -18,16 +18,6 @@ "noImplicitThis": false, "paths": { "#/*": ["./src/*"], - "#/app/*": ["./src/app/*"], - "#/entities/*": ["./src/entities/*"], - "#/features/*": ["./src/features/*"], - "#/shared/*": ["./src/shared/*"], - "#/widgets/*": ["./src/widgets/*"], - "#/assets/*": ["./src/assets/*"], - "#/domains/*": ["./src/domains/*"], - "#/pages/*": ["./src/pages/*"], - "#/views/*": ["./src/views/*"], - "#/main/*": ["./src/main/*"], "#/components/*": ["components/*"] } },