From c3ff94ed59b5cbce2f18f5d93fb4c37b1bbda6a8 Mon Sep 17 00:00:00 2001 From: se <63814960+se030@users.noreply.github.com> Date: Tue, 13 Jun 2023 03:32:11 +0900 Subject: [PATCH] =?UTF-8?q?Feat/#409-K:=20=EC=84=A0=ED=83=9D=EB=90=9C=20?= =?UTF-8?q?=ED=9A=8C=EC=9D=98=EB=A1=9D=20id=20URL=EC=97=90=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20(#411)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 선택된 회의록 id url params에 추가 * feat: URL 통한 회의록 선택 기능 추가 * refactor: navigation, 회의록 상태 및 이벤트 로직 위치 이동 * chore: recoil 설치 * feat: Mom 로딩 상태 및 DefaultMom 렌더링 로직의 workspace.moms에 recoil 적용 * docs: 회의록 선택에 따른 URL 변경 및 SELECT 이벤트 흐름 주석 추가 * refactor: 회의록 선택 로직 MomList로 이동 * del: 중복 로직 제거 * refactor: 회의록 없는 경우의 분기 Mom에서 Workspace 컴포넌트로 이동 * refactor: Sidebar의 workspace recoil atom으로 변경 * feat: 선택 회의록 정보 MomList 스타일에 반영 * feat: MOM_EVENT.SELECT emit 위치 Workspace로 이동 - 초기 접속한 URL에 momId가 지정되어 있을 경우도 커버하기 위해 URL 변경에 소켓 이벤트가 발생하도록 변경 - MomList는 navigate 역할만 수행 * feat: 워크스페이스 이동 로직 개선 - 이동할 워크스페이스 정보가 로드되기 전 렌더링 로직을 위해 workspace atom null로 리셋 - 이전과 값이 동일한 경우에는 변동이 없도록 수정 * refactor: MOM_EVENT.SELECT 이벤트 관련 코드 Workspace로 이동 * docs: 정규식 주석 추가 * refactor: momId 추출에 정규식 대신 react-router useParams 사용 * chore: react-query 설치 Refactor: 상태 관리에 react-query 적용 #412 * feat: workspace 상태에 useQuery 사용 recoil 관련 코드 제거 및 react-query로 대체 --- client/package.json | 1 + client/src/App.tsx | 5 +- client/src/apis/workspace.ts | 4 +- client/src/components/Mom/index.tsx | 26 +- client/src/components/Sidebar/MomList.tsx | 54 ++-- client/src/components/Sidebar/index.tsx | 31 ++- .../src/components/Sidebar/style.module.scss | 5 + client/src/components/Workspace/index.tsx | 63 +++-- .../WorkspaceThumbnailList/index.tsx | 9 +- client/src/main.tsx | 15 +- client/src/pages/Workspace/index.tsx | 2 +- package-lock.json | 239 +++++++++++++----- 12 files changed, 300 insertions(+), 154 deletions(-) diff --git a/client/package.json b/client/package.json index 442a67e8..982e2ce8 100644 --- a/client/package.json +++ b/client/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@react-icons/all-files": "^4.1.0", + "@tanstack/react-query": "^4.29.12", "@types/react-helmet": "^6.1.6", "axios": "^1.1.3", "classnames": "^2.3.2", diff --git a/client/src/App.tsx b/client/src/App.tsx index 706528cc..7625e115 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -16,7 +16,7 @@ function App() { const [user, setUser] = useState(null); const [isLoaded, setIsLoaded] = useState(false); - const location = useLocation(); + const { pathname } = useLocation(); const navigate = useNavigate(); const autoLogin = async () => { @@ -25,7 +25,8 @@ function App() { setIsLoaded(true); setUser(user); - if (user && !/^\/workspace(\/\d+)?$/.test(location.pathname)) { + const validPathPattern = /^\/workspace(\/\d+(\/.+)?)?$/; // /workspace(/숫자(/아무거나)) 와 처음부터 끝까지 일치하는 패턴 + if (user && !validPathPattern.test(pathname)) { navigate('/workspace'); } }; diff --git a/client/src/apis/workspace.ts b/client/src/apis/workspace.ts index ee359c08..b8b688b1 100644 --- a/client/src/apis/workspace.ts +++ b/client/src/apis/workspace.ts @@ -28,7 +28,9 @@ export const postWorkspaceJoin = async ({ export const getWorkspaceInfo = async ({ id, -}: GetInfoParams): Promise => { +}: Partial): Promise => { + if (!id) return null; + const res = await http.get(`/workspace/${id}`); if (res.status !== OK) throw new Error(); diff --git a/client/src/components/Mom/index.tsx b/client/src/components/Mom/index.tsx index e3618303..d2d56be1 100644 --- a/client/src/components/Mom/index.tsx +++ b/client/src/components/Mom/index.tsx @@ -9,7 +9,6 @@ import { useCRDT } from 'src/hooks/useCRDT'; import useDebounce from 'src/hooks/useDebounce'; import { v4 as uuid } from 'uuid'; -import DefaultMom from './DefaultMom'; import ee from './EventEmitter'; import style from './style.module.scss'; @@ -37,8 +36,6 @@ function Mom() { const focusIndex = useRef(); const [blocks, setBlocks] = useState([]); - const [isLoaded, setIsLoaded] = useState(false); - const [isMomsEmpty, setIsMomsEmpty] = useState(false); const onTitleUpdate: React.FormEventHandler = useDebounce( () => { @@ -230,20 +227,7 @@ function Mom() { BLOCK_EVENT.UPDATE_TYPE, ].forEach((event) => socket.off(event)); }; - }, [selectedMom]); - - useEffect(() => { - ee.on(MOM_EVENT.LOADED, (momsLength: number) => { - setIsLoaded(true); - setIsMomsEmpty(momsLength === 0); - }); - - ee.emit(MOM_EVENT.REQUEST_LOADED); - - return () => { - ee.off(MOM_EVENT.LOADED); - }; - }, [socket]); + }, [selectedMom, socket]); const registerRef = (index: number) => (ref: React.RefObject) => { @@ -251,14 +235,6 @@ function Mom() { setBlockFocus(index); }; - if (!isLoaded) { - return
; - } - - if (isMomsEmpty && !selectedMom) { - return ; - } - return (
{selectedMom && ( diff --git a/client/src/components/Sidebar/MomList.tsx b/client/src/components/Sidebar/MomList.tsx index df718bef..e4bd01d2 100644 --- a/client/src/components/Sidebar/MomList.tsx +++ b/client/src/components/Sidebar/MomList.tsx @@ -1,58 +1,49 @@ import { RiFileAddLine } from '@react-icons/all-files/ri/RiFileAddLine'; import * as MomMessage from '@wabinar/api-types/mom'; import { MOM_EVENT } from '@wabinar/constants/socket-message'; -import { memo, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import ee from 'src/components/Mom/EventEmitter'; +import useSelectedMomContext from 'src/hooks/context/useSelectedMomContext'; import useSocketContext from 'src/hooks/context/useSocketContext'; import { TMom } from 'src/types/mom'; -import ee from '../Mom/EventEmitter'; import style from './style.module.scss'; interface MomListProps { moms: TMom[]; - selectedMom: TMom | null; - setSelectedMom: React.Dispatch>; } -function MomList({ moms, selectedMom, setSelectedMom }: MomListProps) { +function MomList({ moms }: MomListProps) { + const { selectedMom, setSelectedMom } = useSelectedMomContext(); + const { momSocket: socket } = useSocketContext(); const [momList, setMomList] = useState(moms); + const navigate = useNavigate(); + const onCreateMom = () => { socket.emit(MOM_EVENT.CREATE); }; const onSelect = (id: string) => { - const message: MomMessage.Select = { id }; - socket.emit(MOM_EVENT.SELECT, message); + setSelectedMom(null); + navigate(id); }; useEffect(() => { - if (moms.length) { - const message: MomMessage.Select = { id: moms[0]._id }; - socket.emit(MOM_EVENT.SELECT, message); - } - setMomList(moms); + }, [moms]); - ee.on(MOM_EVENT.REQUEST_LOADED, () => { - ee.emit(MOM_EVENT.LOADED, moms ? moms.length : 0); - }); - + useEffect(() => { socket.on(MOM_EVENT.CREATE, ({ mom }: MomMessage.Created) => setMomList((prev) => [...prev, mom]), ); - socket.on(MOM_EVENT.SELECT, ({ mom }: MomMessage.Selected) => { - setSelectedMom(mom); - }); - return () => { socket.off(MOM_EVENT.CREATE); - socket.off(MOM_EVENT.SELECT); - ee.off(MOM_EVENT.REQUEST_LOADED); }; - }, [moms]); + }, [socket]); useEffect(() => { ee.on(MOM_EVENT.UPDATE_TITLE, (title) => { @@ -71,7 +62,7 @@ function MomList({ moms, selectedMom, setSelectedMom }: MomListProps) { return () => { ee.off(MOM_EVENT.UPDATE_TITLE); }; - }, []); + }, [selectedMom]); return (
@@ -89,7 +80,14 @@ function MomList({ moms, selectedMom, setSelectedMom }: MomListProps) {
    {momList.map(({ _id: id, title }) => ( -
  • onSelect(id)} role="button"> +
  • onSelect(id)} + role="button" + > {title}
  • ))} @@ -98,8 +96,4 @@ function MomList({ moms, selectedMom, setSelectedMom }: MomListProps) { ); } -const isMemoized = (prevProps: MomListProps, nextProps: MomListProps) => { - return prevProps.moms === nextProps.moms; -}; - -export default memo(MomList, isMemoized); +export default MomList; diff --git a/client/src/components/Sidebar/index.tsx b/client/src/components/Sidebar/index.tsx index 4ea139c6..fd0be935 100644 --- a/client/src/components/Sidebar/index.tsx +++ b/client/src/components/Sidebar/index.tsx @@ -1,5 +1,6 @@ -import useSelectedMomContext from 'src/hooks/context/useSelectedMomContext'; -import { WorkspaceInfo } from 'src/types/workspace'; +import { useQuery } from '@tanstack/react-query'; +import { useParams } from 'react-router-dom'; +import { getWorkspaceInfo } from 'src/apis/workspace'; import Header from './Header'; import MeetingButton from './MeetingButton'; @@ -7,23 +8,25 @@ import MemberList from './MemberList'; import MomList from './MomList'; import style from './style.module.scss'; -interface SidebarProps { - workspace: WorkspaceInfo; -} +function Sidebar() { + const { id } = useParams(); + const { data: workspace } = useQuery({ + queryKey: ['workspace', id], + queryFn: () => getWorkspaceInfo({ id }), + }); + + if (!workspace) { + return
    ; + } -function Sidebar({ workspace }: SidebarProps) { - const { selectedMom, setSelectedMom } = useSelectedMomContext(); + const { name, members, moms } = workspace; return (
    -
    +
    - - + +
    diff --git a/client/src/components/Sidebar/style.module.scss b/client/src/components/Sidebar/style.module.scss index 1bdc0356..8780fe01 100644 --- a/client/src/components/Sidebar/style.module.scss +++ b/client/src/components/Sidebar/style.module.scss @@ -135,6 +135,11 @@ } } +.mom-list-item__selected { + color: $black; + font-weight: 500; +} + .meeting-button { position: absolute; bottom: 15px; diff --git a/client/src/components/Workspace/index.tsx b/client/src/components/Workspace/index.tsx index 8c4df93b..54a8961e 100644 --- a/client/src/components/Workspace/index.tsx +++ b/client/src/components/Workspace/index.tsx @@ -1,8 +1,11 @@ -import { WORKSPACE_EVENT } from '@wabinar/constants/socket-message'; +import { useQuery } from '@tanstack/react-query'; +import * as MomMessage from '@wabinar/api-types/mom'; +import { MOM_EVENT, WORKSPACE_EVENT } from '@wabinar/constants/socket-message'; import Mom from 'components/Mom'; +import DefaultMom from 'components/Mom/DefaultMom'; import Sidebar from 'components/Sidebar'; import { useEffect, useMemo, useState } from 'react'; -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { getWorkspaceInfo } from 'src/apis/workspace'; import MeetingMediaBar from 'src/components/MeetingMediaBar'; import MeetingContext from 'src/contexts/meeting'; @@ -10,32 +13,60 @@ import { SelectedMomContext } from 'src/contexts/selected-mom'; import { SocketContext } from 'src/contexts/socket'; import useSocket from 'src/hooks/useSocket'; import { TMom } from 'src/types/mom'; -import { WorkspaceInfo } from 'src/types/workspace'; function Workspace() { const { id } = useParams(); - const [isOnGoing, setIsOnGoing] = useState(false); + const navigate = useNavigate(); + + const params = useParams(); + const momId = params['*']; + + const { data: workspace } = useQuery({ + queryKey: ['workspace', id], + queryFn: () => getWorkspaceInfo({ id }), + }); - const [workspace, setWorkspace] = useState(null); const [selectedMom, setSelectedMom] = useState(null); + const [isOnGoing, setIsOnGoing] = useState(false); const momSocket = useSocket(`/workspace-mom/${id}`); const workspaceSocket = useSocket(`/workspace/${id}`); - const loadWorkspaceInfo = async () => { - if (id) { - const workspaceInfo = await getWorkspaceInfo({ id }); + useEffect(() => { + setIsOnGoing(false); + }, [id]); + + useEffect(() => { + if (!workspace) return; + const { moms } = workspace; + + if (!momId && moms.length) { + navigate(moms[0]._id); + } - setWorkspace(workspaceInfo); + if (!moms.length) { + setSelectedMom(null); + } + }, [workspace, momId]); - if (!workspaceInfo.moms[0]) setSelectedMom(null); + useEffect(() => { + if (momId && momSocket) { + const message: MomMessage.Select = { id: momId }; + momSocket.emit(MOM_EVENT.SELECT, message); } - }; + }, [momId, momSocket]); useEffect(() => { - loadWorkspaceInfo(); - setIsOnGoing(false); - }, [id]); + if (!momSocket) return; + + momSocket.on(MOM_EVENT.SELECT, ({ mom }: MomMessage.Selected) => { + setSelectedMom(mom); + }); + + return () => { + momSocket.off(MOM_EVENT.SELECT); + }; + }, [momSocket]); useEffect(() => { if (!workspaceSocket) { @@ -72,8 +103,8 @@ function Workspace() { {workspace && ( - - + + {workspace.moms.length ? : } )} {isOnGoing && } diff --git a/client/src/components/WorkspaceThumbnailList/index.tsx b/client/src/components/WorkspaceThumbnailList/index.tsx index 9f1d7182..a16391ec 100644 --- a/client/src/components/WorkspaceThumbnailList/index.tsx +++ b/client/src/components/WorkspaceThumbnailList/index.tsx @@ -1,4 +1,5 @@ -import { useNavigate } from 'react-router-dom'; +import { useQueryClient } from '@tanstack/react-query'; +import { useNavigate, useParams } from 'react-router-dom'; import { Workspace } from 'src/types/workspace'; import style from './style.module.scss'; @@ -9,9 +10,15 @@ interface WorkspaceThumbnailListProps { } function WorkspaceThumbnailList({ workspaces }: WorkspaceThumbnailListProps) { + const queryClient = useQueryClient(); + + const { id: currentId } = useParams(); const navigate = useNavigate(); const onClick = (targetId: number) => { + if (Number(currentId) === targetId) return; + + queryClient.invalidateQueries({ queryKey: ['workspace', currentId] }); navigate(`/workspace/${targetId}`); }; diff --git a/client/src/main.tsx b/client/src/main.tsx index fda074a0..76a65715 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -1,13 +1,18 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; - import 'react-toastify/dist/ReactToastify.css'; + import App from './App'; import Toaster from './components/common/Toaster'; +const queryClient = new QueryClient(); + ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( - - - - , + + + + + + , ); diff --git a/client/src/pages/Workspace/index.tsx b/client/src/pages/Workspace/index.tsx index 15e3b1b4..1856d81b 100644 --- a/client/src/pages/Workspace/index.tsx +++ b/client/src/pages/Workspace/index.tsx @@ -58,7 +58,7 @@ function WorkspacePage() { }> } /> - } /> + } /> ) : ( diff --git a/package-lock.json b/package-lock.json index 2ae803a9..9a93b287 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,6 +61,7 @@ "version": "0.0.0", "dependencies": { "@react-icons/all-files": "^4.1.0", + "@tanstack/react-query": "^4.29.12", "@types/react-helmet": "^6.1.6", "axios": "^1.1.3", "classnames": "^2.3.2", @@ -1882,6 +1883,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -1897,6 +1899,7 @@ "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -3134,6 +3137,41 @@ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, + "node_modules/@tanstack/query-core": { + "version": "4.29.11", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.11.tgz", + "integrity": "sha512-8C+hF6SFAb/TlFZyS9FItgNwrw4PMa7YeX+KQYe2ZAiEz6uzg6yIr+QBzPkUwZ/L0bXvGd1sufTm3wotoz+GwQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.29.12", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.12.tgz", + "integrity": "sha512-zhcN6+zF6cxprxhTHQajHGlvxgK8npnp9uLe9yaWhGc6sYcPWXzyO4raL4HomUzQOPzu3jLvkriJQ7BOrDM8vA==", + "dependencies": { + "@tanstack/query-core": "4.29.11", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/@testing-library/jest-dom": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", @@ -3882,7 +3920,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "devOptional": true, + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4236,7 +4274,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -4308,7 +4346,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -4558,7 +4596,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, + "dev": true, "funding": [ { "type": "individual", @@ -4585,7 +4623,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -5631,6 +5669,7 @@ "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz", "integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -5670,6 +5709,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -5685,6 +5725,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -5700,6 +5741,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -5715,6 +5757,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -5730,6 +5773,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -5745,6 +5789,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -5760,6 +5805,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -5775,6 +5821,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -5790,6 +5837,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -5805,6 +5853,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -5820,6 +5869,7 @@ "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -5835,6 +5885,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -5850,6 +5901,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -5865,6 +5917,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -5880,6 +5933,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -5895,6 +5949,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -5910,6 +5965,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -5925,6 +5981,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -5940,6 +5997,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -5955,6 +6013,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -6867,7 +6926,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "devOptional": true, + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -7028,6 +7087,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -7549,7 +7609,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", - "devOptional": true + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -7814,7 +7874,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -7854,6 +7914,7 @@ "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -7895,7 +7956,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -7925,7 +7986,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -7967,7 +8028,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.12.0" } @@ -10456,6 +10517,7 @@ "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -10591,7 +10653,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -11121,7 +11183,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-to-regexp": { "version": "0.1.7", @@ -11140,7 +11203,8 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -11242,6 +11306,7 @@ "version": "8.4.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -11780,7 +11845,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -12009,6 +12074,7 @@ "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -12114,7 +12180,7 @@ "version": "1.56.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.1.tgz", "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", - "devOptional": true, + "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -12383,6 +12449,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -13035,6 +13102,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -13308,7 +13376,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "devOptional": true, + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -13626,6 +13694,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -13696,6 +13772,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.3.tgz", "integrity": "sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==", + "dev": true, "dependencies": { "esbuild": "^0.15.9", "postcss": "^8.4.18", @@ -13807,6 +13884,7 @@ "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -15701,8 +15779,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", - "dev": true, - "requires": {} + "dev": true }, "@cush/relative": { "version": "1.0.0", @@ -15737,12 +15814,14 @@ "version": "0.15.13", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz", "integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==", + "dev": true, "optional": true }, "@esbuild/linux-loong64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz", "integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==", + "dev": true, "optional": true }, "@eslint/eslintrc": { @@ -16635,8 +16714,7 @@ "@react-icons/all-files": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz", - "integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==", - "requires": {} + "integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==" }, "@remix-run/router": { "version": "1.0.3", @@ -16681,6 +16759,20 @@ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, + "@tanstack/query-core": { + "version": "4.29.11", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.11.tgz", + "integrity": "sha512-8C+hF6SFAb/TlFZyS9FItgNwrw4PMa7YeX+KQYe2ZAiEz6uzg6yIr+QBzPkUwZ/L0bXvGd1sufTm3wotoz+GwQ==" + }, + "@tanstack/react-query": { + "version": "4.29.12", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.12.tgz", + "integrity": "sha512-zhcN6+zF6cxprxhTHQajHGlvxgK8npnp9uLe9yaWhGc6sYcPWXzyO4raL4HomUzQOPzu3jLvkriJQ7BOrDM8vA==", + "requires": { + "@tanstack/query-core": "4.29.11", + "use-sync-external-store": "^1.2.0" + } + }, "@testing-library/jest-dom": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", @@ -17222,8 +17314,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "8.2.0", @@ -17290,7 +17381,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "devOptional": true, + "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -17553,7 +17644,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true + "dev": true }, "bl": { "version": "4.1.0", @@ -17620,7 +17711,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, + "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -17784,7 +17875,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, + "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -17800,7 +17891,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -17920,6 +18011,7 @@ "version": "file:client", "requires": { "@react-icons/all-files": "^4.1.0", + "@tanstack/react-query": "^4.29.12", "@testing-library/jest-dom": "^5.16.5", "@types/react": "^18.0.24", "@types/react-dom": "^18.0.8", @@ -18637,6 +18729,7 @@ "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz", "integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==", + "dev": true, "requires": { "@esbuild/android-arm": "0.15.13", "@esbuild/linux-loong64": "0.15.13", @@ -18666,120 +18759,140 @@ "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz", "integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==", + "dev": true, "optional": true }, "esbuild-android-arm64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz", "integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==", + "dev": true, "optional": true }, "esbuild-darwin-64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz", "integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==", + "dev": true, "optional": true }, "esbuild-darwin-arm64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz", "integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==", + "dev": true, "optional": true }, "esbuild-freebsd-64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz", "integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==", + "dev": true, "optional": true }, "esbuild-freebsd-arm64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz", "integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==", + "dev": true, "optional": true }, "esbuild-linux-32": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz", "integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==", + "dev": true, "optional": true }, "esbuild-linux-64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz", "integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==", + "dev": true, "optional": true }, "esbuild-linux-arm": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz", "integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==", + "dev": true, "optional": true }, "esbuild-linux-arm64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz", "integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==", + "dev": true, "optional": true }, "esbuild-linux-mips64le": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz", "integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==", + "dev": true, "optional": true }, "esbuild-linux-ppc64le": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz", "integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==", + "dev": true, "optional": true }, "esbuild-linux-riscv64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz", "integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==", + "dev": true, "optional": true }, "esbuild-linux-s390x": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz", "integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==", + "dev": true, "optional": true }, "esbuild-netbsd-64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz", "integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==", + "dev": true, "optional": true }, "esbuild-openbsd-64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz", "integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==", + "dev": true, "optional": true }, "esbuild-sunos-64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz", "integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==", + "dev": true, "optional": true }, "esbuild-windows-32": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz", "integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==", + "dev": true, "optional": true }, "esbuild-windows-64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz", "integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==", + "dev": true, "optional": true }, "esbuild-windows-arm64": { "version": "0.15.13", "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz", "integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==", + "dev": true, "optional": true }, "escalade": { @@ -18911,8 +19024,7 @@ "version": "8.5.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "requires": {} + "dev": true }, "eslint-import-resolver-node": { "version": "0.3.6", @@ -19481,7 +19593,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "devOptional": true, + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -19603,6 +19715,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "optional": true }, "function-bind": { @@ -19971,7 +20084,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", - "devOptional": true + "dev": true }, "import-fresh": { "version": "3.3.0", @@ -20172,7 +20285,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -20197,6 +20310,7 @@ "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, "requires": { "has": "^1.0.3" } @@ -20220,7 +20334,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true + "dev": true }, "is-fullwidth-code-point": { "version": "4.0.0", @@ -20238,7 +20352,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -20265,7 +20379,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true + "dev": true }, "is-number-object": { "version": "1.0.7", @@ -20941,8 +21055,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "29.2.0", @@ -22099,7 +22212,8 @@ "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true }, "natural-compare": { "version": "1.4.0", @@ -22209,7 +22323,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true + "dev": true }, "npm-run-path": { "version": "5.1.0", @@ -22577,7 +22691,8 @@ "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "path-to-regexp": { "version": "0.1.7", @@ -22593,7 +22708,8 @@ "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "picomatch": { "version": "2.3.1", @@ -22664,6 +22780,7 @@ "version": "8.4.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "dev": true, "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -22686,15 +22803,13 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, - "requires": {} + "dev": true }, "postcss-scss": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.5.tgz", "integrity": "sha512-F7xpB6TrXyqUh3GKdyB4Gkp3QL3DDW1+uI+gxx/oJnUt/qXI4trj5OGlp9rOKdoABGULuqtqeG+3HEVQk4DjmA==", - "dev": true, - "requires": {} + "dev": true }, "postcss-selector-parser": { "version": "6.0.10", @@ -23038,7 +23153,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -23209,6 +23324,7 @@ "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, "requires": { "fsevents": "~2.3.2" } @@ -23271,7 +23387,7 @@ "version": "1.56.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.1.tgz", "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", - "devOptional": true, + "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -23511,7 +23627,8 @@ "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true }, "source-map-support": { "version": "0.5.13", @@ -23876,8 +23993,7 @@ "version": "9.0.4", "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.4.tgz", "integrity": "sha512-38nIGTGpFOiK5LjJ8Ma1yUgpKENxoKSOhbDNSemY7Ep0VsJoXIW9Iq/2hSt699oB9tReynfWicTAoIHiq8Rvbg==", - "dev": true, - "requires": {} + "dev": true }, "stylelint-config-prettier-scss": { "version": "0.0.1", @@ -23902,8 +24018,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz", "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==", - "dev": true, - "requires": {} + "dev": true }, "stylelint-config-recommended-scss": { "version": "8.0.0", @@ -23930,8 +24045,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz", "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==", - "dev": true, - "requires": {} + "dev": true } } }, @@ -24005,7 +24119,8 @@ "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true }, "svg-tags": { "version": "1.0.0", @@ -24220,7 +24335,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "devOptional": true, + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -24417,6 +24532,11 @@ "punycode": "^2.1.0" } }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -24475,6 +24595,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.3.tgz", "integrity": "sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==", + "dev": true, "requires": { "esbuild": "^0.15.9", "fsevents": "~2.3.2", @@ -24487,6 +24608,7 @@ "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, "requires": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -24750,8 +24872,7 @@ "ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "requires": {} + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" }, "xmlhttprequest-ssl": { "version": "2.0.0",