Compare commits

14 Commits

Author SHA1 Message Date
Borislav Pantaleev
7c21692a1e Add server status page and a badge in AppBar (#182)
* WIP: Add server status and running process indicators

* Finish ServerStatusPage and ServerRunningProcess

* fix typos, add running process info to the server status page

* Remove ServerRunningProcess and integrate it into ServerStatusBadge

* remove divider in menu

* display time as started X minutes ago

* add documentation; clearly state what new components are; update readme

* change wording a bit, cross-link with docs/README.md

* use returned HTML

* Finish ServerStatus page and badges

* Fix types

* cleanup

* remove some code

* adjust config load
2024-12-04 00:14:29 +02:00
dependabot[bot]
3b69e78bb8 Bump eslint from 9.15.0 to 9.16.0 (#193)
Bumps [eslint](https://github.com/eslint/eslint) from 9.15.0 to 9.16.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.15.0...v9.16.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:30:24 +02:00
dependabot[bot]
a6caa0714e Bump prettier from 3.3.3 to 3.4.1 (#191)
Bumps [prettier](https://github.com/prettier/prettier) from 3.3.3 to 3.4.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.3...3.4.1)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:30:10 +02:00
dependabot[bot]
83473dd3fa Bump @mui/utils from 5.16.6 to 5.16.8 (#185)
Bumps [@mui/utils](https://github.com/mui/material-ui/tree/HEAD/packages/mui-utils) from 5.16.6 to 5.16.8.
- [Release notes](https://github.com/mui/material-ui/releases)
- [Changelog](https://github.com/mui/material-ui/blob/v5.16.8/CHANGELOG.md)
- [Commits](https://github.com/mui/material-ui/commits/v5.16.8/packages/mui-utils)

---
updated-dependencies:
- dependency-name: "@mui/utils"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:29:56 +02:00
dependabot[bot]
aad90760a5 Bump @types/node from 22.9.3 to 22.10.1 (#189)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.9.3 to 22.10.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:21:02 +02:00
dependabot[bot]
cb853bf342 Bump @vitejs/plugin-react from 4.3.3 to 4.3.4 (#188)
Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 4.3.3 to 4.3.4.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/v4.3.4/packages/plugin-react)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:20:47 +02:00
dependabot[bot]
8d45ae2886 Bump @tanstack/react-query from 5.61.3 to 5.62.0 (#187)
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.61.3 to 5.62.0.
- [Release notes](https://github.com/TanStack/query/releases)
- [Commits](https://github.com/TanStack/query/commits/v5.62.0/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:20:31 +02:00
dependabot[bot]
2e151cf198 Bump vite-plugin-version-mark from 0.1.2 to 0.1.3 (#186)
Bumps [vite-plugin-version-mark](https://github.com/ZhongxuYang/vite-plugin-version-mark) from 0.1.2 to 0.1.3.
- [Release notes](https://github.com/ZhongxuYang/vite-plugin-version-mark/releases)
- [Changelog](https://github.com/ZhongxuYang/vite-plugin-version-mark/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ZhongxuYang/vite-plugin-version-mark/compare/v0.1.2...v0.1.3)

---
updated-dependencies:
- dependency-name: vite-plugin-version-mark
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:20:16 +02:00
dependabot[bot]
52c17bc5ca Bump @mui/material from 6.1.8 to 6.1.9 (#184)
Bumps [@mui/material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-material) from 6.1.8 to 6.1.9.
- [Release notes](https://github.com/mui/material-ui/releases)
- [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mui/material-ui/commits/v6.1.9/packages/mui-material)

---
updated-dependencies:
- dependency-name: "@mui/material"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:19:57 +02:00
dependabot[bot]
d79d825ab4 Bump typescript-eslint from 8.15.0 to 8.16.0 (#183)
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.15.0 to 8.16.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.16.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 10:19:42 +02:00
Aine
28b80d7fa2 Show 50 elements by default in the list of each resource 2024-11-30 21:49:05 +02:00
Aine
9735ffbc19 fix readme link 2024-11-30 17:05:29 +02:00
Aine
f4d0e19d21 Allow prefilling of any fields of the login form using GET params (#181)
* Allow prefilling of any fields of the login form using GET params

* update readme
2024-11-29 19:17:52 +02:00
Aine
14d1c904c0 add docs/README.md 2024-11-29 16:58:30 +02:00
22 changed files with 808 additions and 286 deletions

View File

@@ -100,6 +100,9 @@ The following changes are already implemented:
* 🔰 [Add "Assign Admin" button to the rooms](https://github.com/etkecc/synapse-admin/pull/156)
* 🖼️ [Add rooms' avatars](https://github.com/etkecc/synapse-admin/pull/158)
* 🤖 [User Badges](https://github.com/etkecc/synapse-admin/pull/160)
* 🔑 [Allow prefilling any fields on the login form via GET params](https://github.com/etkecc/synapse-admin/pull/181)
* _(for [etke.cc](https://etke.cc) customers only)_ [Server Status indicator and page](https://github.com/etkecc/synapse-admin/pull/182)
_the list will be updated as new changes are added_
@@ -111,7 +114,8 @@ _the list will be updated as new changes are added_
This command initializes the development environment (local Synapse server and Postgres DB),
and launches the app in a dev mode at `http://localhost:5173`
After that open `http://localhost:5173` in your browser, login using the following credentials:
After that open [http://localhost:5173](http://localhost:5173?username=admin&password=admin&server=http://localhost:8008) in your browser,
login using the following credentials:
* Login: admin
* Password: admin
@@ -148,13 +152,9 @@ services:
### Prefilling login form
You can prefill `username` and `homeserver` fields on the login page using GET parameters, example:
You can prefill all fields on the login page using GET parameters.
```
https://matrix.example.com/synapse-admin/?username=admin&server=matrix.example.com
```
That way `username` and `homeserver` fields will be pre-filled with `admin` and `https://matrix.example.com` respectively.
[Documentation](./docs/prefill-login-form.md)
### Restricting available homeserver

39
docs/README.md Normal file
View File

@@ -0,0 +1,39 @@
# Documentation
Synapse Admin documentation is under construction right now, so PRs are greatly appreciated!
Table of contents:
<!-- vim-markdown-toc GFM -->
* [Configuration](#configuration)
* [Features](#features)
* [Deployment](#deployment)
<!-- vim-markdown-toc -->
## Configuration
[Full configuration documentation](./config.md)
Specific configuration options:
* [Restricting available homeserver](./restrict-hs.md)
* [System / Appservice-managed Users](./system-users.md)
* [Custom Menu Items](./custom-menu.md)
## Features
* [User Badges](./user-badges.md)
* [Prefilling the Login Form](./prefill-login-form.md)
for [etke.cc](https://etke.cc) customers only:
> **Note:** The following features are only available for etke.cc customers. Due to specifics of the implementation,
they are not available for any other Synapse Admin deployments.
* [Server Status icon](../src/components/etke.cc/README.md#server-status-icon)
* [Server Status page](../src/components/etke.cc/README.md#server-status-page)
## Deployment
* [Serving Synapse Admin behind a reverse proxy](./reverse-proxy.md)

View File

@@ -0,0 +1,48 @@
# Prefilling the Login Form
In some cases you may wish to prefill/preset the login form fields when sharing a link to a Synapse Admin instance.
This can be done by adding the following query parameters to the URL:
* `username` - The username to prefill in the username field.
* `server` - The server to prefill in the homeserver url field.
The following query params will work only if the Synapse Admin is loaded from `localhost` or `127.0.0.1`:
* `password` - The password to prefill in the password field (credentials auth). **NEVER** use this in production.
* `accessToken` - The access token to prefill in the access token field (access token auth). **NEVER** use this in production.
> **WARNING**: Never use the `password` or `accessToken` query parameters in production as they can be easily extracted
from the URL. These are only meant for development purposes and local environments.
## Examples
### Production
```bash
https://admin.etke.cc?username=admin&server=https://matrix.example.com
```
This will open `Credentials` (username/password) login form with the username field prefilled with `admin` and the
Homeserver URL field prefilled with `https://matrix.example.com`.
### Development and Local environments
**With Password**
```bash
http://localhost:8080?username=admin&server=https://matrix.example.com&password=secret
```
This will open `Credentials` (username/password) login form with the username field prefilled with `admin`, the
Homeserver URL field prefilled with `https://matrix.example.com` and the password field prefilled with `secret`.
**With Access Token**
```bash
http://localhost:8080?server=https://matrix.example.com&accessToken=secret
```
This will open `Access Token` login form with the Homeserver URL field prefilled with `https://matrix.example.com` and
the access token field prefilled with `secret`.

View File

@@ -18,13 +18,13 @@
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.14",
"@types/lodash": "^4.17.13",
"@types/node": "^22.9.3",
"@types/node": "^22.10.1",
"@types/papaparse": "^5.3.15",
"@types/react": "^18.3.12",
"@typescript-eslint/eslint-plugin": "^8.14.0",
"@typescript-eslint/parser": "^8.15.0",
"@vitejs/plugin-react": "^4.3.3",
"eslint": "^9.15.0",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.16.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
@@ -34,14 +34,14 @@
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-fetch-mock": "^3.0.3",
"prettier": "^3.3.3",
"prettier": "^3.4.1",
"react-test-renderer": "^18.3.1",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.7.2",
"typescript-eslint": "^8.15.0",
"typescript-eslint": "^8.16.0",
"vite": "^5.4.11",
"vite-plugin-version-mark": "^0.1.2"
"vite-plugin-version-mark": "^0.1.3"
},
"dependencies": {
"@emotion/react": "^11.13.5",
@@ -49,9 +49,9 @@
"@haleos/ra-language-german": "^1.0.0",
"@haxqer/ra-language-chinese": "^4.16.2",
"@mui/icons-material": "^6.1.8",
"@mui/material": "^6.1.8",
"@mui/utils": "^5.16.6",
"@tanstack/react-query": "^5.61.3",
"@mui/material": "^6.1.9",
"@mui/utils": "^5.16.8",
"@tanstack/react-query": "^5.62.0",
"history": "^5.3.0",
"lodash": "^4.17.21",
"papaparse": "^5.4.1",

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -22,9 +22,10 @@ import rooms from "./resources/rooms";
import userMediaStats from "./resources/user_media_statistics";
import users from "./resources/users";
import authProvider from "./synapse/authProvider";
import dataProvider from "./synapse/dataProvider";
import dataProvider, { ServerStatusResponse } from "./synapse/dataProvider";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Config } from "./utils/config";
import ServerStatusPage from "./components/etke.cc/ServerStatusPage";
// TODO: Can we use lazy loading together with browser locale?
const messages = {
@@ -64,6 +65,7 @@ export const App = () => (
>
<CustomRoutes>
<Route path="/import_users" element={<UserImport />} />
<Route path="/server_status" element={<ServerStatusPage />} />
</CustomRoutes>
<Resource {...users} />
<Resource {...rooms} />

View File

@@ -4,6 +4,7 @@ import { useEffect, useState, Suspense } from "react";
import { Icons, DefaultIcon } from "../utils/icons";
import { MenuItem, GetConfig, ClearConfig } from "../utils/config";
import Footer from "./Footer";
import ServerStatusBadge from "./etke.cc/ServerStatusBadge";
const AdminUserMenu = () => {
const [open, setOpen] = useState(false);
@@ -48,6 +49,7 @@ const AdminUserMenu = () => {
const AdminAppBar = () => {
return (<AppBar userMenu={<AdminUserMenu />}>
<TitlePortal />
<ServerStatusBadge />
<InspectorButton />
</AppBar>);
};

View File

@@ -0,0 +1,30 @@
# etke.cc-specific components
This directory contains [etke.cc](https://etke.cc)-specific components, unusable for any other purposes and/or configuration.
We at [etke.cc](https://etke.cc) attempting to develop everything open-source, but some things are too specific to be used by anyone else. This directory contains such components - they are only available for [etke.cc](https://etke.cc) customers.
Due to the specifics mentioned above, these components are documented here rather than in the [docs](../../../docs/README.md), plus they are not supported as part of the Synapse Admin open-source project (i.e.: no issues, no PRs, no support, no requests, etc.).
## Components
### Server Status icon
![Server Status icon](../../../screenshots/etke.cc/server-status/indicator.webp)
In the application bar the new monitoring icon is displayed that shows the current server status, and has the following color dot (and tooltip indicators):
* 🟢 (green) - the server is up and running, everything is fine, no issues detected
* 🟡 (yellow) - the server is up and running, but there is a command in progress (likely [maintenance](https://etke.cc/help/extras/scheduler/#maintenance)), so some temporary issues may occur - that's totally fine
* 🔴 (red) - there is at least 1 issue with one of the server's components
### Server Status page
![Server Status Page](../../../screenshots/etke.cc/server-status/page.webp)
When you click on the [Server Status icon](#server-status-icon) in the application bar, you will be redirected to the
Server Status page. This page contains the following information:
* Overall server status (up/updating/has issues)
* Details about the currently running command (if any)
* Details about the server's components statuses (up/down with error details and suggested actions) by categories

View File

@@ -0,0 +1,169 @@
import { Avatar, Badge, Theme, Tooltip } from "@mui/material";
import { useEffect } from "react";
import { useAppContext } from "../../App";
import { Button, useDataProvider, useStore } from "react-admin";
import { styled } from '@mui/material/styles';
import MonitorHeartIcon from '@mui/icons-material/MonitorHeart';
import { BadgeProps } from "@mui/material/Badge";
import { useNavigate } from "react-router";
import { useTheme } from "@mui/material/styles";
import { ServerProcessResponse, ServerStatusResponse } from "../../synapse/dataProvider";
interface StyledBadgeProps extends BadgeProps {
backgroundColor: string;
badgeColor: string
theme?: Theme;
}
const StyledBadge = styled(Badge, { shouldForwardProp: (prop) => !['badgeColor', 'backgroundColor'].includes(prop as string) })<StyledBadgeProps>
(({ theme, backgroundColor, badgeColor }) => ({
'& .MuiBadge-badge': {
backgroundColor: backgroundColor,
color: badgeColor,
boxShadow: `0 0 0 2px ${theme.palette.background.paper}`,
'&::after': {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
borderRadius: '50%',
animation: 'ripple 2.5s infinite ease-in-out',
border: '1px solid currentColor',
content: '""',
},
},
'@keyframes ripple': {
'0%': {
transform: 'scale(.8)',
opacity: 1,
},
'100%': {
transform: 'scale(2.4)',
opacity: 0,
},
},
}));
// every 5 minutes
const SERVER_STATUS_INTERVAL_TIME = 5 * 60 * 1000;
// every 5 seconds
const SERVER_CURRENT_PROCCESS_INTERVAL_TIME = 5 * 1000;
const useServerStatus = () => {
const [serverStatus, setServerStatus] = useStore<ServerStatusResponse>("serverStatus", { ok: false, success: false, host: "", results: [] });
const { etkeccAdmin } = useAppContext();
const dataProvider = useDataProvider();
const isOkay = serverStatus.ok;
const successCheck = serverStatus.success;
const checkServerStatus = async () => {
const serverStatus: ServerStatusResponse = await dataProvider.getServerStatus(etkeccAdmin);
setServerStatus({
ok: serverStatus.ok,
success: serverStatus.success,
host: serverStatus.host,
results: serverStatus.results,
});
};
useEffect(() => {
let serverStatusInterval: NodeJS.Timeout;
if (etkeccAdmin) {
checkServerStatus();
setTimeout(() => {
// start the interval after 10 seconds to avoid too many requests
serverStatusInterval = setInterval(checkServerStatus, SERVER_STATUS_INTERVAL_TIME);
}, 10000);
} else {
setServerStatus({ ok: false, success: false, host: "", results: [] });
}
return () => {
if (serverStatusInterval) {
clearInterval(serverStatusInterval);
}
}
}, [etkeccAdmin]);
return { isOkay, successCheck };
};
const useCurrentServerProcess = () => {
const [serverProcess, setServerProcess] = useStore<ServerProcessResponse>("serverProcess", { command: "", locked_at: "" });
const { etkeccAdmin } = useAppContext();
const dataProvider = useDataProvider();
const { command, locked_at } = serverProcess;
const checkServerRunningProcess = async () => {
const serverProcess: ServerProcessResponse = await dataProvider.getServerRunningProcess(etkeccAdmin);
setServerProcess({
...serverProcess,
command: serverProcess.command,
locked_at: serverProcess.locked_at
});
}
useEffect(() => {
let serverCheckInterval: NodeJS.Timeout;
if (etkeccAdmin) {
checkServerRunningProcess();
setTimeout(() => {
serverCheckInterval = setInterval(checkServerRunningProcess, SERVER_CURRENT_PROCCESS_INTERVAL_TIME);
}, 5000);
} else {
setServerProcess({ command: "", locked_at: "" });
}
return () => {
if (serverCheckInterval) {
clearInterval(serverCheckInterval);
}
}
}, [etkeccAdmin]);
return { command, locked_at };
};
const ServerStatusBadge = () => {
const { isOkay, successCheck } = useServerStatus();
const { command, locked_at } = useCurrentServerProcess();
const theme = useTheme();
const navigate = useNavigate();
if (!successCheck) {
return null;
}
const handleServerStatusClick = () => {
navigate("/server_status");
};
let tooltipText = "Click to view Server Status";
let badgeBackgroundColor = isOkay ? theme.palette.success.light : theme.palette.error.main;
let badgeColor = isOkay ? theme.palette.success.light : theme.palette.error.main;
if (command && locked_at) {
badgeBackgroundColor = theme.palette.warning.main;
badgeColor = theme.palette.warning.main;
tooltipText = `Running: ${command}; ${tooltipText}`;
}
return <Button onClick={handleServerStatusClick} size="medium" sx={{ minWidth: "auto", ".MuiButton-startIcon": { m: 0 }}}>
<Tooltip title={tooltipText} sx={{ cursor: "pointer" }}>
<StyledBadge
overlap="circular"
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
variant="dot"
backgroundColor={badgeBackgroundColor}
badgeColor={badgeColor}
>
<Avatar sx={{ height: 24, width: 24, background: theme.palette.mode === "dark" ? theme.palette.background.default : "#2196f3" }}>
<MonitorHeartIcon sx={{ height: 22, width: 22, color: theme.palette.common.white }} />
</Avatar>
</StyledBadge>
</Tooltip>
</Button>
};
export default ServerStatusBadge;

View File

@@ -0,0 +1,144 @@
import { useStore } from "ra-core";
import { Box, Stack, Typography, Paper, Link, Chip, Divider, Tooltip, ChipProps } from "@mui/material";
import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from "@mui/icons-material/Close";
import EngineeringIcon from '@mui/icons-material/Engineering';
import { ServerProcessResponse, ServerStatusComponent, ServerStatusResponse } from "../../synapse/dataProvider";
const getTimeSince = (date: string) => {
const now = new Date();
const past = new Date(date);
const diffInMinutes = Math.floor((now.getTime() - past.getTime()) / (1000 * 60));
if (diffInMinutes < 1) return "a couple of seconds";
if (diffInMinutes === 1) return "1 minute";
return `${diffInMinutes} minutes`;
};
const StatusChip = ({ isOkay, size = "medium", command }: { isOkay: boolean, size?: "small" | "medium", command?: string }) => {
let label = "OK";
let icon = <CheckIcon />;
let color: ChipProps["color"] = "success";
if (!isOkay) {
label = "Error";
icon = <CloseIcon />;
color = "error";
}
if (command) {
label = command;
color = "warning";
icon = <EngineeringIcon />;
}
return (
<Chip icon={icon} label={label} color={color} variant="outlined" size={size} />
);
};
const ServerComponentText = ({ text }: { text: string }) => {
return <Typography variant="body1" dangerouslySetInnerHTML={{ __html: text }} />;
};
const ServerStatusPage = () => {
const [serverStatus, setServerStatus] = useStore<ServerStatusResponse>("serverStatus", {
ok: false,
success: false,
host: "",
results: [],
});
const [ serverProcess, setServerProcess ] = useStore<ServerProcessResponse>("serverProcess", { command: "", locked_at: "" });
const { command, locked_at } = serverProcess;
const successCheck = serverStatus.success;
const isOkay = serverStatus.ok;
const host = serverStatus.host;
const results = serverStatus.results;
let groupedResults: Record<string, ServerStatusComponent[]> = {};
for (const result of results) {
if (!groupedResults[result.category]) {
groupedResults[result.category] = [];
}
groupedResults[result.category].push(result);
}
if (!successCheck) {
return (
<Paper elevation={3} sx={{ p: 3, mt: 3 }}>
<Stack direction="row" spacing={2} alignItems="center">
<CloseIcon color="error" />
<Typography color="error">
Unable to fetch server status. Please try again later.
</Typography>
</Stack>
</Paper>
);
}
return (
<Stack spacing={3} mt={3}>
<Stack spacing={1} direction="row" alignItems="center">
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Typography variant="h4">Status:</Typography>
<StatusChip isOkay={isOkay} command={command} />
</Box>
<Typography variant="h5" color="primary" fontWeight="medium">
{host}
</Typography>
</Stack>
{command && locked_at && (
<Stack spacing={1} direction="row" alignItems="center">
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Typography variant="h5">Currently running:</Typography>
<Typography variant="h5" color="text.secondary">
<Link href={"https://etke.cc/help/extras/scheduler/#"+command} target="_blank">
{command}
</Link>
<Tooltip title={locked_at.toString()}>
<Typography component="span" color="text.secondary" sx={{ display: "inline-block", ml: 1 }}>(started {getTimeSince(locked_at)} ago)</Typography>
</Tooltip>
</Typography>
</Box>
</Stack>
)}
<Stack spacing={2} direction="row">
{Object.keys(groupedResults).map((category, idx) => (
<Box key={`category_${category}`} sx={{ flex: 1 }}>
<Typography variant="h5" mb={1}>
{category}
</Typography>
<Paper elevation={2} sx={{ p: 3 }}>
<Stack spacing={1} divider={<Divider />}>
{groupedResults[category].map((result, idx) => (
<Box key={`${category}_${idx}`}>
<Stack spacing={2}>
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<StatusChip isOkay={result.ok} size="small" />
{result.label.url ? (
<Link href={result.label.url} target="_blank" rel="noopener noreferrer">
<ServerComponentText text={result.label.text} />
</Link>
) : (
<ServerComponentText text={result.label.text} />
)}
</Box>
{result.reason && <Typography color="text.secondary" dangerouslySetInnerHTML={{ __html: result.reason }}/>}
{(!result.ok && result.help) && (
<Link href={result.help} target="_blank" rel="noopener noreferrer" sx={{ mt: 1 }}>
Learn more
</Link>
)}
</Stack>
</Box>
))}
</Stack>
</Paper>
</Box>
))}
</Stack>
</Stack>
);
};
export default ServerStatusPage;

View File

@@ -171,11 +171,24 @@ const LoginPage = () => {
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const hostname = window.location.hostname;
const username = params.get("username");
const password = params.get("password");
const accessToken = params.get("accessToken");
let serverURL = params.get("server");
if (username) {
form.setValue("username", username);
}
if (hostname === "localhost" || hostname === "127.0.0.1") {
if (password) {
form.setValue("password", password);
}
if (accessToken) {
setLoginMethod("accessToken");
form.setValue("accessToken", accessToken);
}
}
if (serverURL) {
const isFullUrl = serverURL.match(/^(http|https):\/\//);
if (!isFullUrl) {

View File

@@ -123,6 +123,7 @@ export const DestinationList = (props: ListProps) => {
filters={destinationFilters}
pagination={<DestinationPagination />}
sort={{ field: "destination", order: "ASC" }}
perPage={50}
>
<DatagridConfigurable rowClick={id => `${id}/show/rooms`} bulkActionButtons={false}>
<FunctionField source="destination" render={destinationFieldRender} label="resources.destinations.fields.destination" />

View File

@@ -38,7 +38,7 @@ export const RegistrationTokenList = (props: ListProps) => (
filters={registrationTokenFilters}
filterDefaultValues={{ valid: true }}
pagination={false}
perPage={500}
perPage={50}
>
<DatagridConfigurable rowClick="edit">
<TextField source="token" sortable={false} label="resources.registration_tokens.fields.token"/>

View File

@@ -90,7 +90,7 @@ const ReportShowActions = () => {
};
export const ReportList = (props: ListProps) => (
<List {...props} pagination={<ReportPagination />} sort={{ field: "received_ts", order: "DESC" }}>
<List {...props} pagination={<ReportPagination />} perPage={50} sort={{ field: "received_ts", order: "DESC" }}>
<DatagridConfigurable rowClick="show" bulkActionButtons={false}>
<TextField source="id" sortable={false} label="resources.reports.fields.id" />
<DateField source="received_ts" showTime options={DATE_FORMAT} sortable={true} label="resources.reports.fields.received_ts" />

View File

@@ -135,7 +135,7 @@ const RoomDirectoryListActions = () => (
);
export const RoomDirectoryList = () => (
<List pagination={<RoomDirectoryPagination />} perPage={100} actions={<RoomDirectoryListActions />}>
<List pagination={<RoomDirectoryPagination />} perPage={50} actions={<RoomDirectoryListActions />}>
<DatagridConfigurable
rowClick={id => "/rooms/" + id + "/show"}
bulkActionButtons={<RoomDirectoryBulkUnpublishButton />}

View File

@@ -352,6 +352,7 @@ export const RoomList = (props: ListProps) => {
sort={{ field: "name", order: "ASC" }}
filters={roomFilters}
actions={<RoomListActions />}
perPage={50}
>
<DatagridConfigurable
rowClick="show"

View File

@@ -37,6 +37,7 @@ export const UserMediaStatsList = (props: ListProps) => (
filters={userMediaStatsFilters}
pagination={<UserMediaStatsPagination />}
sort={{ field: "media_length", order: "DESC" }}
perPage={50}
>
<DatagridConfigurable rowClick={id => "/users/" + id + "/media"} bulkActionButtons={false}>
<TextField source="user_id" label="resources.users.fields.id" />

View File

@@ -166,6 +166,7 @@ export const UserList = (props: ListProps) => (
sort={{ field: "name", order: "ASC" }}
actions={<UserListActions />}
pagination={<UserPagination />}
perPage={50}
>
<DatagridConfigurable
rowClick={(id: Identifier, resource: string) => `/${resource}/${id}`}

View File

@@ -265,6 +265,31 @@ export interface UsernameAvailabilityResult {
errcode?: string;
}
export interface ServerStatusComponent {
ok: boolean;
category: string;
reason: string;
url: string;
help: string;
label: {
url: string;
icon: string;
text: string;
}
}
export interface ServerStatusResponse {
success: boolean;
ok: boolean;
host: string;
results: ServerStatusComponent[];
}
export interface ServerProcessResponse {
locked_at?: string;
command?: string;
}
export interface SynapseDataProvider extends DataProvider {
deleteMedia: (params: DeleteMediaParams) => Promise<DeleteMediaResult>;
uploadMedia: (params: UploadMediaParams) => Promise<UploadMediaResult>;
@@ -273,6 +298,8 @@ export interface SynapseDataProvider extends DataProvider {
setRateLimits: (id: Identifier, rateLimits: RateLimitsModel) => Promise<void>;
checkUsernameAvailability: (username: string) => Promise<UsernameAvailabilityResult>;
makeRoomAdmin: (room_id: string, user_id: string) => Promise<{ success: boolean; error?: string; errcode?: string }>;
getServerRunningProcess: (etkeAdminUrl: string) => Promise<ServerProcessResponse>;
getServerStatus: (etkeAdminUrl: string) => Promise<ServerStatusResponse>;
}
const resourceMap = {
@@ -880,6 +907,60 @@ const baseDataProvider: SynapseDataProvider = {
}
throw error;
}
},
getServerRunningProcess: async (runningProcessUrl: string): Promise<ServerProcessResponse> => {
const locked_at = "";
const command = "";
try {
const response = await fetch(`${runningProcessUrl}/lock`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
}
});
if (!response.ok) {
console.error(`Error getting server running process: ${response.status} ${response.statusText}`);
return { locked_at, command };
}
const status = response.status;
if (status === 200) {
const json = await response.json();
return json as { locked_at: string; command: string };
}
if (status === 204) {
return { locked_at, command };
}
} catch (error) {
console.error("Error getting server running process", error);
}
return { locked_at, command };
},
getServerStatus: async (serverStatusUrl: string): Promise<ServerStatusResponse> => {
try {
const response = await fetch(`${serverStatusUrl}/status`, {
headers: {
"Authorization": `Bearer ${localStorage.getItem("access_token")}`
}
});
if (!response.ok) {
console.error(`Error getting server status: ${response.status} ${response.statusText}`);
return { success: false, ok: false, host: "", results: [] };
}
const status = response.status;
if (status === 200) {
const json = await response.json();
const result = { success: true, ...json } as ServerStatusResponse;
return result;
}
} catch (error) {
console.error("Error getting server status", error);
}
return { success: false, ok: false, host: "", results: [] };
}
};

View File

@@ -2,6 +2,7 @@ export interface Config {
restrictBaseUrl: string | string[];
asManagedUsers: RegExp[];
menu: MenuItem[];
etkeccAdmin?: string;
}
export interface MenuItem {
@@ -17,6 +18,7 @@ let config: Config = {
restrictBaseUrl: "",
asManagedUsers: [],
menu: [],
etkeccAdmin: ""
};
export const FetchConfig = async () => {
@@ -49,6 +51,8 @@ export const FetchConfig = async () => {
}
// load config from context
// we deliberately processing each key separately to avoid overwriting the whole config, loosing some keys, and messing
// with typescript types
export const LoadConfig = (context: any) => {
if (context?.restrictBaseUrl) {
config.restrictBaseUrl = context.restrictBaseUrl as string | string[];
@@ -65,6 +69,10 @@ export const LoadConfig = (context: any) => {
if (menu.length > 0) {
config.menu = menu;
}
if (context?.etkeccAdmin) {
config.etkeccAdmin = context.etkeccAdmin;
}
}
// get config

508
yarn.lock
View File

@@ -23,34 +23,35 @@
"@babel/highlight" "^7.24.7"
picocolors "^1.0.0"
"@babel/code-frame@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7"
integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==
"@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
dependencies:
"@babel/highlight" "^7.25.7"
"@babel/helper-validator-identifier" "^7.25.9"
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/compat-data@^7.25.7":
version "7.25.8"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.8.tgz#0376e83df5ab0eb0da18885c0140041f0747a402"
integrity sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==
"@babel/compat-data@^7.25.9":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e"
integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==
"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.25.2":
version "7.25.8"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.8.tgz#a57137d2a51bbcffcfaeba43cb4dd33ae3e0e1c6"
integrity sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==
"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.26.0":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40"
integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==
dependencies:
"@ampproject/remapping" "^2.2.0"
"@babel/code-frame" "^7.25.7"
"@babel/generator" "^7.25.7"
"@babel/helper-compilation-targets" "^7.25.7"
"@babel/helper-module-transforms" "^7.25.7"
"@babel/helpers" "^7.25.7"
"@babel/parser" "^7.25.8"
"@babel/template" "^7.25.7"
"@babel/traverse" "^7.25.7"
"@babel/types" "^7.25.8"
"@babel/code-frame" "^7.26.0"
"@babel/generator" "^7.26.0"
"@babel/helper-compilation-targets" "^7.25.9"
"@babel/helper-module-transforms" "^7.26.0"
"@babel/helpers" "^7.26.0"
"@babel/parser" "^7.26.0"
"@babel/template" "^7.25.9"
"@babel/traverse" "^7.25.9"
"@babel/types" "^7.26.0"
convert-source-map "^2.0.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
@@ -67,23 +68,24 @@
"@jridgewell/trace-mapping" "^0.3.25"
jsesc "^2.5.1"
"@babel/generator@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56"
integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==
"@babel/generator@^7.25.9", "@babel/generator@^7.26.0":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f"
integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==
dependencies:
"@babel/types" "^7.25.7"
"@babel/parser" "^7.26.2"
"@babel/types" "^7.26.0"
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.25"
jsesc "^3.0.2"
"@babel/helper-compilation-targets@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz#11260ac3322dda0ef53edfae6e97b961449f5fa4"
integrity sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==
"@babel/helper-compilation-targets@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875"
integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==
dependencies:
"@babel/compat-data" "^7.25.7"
"@babel/helper-validator-option" "^7.25.7"
"@babel/compat-data" "^7.25.9"
"@babel/helper-validator-option" "^7.25.9"
browserslist "^4.24.0"
lru-cache "^5.1.1"
semver "^6.3.1"
@@ -96,74 +98,65 @@
"@babel/traverse" "^7.24.7"
"@babel/types" "^7.24.7"
"@babel/helper-module-imports@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472"
integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==
"@babel/helper-module-imports@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715"
integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==
dependencies:
"@babel/traverse" "^7.25.7"
"@babel/types" "^7.25.7"
"@babel/traverse" "^7.25.9"
"@babel/types" "^7.25.9"
"@babel/helper-module-transforms@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz#2ac9372c5e001b19bc62f1fe7d96a18cb0901d1a"
integrity sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==
"@babel/helper-module-transforms@^7.26.0":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae"
integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==
dependencies:
"@babel/helper-module-imports" "^7.25.7"
"@babel/helper-simple-access" "^7.25.7"
"@babel/helper-validator-identifier" "^7.25.7"
"@babel/traverse" "^7.25.7"
"@babel/helper-module-imports" "^7.25.9"
"@babel/helper-validator-identifier" "^7.25.9"
"@babel/traverse" "^7.25.9"
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.8.0":
version "7.24.8"
resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz"
integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==
"@babel/helper-plugin-utils@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c"
integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==
"@babel/helper-simple-access@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz#5eb9f6a60c5d6b2e0f76057004f8dacbddfae1c0"
integrity sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==
dependencies:
"@babel/traverse" "^7.25.7"
"@babel/types" "^7.25.7"
"@babel/helper-plugin-utils@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46"
integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==
"@babel/helper-string-parser@^7.24.8":
version "7.24.8"
resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz"
integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==
"@babel/helper-string-parser@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54"
integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==
"@babel/helper-string-parser@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
"@babel/helper-validator-identifier@^7.24.7":
version "7.24.7"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz"
integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==
"@babel/helper-validator-identifier@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5"
integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==
"@babel/helper-validator-identifier@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7"
integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
"@babel/helper-validator-option@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz#97d1d684448228b30b506d90cace495d6f492729"
integrity sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==
"@babel/helper-validator-option@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72"
integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==
"@babel/helpers@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.7.tgz#091b52cb697a171fe0136ab62e54e407211f09c2"
integrity sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==
"@babel/helpers@^7.26.0":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4"
integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==
dependencies:
"@babel/template" "^7.25.7"
"@babel/types" "^7.25.7"
"@babel/template" "^7.25.9"
"@babel/types" "^7.26.0"
"@babel/highlight@^7.24.7":
version "7.24.7"
@@ -175,16 +168,6 @@
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/highlight@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.7.tgz#20383b5f442aa606e7b5e3043b0b1aafe9f37de5"
integrity sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==
dependencies:
"@babel/helper-validator-identifier" "^7.25.7"
chalk "^2.4.2"
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.25.0", "@babel/parser@^7.25.6":
version "7.25.6"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz"
@@ -192,12 +175,12 @@
dependencies:
"@babel/types" "^7.25.6"
"@babel/parser@^7.25.7", "@babel/parser@^7.25.8":
version "7.25.8"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2"
integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==
"@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.2":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11"
integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==
dependencies:
"@babel/types" "^7.25.8"
"@babel/types" "^7.26.0"
"@babel/plugin-syntax-async-generators@^7.8.4":
version "7.8.4"
@@ -318,19 +301,19 @@
dependencies:
"@babel/helper-plugin-utils" "^7.24.8"
"@babel/plugin-transform-react-jsx-self@^7.24.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.7.tgz#3d11df143131fd8f5486a1f7d3839890f88f8c85"
integrity sha512-JD9MUnLbPL0WdVK8AWC7F7tTG2OS6u/AKKnsK+NdRhUiVdnzyR1S3kKQCaRLOiaULvUiqK6Z4JQE635VgtCFeg==
"@babel/plugin-transform-react-jsx-self@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz#c0b6cae9c1b73967f7f9eb2fca9536ba2fad2858"
integrity sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==
dependencies:
"@babel/helper-plugin-utils" "^7.25.7"
"@babel/helper-plugin-utils" "^7.25.9"
"@babel/plugin-transform-react-jsx-source@^7.24.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.7.tgz#a0d8372310d5ea5b0447dfa03a8485f960eff7be"
integrity sha512-S/JXG/KrbIY06iyJPKfxr0qRxnhNOdkNXYBl/rmwgDd72cQLH9tEGkDm/yJPGvcSIUoikzfjMios9i+xT/uv9w==
"@babel/plugin-transform-react-jsx-source@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz#4c6b8daa520b5f155b5fb55547d7c9fa91417503"
integrity sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==
dependencies:
"@babel/helper-plugin-utils" "^7.25.7"
"@babel/helper-plugin-utils" "^7.25.9"
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.8", "@babel/runtime@^7.23.9", "@babel/runtime@^7.26.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.7":
version "7.26.0"
@@ -348,14 +331,14 @@
"@babel/parser" "^7.25.0"
"@babel/types" "^7.25.0"
"@babel/template@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769"
integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==
"@babel/template@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016"
integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==
dependencies:
"@babel/code-frame" "^7.25.7"
"@babel/parser" "^7.25.7"
"@babel/types" "^7.25.7"
"@babel/code-frame" "^7.25.9"
"@babel/parser" "^7.25.9"
"@babel/types" "^7.25.9"
"@babel/traverse@^7.24.7":
version "7.25.6"
@@ -370,16 +353,16 @@
debug "^4.3.1"
globals "^11.1.0"
"@babel/traverse@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8"
integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==
"@babel/traverse@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84"
integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
dependencies:
"@babel/code-frame" "^7.25.7"
"@babel/generator" "^7.25.7"
"@babel/parser" "^7.25.7"
"@babel/template" "^7.25.7"
"@babel/types" "^7.25.7"
"@babel/code-frame" "^7.25.9"
"@babel/generator" "^7.25.9"
"@babel/parser" "^7.25.9"
"@babel/template" "^7.25.9"
"@babel/types" "^7.25.9"
debug "^4.3.1"
globals "^11.1.0"
@@ -392,14 +375,13 @@
"@babel/helper-validator-identifier" "^7.24.7"
to-fast-properties "^2.0.0"
"@babel/types@^7.25.7", "@babel/types@^7.25.8":
version "7.25.8"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1"
integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==
"@babel/types@^7.25.9", "@babel/types@^7.26.0":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff"
integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==
dependencies:
"@babel/helper-string-parser" "^7.25.7"
"@babel/helper-validator-identifier" "^7.25.7"
to-fast-properties "^2.0.0"
"@babel/helper-string-parser" "^7.25.9"
"@babel/helper-validator-identifier" "^7.25.9"
"@bcoe/v8-coverage@^0.2.3":
version "0.2.3"
@@ -430,7 +412,7 @@
source-map "^0.5.7"
stylis "4.2.0"
"@emotion/cache@^11.11.0", "@emotion/cache@^11.13.1", "@emotion/cache@^11.13.5":
"@emotion/cache@^11.11.0", "@emotion/cache@^11.13.5":
version "11.13.5"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.13.5.tgz#e78dad0489e1ed7572507ba8ed9d2130529e4266"
integrity sha512-Z3xbtJ+UcK76eWkagZ1onvn/wAVb1GOMuR15s30Fm2wrMgC7jzpnO2JZXr4eujTTqoQFUrZIw/rT0c6Zzjca1g==
@@ -472,7 +454,7 @@
"@emotion/weak-memoize" "^0.4.0"
hoist-non-react-statics "^3.3.1"
"@emotion/serialize@^1.3.2", "@emotion/serialize@^1.3.3":
"@emotion/serialize@^1.3.3":
version "1.3.3"
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.3.tgz#d291531005f17d704d0463a032fe679f376509e8"
integrity sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==
@@ -676,10 +658,10 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@9.15.0", "@eslint/js@^9.13.0":
version "9.15.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.15.0.tgz#df0e24fe869143b59731942128c19938fdbadfb5"
integrity sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==
"@eslint/js@9.16.0", "@eslint/js@^9.13.0":
version "9.16.0"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.16.0.tgz#3df2b2dd3b9163056616886c86e4082f45dbf3f4"
integrity sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==
"@eslint/object-schema@^2.1.4":
version "2.1.4"
@@ -990,10 +972,10 @@
resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz"
integrity sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==
"@mui/core-downloads-tracker@^6.1.8":
version "6.1.8"
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.8.tgz#4fccd4eb9960ffa17ebf0533a6e9cfd2787cba57"
integrity sha512-TGAvzwUg9hybDacwfIGFjI2bXYXrIqky+vMfaeay8rvT56/PNAlvIDUJ54kpT5KRc9AWAihOvtDI7/LJOThOmQ==
"@mui/core-downloads-tracker@^6.1.9":
version "6.1.9"
resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.9.tgz#7f538205f7f877cdc335d06ef7e671fe840cf68f"
integrity sha512-TWqj7b1w5cmSz4H/uf+y2AHxAH4ldPR7D2bz0XVyn60GCAo/zRbRPx7cF8gTs/i7CiYeHzV6dtat0VpMwOtolw==
"@mui/icons-material@^5.15.20":
version "5.16.7"
@@ -1027,16 +1009,16 @@
react-is "^18.3.1"
react-transition-group "^4.4.5"
"@mui/material@^6.1.8":
version "6.1.8"
resolved "https://registry.yarnpkg.com/@mui/material/-/material-6.1.8.tgz#67cc5796aaa3f81ac94783fd79c85c80062e4a99"
integrity sha512-QZdQFnXct+7NXIzHgT3qt+sQiO7HYGZU2vymP9Xl9tUMXEOA/S1mZMMb7+WGZrk5TzNlU/kP/85K0da5V1jXoQ==
"@mui/material@^6.1.9":
version "6.1.9"
resolved "https://registry.yarnpkg.com/@mui/material/-/material-6.1.9.tgz#e596944ea4d95f16bdc9dd83ebd1b7067e5957be"
integrity sha512-NwqIN0bdsgzSbZd5JFcC+2ez0XW/XNs8uiV2PDHrqQ4qf/FEasFJG1z6g8JbCN0YlTrHZekVb17X0Fv0qcYJfQ==
dependencies:
"@babel/runtime" "^7.26.0"
"@mui/core-downloads-tracker" "^6.1.8"
"@mui/system" "^6.1.8"
"@mui/core-downloads-tracker" "^6.1.9"
"@mui/system" "^6.1.9"
"@mui/types" "^7.2.19"
"@mui/utils" "^6.1.8"
"@mui/utils" "^6.1.9"
"@popperjs/core" "^2.11.8"
"@types/react-transition-group" "^4.4.11"
clsx "^2.1.1"
@@ -1054,13 +1036,13 @@
"@mui/utils" "^5.16.6"
prop-types "^15.8.1"
"@mui/private-theming@^6.1.8":
version "6.1.8"
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.1.8.tgz#3ac194689bd4a4bb79816508e9fcc00708753d12"
integrity sha512-TuKl7msynCNCVvhX3c0ef1sF0Qb3VHcPs8XOGB/8bdOGBr/ynmIG1yTMjZeiFQXk8yN9fzK/FDEKMFxILNn3wg==
"@mui/private-theming@^6.1.9":
version "6.1.9"
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.1.9.tgz#14b84e31bff4caef9b85d77870869d733fde39f6"
integrity sha512-7aum/O1RquBYhfwL/7egDyl9GqJgPM6hoJDFFBbhF6Sgv9yI9v4w3ArKUkuVvR0CtVj4NXRVMKEioh1bjUzvuA==
dependencies:
"@babel/runtime" "^7.26.0"
"@mui/utils" "^6.1.8"
"@mui/utils" "^6.1.9"
prop-types "^15.8.1"
"@mui/styled-engine@^5.16.6":
@@ -1073,14 +1055,14 @@
csstype "^3.1.3"
prop-types "^15.8.1"
"@mui/styled-engine@^6.1.8":
version "6.1.8"
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-6.1.8.tgz#8e99ff036d171b811eff0f0421c7aae8b0b9ac35"
integrity sha512-ZvEoT0U2nPLSLI+B4by4cVjaZnPT2f20f4JUPkyHdwLv65ZzuoHiTlwyhqX1Ch63p8bcJzKTHQVGisEoMK6PGA==
"@mui/styled-engine@^6.1.9":
version "6.1.9"
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-6.1.9.tgz#ef2c39d3e3eda94490e1822d1f23c4fb924651f1"
integrity sha512-xynSLlJRxHLzSfQaiDjkaTx8LiFb9ByVa7aOdwFnTxGWFMY1F+mkXwAUY4jDDE+MAxkWxlzzQE0wOohnsxhdQg==
dependencies:
"@babel/runtime" "^7.26.0"
"@emotion/cache" "^11.13.1"
"@emotion/serialize" "^1.3.2"
"@emotion/cache" "^11.13.5"
"@emotion/serialize" "^1.3.3"
"@emotion/sheet" "^1.4.0"
csstype "^3.1.3"
prop-types "^15.8.1"
@@ -1099,16 +1081,16 @@
csstype "^3.1.3"
prop-types "^15.8.1"
"@mui/system@^6.1.8":
version "6.1.8"
resolved "https://registry.yarnpkg.com/@mui/system/-/system-6.1.8.tgz#8ec7eabbb40a6888ebc526fd919b8f3a9d8eeece"
integrity sha512-i1kLfQoWxzFpXTBQIuPoA3xKnAnP3en4I2T8xIolovSolGQX5k8vGjw1JaydQS40td++cFsgCdEU458HDNTGUA==
"@mui/system@^6.1.9":
version "6.1.9"
resolved "https://registry.yarnpkg.com/@mui/system/-/system-6.1.9.tgz#7b8735e7cbb6df552416607b9c00404557aa4e31"
integrity sha512-8x+RucnNp21gfFYsklCaZf0COXbv3+v0lrVuXONxvPEkESi2rwLlOi8UPJfcz6LxZOAX3v3oQ7qw18vnpgueRg==
dependencies:
"@babel/runtime" "^7.26.0"
"@mui/private-theming" "^6.1.8"
"@mui/styled-engine" "^6.1.8"
"@mui/private-theming" "^6.1.9"
"@mui/styled-engine" "^6.1.9"
"@mui/types" "^7.2.19"
"@mui/utils" "^6.1.8"
"@mui/utils" "^6.1.9"
clsx "^2.1.1"
csstype "^3.1.3"
prop-types "^15.8.1"
@@ -1118,10 +1100,10 @@
resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.19.tgz#c941954dd24393fdce5f07830d44440cf4ab6c80"
integrity sha512-6XpZEM/Q3epK9RN8ENoXuygnqUQxE+siN/6rGRi2iwJPgBUR25mphYQ9ZI87plGh58YoZ5pp40bFvKYOCDJ3tA==
"@mui/utils@^5.16.6":
version "5.16.6"
resolved "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz"
integrity sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==
"@mui/utils@^5.16.6", "@mui/utils@^5.16.8":
version "5.16.8"
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.16.8.tgz#e44acf38d446d361347c46b3e81ae366f615f37b"
integrity sha512-P/yb7BSWallQUeiNGxb+TM8epHteIUC8gzNTdPV2VfKhVY/EnGliHgt5np0GPkjQ7EzwDi/+gBevrAJtf+K94A==
dependencies:
"@babel/runtime" "^7.23.9"
"@mui/types" "^7.2.15"
@@ -1130,10 +1112,10 @@
prop-types "^15.8.1"
react-is "^18.3.1"
"@mui/utils@^6.1.8":
version "6.1.8"
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.1.8.tgz#ae07cad4f6099eeb43dbc71267b4a96304ba3982"
integrity sha512-O2DWb1kz8hiANVcR7Z4gOB3SvPPsSQGUmStpyBDzde6dJIfBzgV9PbEQOBZd3EBsd1pB+Uv1z5LAJAbymmawrA==
"@mui/utils@^6.1.9":
version "6.1.9"
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.1.9.tgz#821612300f66684054fd6e36336cfea91f050fbe"
integrity sha512-N7uzBp7p2or+xanXn3aH2OTINC6F/Ru/U8h6amhRZEev8bJhKN86rIDIoxZZ902tj+09LXtH83iLxFMjMHyqNA==
dependencies:
"@babel/runtime" "^7.26.0"
"@mui/types" "^7.2.19"
@@ -1282,17 +1264,17 @@
dependencies:
"@sinonjs/commons" "^3.0.0"
"@tanstack/query-core@5.60.6":
version "5.60.6"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.60.6.tgz#0dd33fe231b0d18bf66d0c615b29899738300658"
integrity sha512-tI+k0KyCo1EBJ54vxK1kY24LWj673ujTydCZmzEZKAew4NqZzTaVQJEuaG1qKj2M03kUHN46rchLRd+TxVq/zQ==
"@tanstack/query-core@5.62.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.62.0.tgz#94022c9fde3b8c60e69828b726bd0df535dcacf9"
integrity sha512-sx38bGrqF9bop92AXOvzDr0L9fWDas5zXdPglxa9cuqeVSWS7lY6OnVyl/oodfXjgOGRk79IfCpgVmxrbHuFHg==
"@tanstack/react-query@^5.21.7", "@tanstack/react-query@^5.61.3":
version "5.61.3"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.61.3.tgz#0187b73b87adaeaed09f3d9717e35b507175fe23"
integrity sha512-c3Oz9KaCBapGkRewu7AJLhxE9BVqpMcHsd3KtFxSd7FSCu2qGwqfIN37zbSGoyk6Ix9LGZBNHQDPI6GpWABnmA==
"@tanstack/react-query@^5.21.7", "@tanstack/react-query@^5.62.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.62.0.tgz#db7d4ec58a0db69b105e2d8bd249acfb20653825"
integrity sha512-tj2ltjAn2a3fs+Dqonlvs6GyLQ/LKVJE2DVSYW+8pJ3P6/VCVGrfqv5UEchmlP7tLOvvtZcOuSyI2ooVlR5Yqw==
dependencies:
"@tanstack/query-core" "5.60.6"
"@tanstack/query-core" "5.62.0"
"@testing-library/dom@^10.0.0":
version "10.4.0"
@@ -1464,12 +1446,12 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb"
integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==
"@types/node@*", "@types/node@^22.9.3":
version "22.9.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.3.tgz#08f3d64b3bc6d74b162d36f60213e8a6704ef2b4"
integrity sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==
"@types/node@*", "@types/node@^22.10.1":
version "22.10.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.1.tgz#41ffeee127b8975a05f8c4f83fb89bcb2987d766"
integrity sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==
dependencies:
undici-types "~6.19.8"
undici-types "~6.20.0"
"@types/papaparse@^5.3.15":
version "5.3.15"
@@ -1525,62 +1507,62 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@8.15.0", "@typescript-eslint/eslint-plugin@^8.14.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz#c95c6521e70c8b095a684d884d96c0c1c63747d2"
integrity sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==
"@typescript-eslint/eslint-plugin@8.16.0", "@typescript-eslint/eslint-plugin@^8.14.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz#ac56825bcdf3b392fc76a94b1315d4a162f201a6"
integrity sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==
dependencies:
"@eslint-community/regexpp" "^4.10.0"
"@typescript-eslint/scope-manager" "8.15.0"
"@typescript-eslint/type-utils" "8.15.0"
"@typescript-eslint/utils" "8.15.0"
"@typescript-eslint/visitor-keys" "8.15.0"
"@typescript-eslint/scope-manager" "8.16.0"
"@typescript-eslint/type-utils" "8.16.0"
"@typescript-eslint/utils" "8.16.0"
"@typescript-eslint/visitor-keys" "8.16.0"
graphemer "^1.4.0"
ignore "^5.3.1"
natural-compare "^1.4.0"
ts-api-utils "^1.3.0"
"@typescript-eslint/parser@8.15.0", "@typescript-eslint/parser@^8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.15.0.tgz#92610da2b3af702cfbc02a46e2a2daa6260a9045"
integrity sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==
"@typescript-eslint/parser@8.16.0", "@typescript-eslint/parser@^8.15.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.16.0.tgz#ee5b2d6241c1ab3e2e53f03fd5a32d8e266d8e06"
integrity sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==
dependencies:
"@typescript-eslint/scope-manager" "8.15.0"
"@typescript-eslint/types" "8.15.0"
"@typescript-eslint/typescript-estree" "8.15.0"
"@typescript-eslint/visitor-keys" "8.15.0"
"@typescript-eslint/scope-manager" "8.16.0"
"@typescript-eslint/types" "8.16.0"
"@typescript-eslint/typescript-estree" "8.16.0"
"@typescript-eslint/visitor-keys" "8.16.0"
debug "^4.3.4"
"@typescript-eslint/scope-manager@8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz#28a1a0f13038f382424f45a988961acaca38f7c6"
integrity sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==
"@typescript-eslint/scope-manager@8.16.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz#ebc9a3b399a69a6052f3d88174456dd399ef5905"
integrity sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==
dependencies:
"@typescript-eslint/types" "8.15.0"
"@typescript-eslint/visitor-keys" "8.15.0"
"@typescript-eslint/types" "8.16.0"
"@typescript-eslint/visitor-keys" "8.16.0"
"@typescript-eslint/type-utils@8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz#a6da0f93aef879a68cc66c73fe42256cb7426c72"
integrity sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==
"@typescript-eslint/type-utils@8.16.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.16.0.tgz#585388735f7ac390f07c885845c3d185d1b64740"
integrity sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==
dependencies:
"@typescript-eslint/typescript-estree" "8.15.0"
"@typescript-eslint/utils" "8.15.0"
"@typescript-eslint/typescript-estree" "8.16.0"
"@typescript-eslint/utils" "8.16.0"
debug "^4.3.4"
ts-api-utils "^1.3.0"
"@typescript-eslint/types@8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.15.0.tgz#4958edf3d83e97f77005f794452e595aaf6430fc"
integrity sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ==
"@typescript-eslint/types@8.16.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.16.0.tgz#49c92ae1b57942458ab83d9ec7ccab3005e64737"
integrity sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==
"@typescript-eslint/typescript-estree@8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz#915c94e387892b114a2a2cc0df2d7f19412c8ba7"
integrity sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg==
"@typescript-eslint/typescript-estree@8.16.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz#9d741e56e5b13469b5190e763432ce5551a9300c"
integrity sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==
dependencies:
"@typescript-eslint/types" "8.15.0"
"@typescript-eslint/visitor-keys" "8.15.0"
"@typescript-eslint/types" "8.16.0"
"@typescript-eslint/visitor-keys" "8.16.0"
debug "^4.3.4"
fast-glob "^3.3.2"
is-glob "^4.0.3"
@@ -1588,32 +1570,32 @@
semver "^7.6.0"
ts-api-utils "^1.3.0"
"@typescript-eslint/utils@8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.15.0.tgz#ac04679ad19252776b38b81954b8e5a65567cef6"
integrity sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ==
"@typescript-eslint/utils@8.16.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.16.0.tgz#c71264c437157feaa97842809836254a6fc833c3"
integrity sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==
dependencies:
"@eslint-community/eslint-utils" "^4.4.0"
"@typescript-eslint/scope-manager" "8.15.0"
"@typescript-eslint/types" "8.15.0"
"@typescript-eslint/typescript-estree" "8.15.0"
"@typescript-eslint/scope-manager" "8.16.0"
"@typescript-eslint/types" "8.16.0"
"@typescript-eslint/typescript-estree" "8.16.0"
"@typescript-eslint/visitor-keys@8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz#9ea5a85eb25401d2aa74ec8a478af4e97899ea12"
integrity sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==
"@typescript-eslint/visitor-keys@8.16.0":
version "8.16.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz#d5086afc060b01ff7a4ecab8d49d13d5a7b07705"
integrity sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==
dependencies:
"@typescript-eslint/types" "8.15.0"
"@typescript-eslint/types" "8.16.0"
eslint-visitor-keys "^4.2.0"
"@vitejs/plugin-react@^4.3.3":
version "4.3.3"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz#28301ac6d7aaf20b73a418ee5c65b05519b4836c"
integrity sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==
"@vitejs/plugin-react@^4.3.4":
version "4.3.4"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz#c64be10b54c4640135a5b28a2432330e88ad7c20"
integrity sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==
dependencies:
"@babel/core" "^7.25.2"
"@babel/plugin-transform-react-jsx-self" "^7.24.7"
"@babel/plugin-transform-react-jsx-source" "^7.24.7"
"@babel/core" "^7.26.0"
"@babel/plugin-transform-react-jsx-self" "^7.25.9"
"@babel/plugin-transform-react-jsx-source" "^7.25.9"
"@types/babel__core" "^7.20.5"
react-refresh "^0.14.2"
@@ -2763,17 +2745,17 @@ eslint-visitor-keys@^4.2.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45"
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
eslint@^9.15.0:
version "9.15.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.15.0.tgz#77c684a4e980e82135ebff8ee8f0a9106ce6b8a6"
integrity sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==
eslint@^9.16.0:
version "9.16.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.16.0.tgz#66832e66258922ac0a626f803a9273e37747f2a6"
integrity sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.12.1"
"@eslint/config-array" "^0.19.0"
"@eslint/core" "^0.9.0"
"@eslint/eslintrc" "^3.2.0"
"@eslint/js" "9.15.0"
"@eslint/js" "9.16.0"
"@eslint/plugin-kit" "^0.2.3"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
@@ -4535,10 +4517,10 @@ prettier-linter-helpers@^1.0.0:
dependencies:
fast-diff "^1.1.2"
prettier@^3.3.3:
version "3.3.3"
resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz"
integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==
prettier@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.4.1.tgz#e211d451d6452db0a291672ca9154bc8c2579f7b"
integrity sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==
pretty-format@^27.0.2:
version "27.5.1"
@@ -5418,14 +5400,14 @@ typed-array-length@^1.0.6:
is-typed-array "^1.1.13"
possible-typed-array-names "^1.0.0"
typescript-eslint@^8.15.0:
version "8.15.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.15.0.tgz#c8a2a0d183c3eb48ae176aa078c1b9daa584cf9d"
integrity sha512-wY4FRGl0ZI+ZU4Jo/yjdBu0lVTSML58pu6PgGtJmCufvzfV565pUF6iACQt092uFOd49iLOTX/sEVmHtbSrS+w==
typescript-eslint@^8.16.0:
version "8.16.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.16.0.tgz#d608c972d6b2461ca10ec30fd3fa62a080baba19"
integrity sha512-wDkVmlY6O2do4V+lZd0GtRfbtXbeD0q9WygwXXSJnC1xorE8eqyC2L1tJimqpSeFrOzRlYtWnUp/uzgHQOgfBQ==
dependencies:
"@typescript-eslint/eslint-plugin" "8.15.0"
"@typescript-eslint/parser" "8.15.0"
"@typescript-eslint/utils" "8.15.0"
"@typescript-eslint/eslint-plugin" "8.16.0"
"@typescript-eslint/parser" "8.16.0"
"@typescript-eslint/utils" "8.16.0"
typescript@^5.7.2:
version "5.7.2"
@@ -5442,10 +5424,10 @@ unbox-primitive@^1.0.2:
has-symbols "^1.0.3"
which-boxed-primitive "^1.0.2"
undici-types@~6.19.8:
version "6.19.8"
resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz"
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
undici-types@~6.20.0:
version "6.20.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
universalify@^0.2.0:
version "0.2.0"
@@ -5497,10 +5479,10 @@ v8-to-istanbul@^9.0.1:
"@types/istanbul-lib-coverage" "^2.0.1"
convert-source-map "^2.0.0"
vite-plugin-version-mark@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/vite-plugin-version-mark/-/vite-plugin-version-mark-0.1.2.tgz#85b2315cffce7ac2d83b6afceb313d0d1c47c4d4"
integrity sha512-+mPRTwx6SOEfEq3/y1u+O0ju5Lz0Ac27Fx6hE5Xn1fMpIQfo3aERPB2/xxYI8lIa8GPHCX5c8ApqBKWwFNHxwA==
vite-plugin-version-mark@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/vite-plugin-version-mark/-/vite-plugin-version-mark-0.1.3.tgz#ffc604549080c72e886405b33ef9cb8482ecd410"
integrity sha512-dfnFyMZuMDNwetkutFN1HMvrPu9S7k45JkxUa356wE+c/Lj5Sao9gRH69r1Dj/7XgHUiKxTIJeDkTIhomh249A==
vite@^5.4.11:
version "5.4.11"