Merge branch 'livekit' into toger5/track-processor-blur

This commit is contained in:
Hugh Nimmo-Smith
2025-01-06 17:21:30 +00:00
committed by GitHub
19 changed files with 115 additions and 264 deletions

View File

@@ -59,8 +59,8 @@
"@types/node": "^22.0.0",
"@types/pako": "^2.0.3",
"@types/qrcode": "^1.5.5",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@types/react-router-dom": "^5.3.3",
"@types/sdp-transform": "^2.4.5",
"@types/uuid": "10",
"@typescript-eslint/eslint-plugin": "^8.0.0",
@@ -85,10 +85,9 @@
"eslint-plugin-rxjs": "^5.0.3",
"eslint-plugin-unicorn": "^56.0.0",
"global-jsdom": "^25.0.0",
"history": "^4.0.0",
"i18next": "^23.0.0",
"i18next": "^24.0.0",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-parser": "^9.0.0",
"i18next-parser": "^9.1.0",
"jsdom": "^25.0.0",
"knip": "^5.27.2",
"livekit-client": "^2.5.7",
@@ -107,7 +106,7 @@
"react": "18",
"react-dom": "18",
"react-i18next": "^15.0.0",
"react-router-dom": "^5.2.0",
"react-router-dom": "^6.28.0",
"react-use-clipboard": "^1.0.7",
"react-use-measure": "^2.1.1",
"rxjs": "^7.8.1",

View File

@@ -6,14 +6,8 @@ Please see LICENSE in the repository root for full details.
*/
import { type FC, Suspense, useEffect, useState } from "react";
import {
BrowserRouter as Router,
Switch,
Route,
useLocation,
} from "react-router-dom";
import { BrowserRouter, Route, useLocation, Routes } from "react-router-dom";
import * as Sentry from "@sentry/react";
import { type History } from "history";
import { TooltipProvider } from "@vector-im/compound-web";
import { logger } from "matrix-js-sdk/src/logger";
@@ -30,7 +24,7 @@ import { widget } from "./widget";
import { useTheme } from "./useTheme";
import { ProcessorProvider } from "./livekit/TrackProcessorContext";
const SentryRoute = Sentry.withSentryRouting(Route);
const SentryRoute = Sentry.withSentryReactRouterV6Routing(Route);
interface SimpleProviderProps {
children: JSX.Element;
@@ -56,11 +50,7 @@ const ThemeProvider: FC<SimpleProviderProps> = ({ children }) => {
return children;
};
interface AppProps {
history: History;
}
export const App: FC<AppProps> = ({ history }) => {
export const App: FC = () => {
const [loaded, setLoaded] = useState(false);
useEffect(() => {
Initializer.init()
@@ -77,7 +67,7 @@ export const App: FC<AppProps> = ({ history }) => {
return (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
<Router history={history}>
<BrowserRouter>
<BackgroundProvider>
<ThemeProvider>
<TooltipProvider>
@@ -86,20 +76,15 @@ export const App: FC<AppProps> = ({ history }) => {
<Providers>
<Sentry.ErrorBoundary fallback={errorPage}>
<DisconnectedBanner />
<Switch>
<SentryRoute exact path="/">
<HomePage />
</SentryRoute>
<SentryRoute exact path="/login">
<LoginPage />
</SentryRoute>
<SentryRoute exact path="/register">
<RegisterPage />
</SentryRoute>
<SentryRoute path="*">
<RoomPage />
</SentryRoute>
</Switch>
<Routes>
<SentryRoute path="/" element={<HomePage />} />
<SentryRoute path="/login" element={<LoginPage />} />
<SentryRoute
path="/register"
element={<RegisterPage />}
/>
<SentryRoute path="*" element={<RoomPage />} />
</Routes>
</Sentry.ErrorBoundary>
</Providers>
</Suspense>
@@ -109,7 +94,7 @@ export const App: FC<AppProps> = ({ history }) => {
</TooltipProvider>
</ThemeProvider>
</BackgroundProvider>
</Router>
</BrowserRouter>
);
};

View File

@@ -15,7 +15,7 @@ import {
useRef,
useMemo,
} from "react";
import { useHistory } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import { logger } from "matrix-js-sdk/src/logger";
import { useTranslation } from "react-i18next";
import { type ISyncStateData, type SyncState } from "matrix-js-sdk/src/sync";
@@ -144,7 +144,7 @@ interface Props {
}
export const ClientProvider: FC<Props> = ({ children }) => {
const history = useHistory();
const navigate = useNavigate();
// null = signed out, undefined = loading
const [initClientState, setInitClientState] = useState<
@@ -228,9 +228,9 @@ export const ClientProvider: FC<Props> = ({ children }) => {
await client.clearStores();
clearSession();
setInitClientState(null);
history.push("/");
navigate("/");
PosthogAnalytics.instance.setRegistrationType(RegistrationType.Guest);
}, [history, initClientState?.client]);
}, [navigate, initClientState?.client]);
const { t } = useTranslation();

View File

@@ -82,7 +82,7 @@ export const UserMenu: FC<Props> = ({
if (!isAuthenticated) {
return (
<LinkButton to={{ pathname: "/login", state: { from: location } }}>
<LinkButton to={{ pathname: "/login" }} state={{ from: location }}>
{t("log_in")}
</LinkButton>
);

View File

@@ -6,7 +6,7 @@ Please see LICENSE in the repository root for full details.
*/
import { type FC, useCallback, useState } from "react";
import { useHistory, useLocation } from "react-router-dom";
import { useNavigate, useLocation } from "react-router-dom";
import { useClientLegacy } from "./ClientContext";
import { useProfile } from "./profile/useProfile";
@@ -19,7 +19,7 @@ interface Props {
export const UserMenuContainer: FC<Props> = ({ preventNavigation = false }) => {
const location = useLocation();
const history = useHistory();
const navigate = useNavigate();
const { client, logout, authenticated, passwordlessUser } = useClientLegacy();
const { displayName, avatarUrl } = useProfile(client);
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
@@ -45,11 +45,11 @@ export const UserMenuContainer: FC<Props> = ({ preventNavigation = false }) => {
logout?.();
break;
case "login":
history.push("/login", { state: { from: location } });
navigate("/login", { state: { from: location } });
break;
}
},
[history, location, logout, setSettingsModalOpen],
[navigate, location, logout, setSettingsModalOpen],
);
const userName = client?.getUserIdLocalpart() ?? "";

View File

@@ -6,7 +6,7 @@ Please see LICENSE in the repository root for full details.
*/
import { type FC, type FormEvent, useCallback, useRef, useState } from "react";
import { useHistory, useLocation } from "react-router-dom";
import { useNavigate, useLocation } from "react-router-dom";
import { Trans, useTranslation } from "react-i18next";
import { Button } from "@vector-im/compound-web";
@@ -29,7 +29,7 @@ export const LoginPage: FC = () => {
const homeserver = Config.defaultHomeserverUrl(); // TODO: Make this configurable
const usernameRef = useRef<HTMLInputElement>(null);
const passwordRef = useRef<HTMLInputElement>(null);
const history = useHistory();
const navigate = useNavigate();
const location = useLocation();
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error>();
@@ -61,9 +61,9 @@ export const LoginPage: FC = () => {
if (locationState && locationState.from) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
history.push(locationState.from);
navigate(locationState.from);
} else {
history.push("/");
navigate("/");
}
PosthogAnalytics.instance.eventLogin.track();
})
@@ -72,7 +72,7 @@ export const LoginPage: FC = () => {
setLoading(false);
});
},
[login, location, history, homeserver, setClient],
[login, location, navigate, homeserver, setClient],
);
// we need to limit the length of the homserver name to not cover the whole loginview input with the string.
let shortendHomeserverName = Config.defaultServerName()?.slice(0, 25);

View File

@@ -14,7 +14,7 @@ import {
useRef,
useState,
} from "react";
import { useHistory, useLocation } from "react-router-dom";
import { useNavigate, useLocation } from "react-router-dom";
import { captureException } from "@sentry/react";
import { sleep } from "matrix-js-sdk/src/utils";
import { Trans, useTranslation } from "react-i18next";
@@ -41,7 +41,7 @@ export const RegisterPage: FC = () => {
useClientLegacy();
const confirmPasswordRef = useRef<HTMLInputElement>(null);
const history = useHistory();
const navigate = useNavigate();
const location = useLocation();
const [registering, setRegistering] = useState(false);
const [error, setError] = useState<Error>();
@@ -106,9 +106,9 @@ export const RegisterPage: FC = () => {
if (location.state?.from) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
history.push(location.state?.from);
navigate(location.state?.from);
} else {
history.push("/");
navigate("/");
}
})
.catch((error) => {
@@ -120,7 +120,7 @@ export const RegisterPage: FC = () => {
[
register,
location,
history,
navigate,
passwordlessUser,
reset,
execute,
@@ -141,9 +141,9 @@ export const RegisterPage: FC = () => {
useEffect(() => {
if (!loading && authenticated && !passwordlessUser && !registering) {
history.push("/");
navigate("/");
}
}, [loading, history, authenticated, passwordlessUser, registering]);
}, [loading, navigate, authenticated, passwordlessUser, registering]);
if (loading) {
return <LoadingView />;

View File

@@ -9,42 +9,27 @@ import {
type ComponentPropsWithoutRef,
forwardRef,
type MouseEvent,
useCallback,
useMemo,
} from "react";
import { Link as CpdLink } from "@vector-im/compound-web";
import { useHistory } from "react-router-dom";
import { createPath, type LocationDescriptor, type Path } from "history";
import { type LinkProps, useHref, useLinkClickHandler } from "react-router-dom";
import classNames from "classnames";
import { useLatest } from "../useLatest";
import styles from "./Link.module.css";
export function useLink(
to: LocationDescriptor,
to: LinkProps["to"],
state?: unknown,
): [Path, (e: MouseEvent) => void] {
const latestState = useLatest(state);
const history = useHistory();
const path = useMemo(
() => (typeof to === "string" ? to : createPath(to)),
[to],
);
const onClick = useCallback(
(e: MouseEvent) => {
e.preventDefault();
history.push(to, latestState.current);
},
[history, to, latestState],
);
): [string, (e: MouseEvent<HTMLAnchorElement>) => void] {
const href = useHref(to);
const onClick = useLinkClickHandler(to, { state });
return [path, onClick];
return [href, onClick];
}
type Props = Omit<
ComponentPropsWithoutRef<typeof CpdLink>,
"href" | "onClick"
> & { to: LocationDescriptor; state?: unknown };
> & { to: LinkProps["to"]; state?: unknown };
/**
* A version of Compound's link component that integrates with our router setup.

View File

@@ -7,22 +7,22 @@ Please see LICENSE in the repository root for full details.
import { type ComponentPropsWithoutRef, forwardRef } from "react";
import { Button } from "@vector-im/compound-web";
import { type LocationDescriptor } from "history";
import type { LinkProps } from "react-router-dom";
import { useLink } from "./Link";
type Props = Omit<
ComponentPropsWithoutRef<typeof Button<"a">>,
"as" | "href"
> & { to: LocationDescriptor };
> & { to: LinkProps["to"]; state?: unknown };
/**
* A version of Compound's button component that acts as a link and integrates
* with our router setup.
*/
export const LinkButton = forwardRef<HTMLAnchorElement, Props>(
function LinkButton({ to, ...props }, ref) {
const [path, onClick] = useLink(to);
function LinkButton({ to, state, ...props }, ref) {
const [path, onClick] = useLink(to, state);
return <Button as="a" ref={ref} {...props} href={path} onClick={onClick} />;
},
);

View File

@@ -12,12 +12,12 @@ import {
type FormEventHandler,
type FC,
} from "react";
import { useHistory } from "react-router-dom";
import { type MatrixClient } from "matrix-js-sdk/src/client";
import { useTranslation } from "react-i18next";
import { Heading, Text } from "@vector-im/compound-web";
import { logger } from "matrix-js-sdk/src/logger";
import { Button } from "@vector-im/compound-web";
import { useNavigate } from "react-router-dom";
import {
createRoom,
@@ -46,7 +46,7 @@ export const RegisteredView: FC<Props> = ({ client }) => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error>();
const [optInAnalytics] = useOptInAnalytics();
const history = useHistory();
const navigate = useNavigate();
const { t } = useTranslation();
const [joinExistingCallModalOpen, setJoinExistingCallModalOpen] =
useState(false);
@@ -77,7 +77,7 @@ export const RegisteredView: FC<Props> = ({ client }) => {
if (!createRoomResult.password)
throw new Error("Failed to create room with shared secret");
history.push(
navigate(
getRelativeRoomUrl(
createRoomResult.roomId,
{ kind: E2eeType.SHARED_KEY, secret: createRoomResult.password },
@@ -99,15 +99,15 @@ export const RegisteredView: FC<Props> = ({ client }) => {
}
});
},
[client, history, setJoinExistingCallModalOpen],
[client, navigate, setJoinExistingCallModalOpen],
);
const recentRooms = useGroupCallRooms(client);
const [existingAlias, setExistingAlias] = useState<string>();
const onJoinExistingRoom = useCallback(() => {
history.push(`/${existingAlias}`);
}, [history, existingAlias]);
navigate(`/${existingAlias}`);
}, [navigate, existingAlias]);
return (
<>

View File

@@ -6,11 +6,11 @@ Please see LICENSE in the repository root for full details.
*/
import { type FC, useCallback, useState, type FormEventHandler } from "react";
import { useHistory } from "react-router-dom";
import { randomString } from "matrix-js-sdk/src/randomstring";
import { Trans, useTranslation } from "react-i18next";
import { Button, Heading, Text } from "@vector-im/compound-web";
import { logger } from "matrix-js-sdk/src/logger";
import { useNavigate } from "react-router-dom";
import { useClient } from "../ClientContext";
import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
@@ -50,7 +50,7 @@ export const UnauthenticatedView: FC = () => {
[setJoinExistingCallModalOpen],
);
const [onFinished, setOnFinished] = useState<() => void>();
const history = useHistory();
const navigate = useNavigate();
const { t } = useTranslation();
const onSubmit: FormEventHandler<HTMLFormElement> = useCallback(
@@ -91,7 +91,7 @@ export const UnauthenticatedView: FC = () => {
setOnFinished(() => {
setClient({ client, session });
const aliasLocalpart = roomAliasLocalpartFromRoomName(roomName);
history.push(`/${aliasLocalpart}`);
navigate(`/${aliasLocalpart}`);
});
setLoading(false);
@@ -110,7 +110,7 @@ export const UnauthenticatedView: FC = () => {
throw new Error("Failed to create room with shared secret");
setClient({ client, session });
history.push(
navigate(
getRelativeRoomUrl(
createRoomResult.roomId,
{ kind: E2eeType.SHARED_KEY, secret: createRoomResult.password },
@@ -130,7 +130,7 @@ export const UnauthenticatedView: FC = () => {
register,
reset,
execute,
history,
navigate,
setJoinExistingCallModalOpen,
setClient,
],

View File

@@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/
import React from "react";
import i18n, {
type BackendModule,
type ReadCallback,
@@ -16,6 +17,12 @@ import * as Sentry from "@sentry/react";
import { logger } from "matrix-js-sdk/src/logger";
import { shouldPolyfill as shouldPolyfillSegmenter } from "@formatjs/intl-segmenter/should-polyfill";
import { shouldPolyfill as shouldPolyfillDurationFormat } from "@formatjs/intl-durationformat/should-polyfill";
import {
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
} from "react-router-dom";
import { getUrlParams } from "./UrlParams";
import { Config } from "./config/Config";
@@ -217,7 +224,13 @@ export class Initializer {
dsn: Config.get().sentry?.DSN,
environment: Config.get().sentry?.environment,
integrations: [
Sentry.reactRouterV5BrowserTracingIntegration({ history }),
Sentry.reactRouterV6BrowserTracingIntegration({
useEffect: React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
],
tracesSampleRate: 1.0,
});

View File

@@ -13,7 +13,6 @@ import "matrix-js-sdk/src/browser-index";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { createBrowserHistory } from "history";
import "./index.css";
import { logger } from "matrix-js-sdk/src/logger";
import {
@@ -57,11 +56,9 @@ if (fatalError !== null) {
Initializer.initBeforeReact()
.then(() => {
const history = createBrowserHistory();
root.render(
<StrictMode>
<App history={history} />
<App />
</StrictMode>,
);
})

View File

@@ -14,8 +14,8 @@ import {
} from "react";
import { type MatrixClient } from "matrix-js-sdk/src/client";
import { Trans, useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
import { Button, Heading, Text } from "@vector-im/compound-web";
import { useNavigate } from "react-router-dom";
import styles from "./CallEndedView.module.css";
import feedbackStyle from "../input/FeedbackInput.module.css";
@@ -46,7 +46,7 @@ export const CallEndedView: FC<Props> = ({
reconnect,
}) => {
const { t } = useTranslation();
const history = useHistory();
const navigate = useNavigate();
const { displayName } = useProfile(client);
const [surveySubmitted, setSurveySubmitted] = useState(false);
@@ -76,12 +76,12 @@ export const CallEndedView: FC<Props> = ({
setSurveySubmitted(true);
} else if (!confineToRoom) {
// if the user already has an account immediately go back to the home screen
history.push("/");
navigate("/");
}
}, 1000);
}, 1000);
},
[endedCallId, history, isPasswordlessUser, confineToRoom, starRating],
[endedCallId, navigate, isPasswordlessUser, confineToRoom, starRating],
);
const createAccountDialog = isPasswordlessUser && (

View File

@@ -11,8 +11,7 @@ import { type MatrixClient } from "matrix-js-sdk/src/client";
import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc";
import { of } from "rxjs";
import { JoinRule, type RoomState } from "matrix-js-sdk/src/matrix";
import { Router } from "react-router-dom";
import { createBrowserHistory } from "history";
import { BrowserRouter } from "react-router-dom";
import userEvent from "@testing-library/user-event";
import { type RelationsContainer } from "matrix-js-sdk/src/models/relations-container";
@@ -78,7 +77,6 @@ function createGroupCallView(widget: WidgetHelpers | null): {
rtcSession: MockRTCSession;
getByText: ReturnType<typeof render>["getByText"];
} {
const history = createBrowserHistory();
const client = {
getUser: () => null,
getUserId: () => localRtcMember.sender,
@@ -111,7 +109,7 @@ function createGroupCallView(widget: WidgetHelpers | null): {
video: { enabled: false },
} as MuteStates;
const { getByText } = render(
<Router history={history}>
<BrowserRouter>
<GroupCallView
client={client}
isPasswordlessUser={false}
@@ -123,7 +121,7 @@ function createGroupCallView(widget: WidgetHelpers | null): {
muteStates={muteState}
widget={widget}
/>
</Router>,
</BrowserRouter>,
);
return {
getByText,

View File

@@ -13,7 +13,6 @@ import {
useRef,
useState,
} from "react";
import { useHistory } from "react-router-dom";
import { type MatrixClient } from "matrix-js-sdk/src/client";
import {
Room,
@@ -24,6 +23,7 @@ import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSess
import { JoinRule } from "matrix-js-sdk/src/matrix";
import { Heading, Text } from "@vector-im/compound-web";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import type { IWidgetApiRequest } from "matrix-widget-api";
import {
@@ -234,7 +234,7 @@ export const GroupCallView: FC<Props> = ({
const [left, setLeft] = useState(false);
const [leaveError, setLeaveError] = useState<Error | undefined>(undefined);
const history = useHistory();
const navigate = useNavigate();
const onLeave = useCallback(
(leaveError?: Error): void => {
@@ -263,7 +263,7 @@ export const GroupCallView: FC<Props> = ({
!confineToRoom &&
!PosthogAnalytics.instance.isEnabled()
) {
history.push("/");
navigate("/");
}
})
.catch((e) => {
@@ -276,7 +276,7 @@ export const GroupCallView: FC<Props> = ({
isPasswordlessUser,
confineToRoom,
leaveSoundContext,
history,
navigate,
],
);

View File

@@ -10,7 +10,6 @@ import { useTranslation } from "react-i18next";
import { type MatrixClient } from "matrix-js-sdk/src/matrix";
import { Button } from "@vector-im/compound-web";
import classNames from "classnames";
import { useHistory } from "react-router-dom";
import { logger } from "matrix-js-sdk/src/logger";
import { usePreviewTracks } from "@livekit/components-react";
import {
@@ -20,11 +19,11 @@ import {
} from "livekit-client";
import { useObservable } from "observable-hooks";
import { map } from "rxjs";
import { useNavigate } from "react-router-dom";
import inCallStyles from "./InCallView.module.css";
import styles from "./LobbyView.module.css";
import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header";
import { useLocationNavigation } from "../useLocationNavigation";
import { type MatrixInfo, VideoPreview } from "./VideoPreview";
import { type MuteStates } from "./MuteStates";
import { InviteButton } from "../button/InviteButton";
@@ -73,7 +72,6 @@ export const LobbyView: FC<Props> = ({
waitingForInvite,
}) => {
const { t } = useTranslation();
useLocationNavigation();
const onAudioPress = useCallback(
() => muteStates.audio.setEnabled?.((e) => !e),
@@ -96,8 +94,8 @@ export const LobbyView: FC<Props> = ({
[setSettingsModalOpen],
);
const history = useHistory();
const onLeaveClick = useCallback(() => history.push("/"), [history]);
const navigate = useNavigate();
const onLeaveClick = useCallback(() => navigate("/"), [navigate]);
const recentsButtonInFooter = useMediaQuery("(max-height: 500px)");
const recentsButton = !confineToRoom && (

View File

@@ -1,36 +0,0 @@
/*
Copyright 2022-2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/
import { useEffect } from "react";
import { useHistory } from "react-router-dom";
export function useLocationNavigation(enabled = false): void {
const history = useHistory();
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
let unblock = undefined;
if (enabled) {
unblock = history.block((tx) => {
const url = new URL(tx.pathname, window.location.href);
url.search = tx.search;
url.hash = tx.hash;
window.location.href = url.href;
});
}
return (): void => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (unblock) {
unblock();
}
};
}, [history, enabled]);
}

138
yarn.lock
View File

@@ -932,13 +932,6 @@
"@babel/plugin-transform-modules-commonjs" "^7.25.9"
"@babel/plugin-transform-typescript" "^7.25.9"
"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.13":
version "7.22.11"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.11.tgz#7a9ba3bbe406ad6f9e8dd4da2ece453eb23a77a4"
integrity sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.12.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.25.0", "@babel/runtime@^7.8.4":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
@@ -2593,6 +2586,11 @@
"@react-spring/shared" "~9.7.5"
"@react-spring/types" "~9.7.5"
"@remix-run/router@1.21.0":
version "1.21.0"
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5"
integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==
"@rollup/pluginutils@^5.1.0", "@rollup/pluginutils@^5.1.3":
version "5.1.3"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz#3001bf1a03f3ad24457591f2c259c8e514e0dbdf"
@@ -3137,11 +3135,6 @@
resolved "https://registry.yarnpkg.com/@types/grecaptcha/-/grecaptcha-3.0.9.tgz#9f3b07ec06c8fff221aa6fc124fe5b8a0e2c3349"
integrity sha512-fFxMtjAvXXMYTzDFK5NpcVB7WHnrHVLl00QzEGpuFxSAC789io6M+vjcn+g5FTEamIJtJr/IHkCDsqvJxeWDyw==
"@types/history@^4.7.11":
version "4.7.11"
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
"@types/jsdom@^21.1.7":
version "21.1.7"
resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-21.1.7.tgz#9edcb09e0b07ce876e7833922d3274149c898cfa"
@@ -3226,27 +3219,10 @@
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.5.tgz#45f9f87398c5dcea085b715c58ddcf1faf65f716"
integrity sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==
"@types/react-router-dom@^5.3.3":
version "5.3.3"
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83"
integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==
dependencies:
"@types/history" "^4.7.11"
"@types/react" "*"
"@types/react-router" "*"
"@types/react-router@*":
version "5.1.20"
resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c"
integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==
dependencies:
"@types/history" "^4.7.11"
"@types/react" "*"
"@types/react@*":
version "18.3.11"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.11.tgz#9d530601ff843ee0d7030d4227ea4360236bd537"
integrity sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==
"@types/react@^18.3.0":
version "18.3.17"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.17.tgz#d86ca0e081c7a5e979b7db175f9515a41038cea7"
integrity sha512-opAQ5no6LqJNo9TqnxBKsgnkIYHozW9KSTlFVoSUJYh1Fl/sswkEoqIugRSm7tbh6pABtYjGAjW+GOS23j8qbw==
dependencies:
"@types/prop-types" "*"
csstype "^3.0.2"
@@ -5667,19 +5643,7 @@ heimdalljs@^0.2.6:
dependencies:
rsvp "~3.2.1"
history@^4.0.0, history@^4.9.0:
version "4.10.1"
resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
dependencies:
"@babel/runtime" "^7.1.2"
loose-envify "^1.2.0"
resolve-pathname "^3.0.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
value-equal "^1.0.1"
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2:
hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -5774,14 +5738,7 @@ i18next-parser@^9.0.0:
vinyl "^3.0.0"
vinyl-fs "^4.0.0"
i18next@^23.0.0:
version "23.16.8"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.16.8.tgz#3ae1373d344c2393f465556f394aba5a9233b93a"
integrity sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==
dependencies:
"@babel/runtime" "^7.23.2"
"i18next@^23.5.1 || ^24.2.0":
"i18next@^23.5.1 || ^24.2.0", i18next@^24.0.0:
version "24.2.0"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-24.2.0.tgz#344c15a6f3b43d02aed78e2b08532e5b170951b4"
integrity sha512-ArJJTS1lV6lgKH7yEf4EpgNZ7+THl7bsGxxougPYiXRTJ/Fe1j08/TBpV9QsXCIYVfdE/HWG/xLezJ5DOlfBOA==
@@ -6092,11 +6049,6 @@ is-weakset@^2.0.3:
call-bound "^1.0.3"
get-intrinsic "^1.2.6"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
isarray@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
@@ -6414,7 +6366,7 @@ long@^5.0.0:
resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1"
integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==
loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -6935,13 +6887,6 @@ path-scurry@^1.11.1, path-scurry@^1.6.1:
lru-cache "^10.2.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-to-regexp@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
dependencies:
isarray "0.0.1"
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
@@ -7331,7 +7276,7 @@ prompts@~2.4.2:
kleur "^3.0.3"
sisteransi "^1.0.5"
prop-types@^15.6.2, prop-types@^15.8.1:
prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -7419,7 +7364,7 @@ react-i18next@^15.0.0:
"@babel/runtime" "^7.25.0"
html-parse-stringify "^3.0.1"
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -7453,33 +7398,20 @@ react-remove-scroll@^2.6.1:
use-callback-ref "^1.3.3"
use-sidecar "^1.1.2"
react-router-dom@^5.2.0:
version "5.3.4"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.4.tgz#2ed62ffd88cae6db134445f4a0c0ae8b91d2e5e6"
integrity sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==
react-router-dom@^6.28.0:
version "6.28.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.28.0.tgz#f73ebb3490e59ac9f299377062ad1d10a9f579e6"
integrity sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==
dependencies:
"@babel/runtime" "^7.12.13"
history "^4.9.0"
loose-envify "^1.3.1"
prop-types "^15.6.2"
react-router "5.3.4"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
"@remix-run/router" "1.21.0"
react-router "6.28.0"
react-router@5.3.4:
version "5.3.4"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.4.tgz#8ca252d70fcc37841e31473c7a151cf777887bb5"
integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==
react-router@6.28.0:
version "6.28.0"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.28.0.tgz#29247c86d7ba901d7e5a13aa79a96723c3e59d0d"
integrity sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==
dependencies:
"@babel/runtime" "^7.12.13"
history "^4.9.0"
hoist-non-react-statics "^3.1.0"
loose-envify "^1.3.1"
path-to-regexp "^1.7.0"
prop-types "^15.6.2"
react-is "^16.6.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
"@remix-run/router" "1.21.0"
react-style-singleton@^2.2.1, react-style-singleton@^2.2.2:
version "2.2.3"
@@ -7706,11 +7638,6 @@ resolve-options@^2.0.0:
dependencies:
value-or-function "^4.0.0"
resolve-pathname@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.22.4:
version "1.22.8"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
@@ -8379,16 +8306,6 @@ through2@^2.0.1:
readable-stream "~2.3.6"
xtend "~4.0.1"
tiny-invariant@^1.0.2:
version "1.3.1"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==
tiny-warning@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tinybench@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b"
@@ -8769,11 +8686,6 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
value-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
value-or-function@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-4.0.0.tgz#70836b6a876a010dc3a2b884e7902e9db064378d"