mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
Display of scraped elo results
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
MONGODB_URI=
|
||||||
|
DISCORD_WEBHOOK_URL=
|
||||||
|
RESULTS_SCRAPER_URL=
|
||||||
|
GMAIL_USER=
|
||||||
|
GMAIL_PASS=
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { useTranslations } from "next-intl";
|
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
import { TextField } from "@/components/form/TextField";
|
|
||||||
import { fetchTournamentResultsSchema } from "@/schemas";
|
|
||||||
import { trpc } from "@/utils/trpc";
|
|
||||||
|
|
||||||
type FetchResultsFormValues = z.infer<typeof fetchTournamentResultsSchema>;
|
|
||||||
|
|
||||||
export const FetchResultsForm = () => {
|
|
||||||
const t = useTranslations("Elo");
|
|
||||||
const fetchResults = trpc.fetchTournamentResults.useMutation();
|
|
||||||
|
|
||||||
const form = useForm<FetchResultsFormValues>({
|
|
||||||
resolver: zodResolver(fetchTournamentResultsSchema),
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (input: FetchResultsFormValues) => {
|
|
||||||
try {
|
|
||||||
const result = await fetchResults.mutateAsync(input);
|
|
||||||
console.log(result);
|
|
||||||
} catch (err: unknown) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormProvider {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
||||||
<div className="flex items-end gap-4">
|
|
||||||
<TextField
|
|
||||||
name="url"
|
|
||||||
label={t("resultsUrlLabel")}
|
|
||||||
placeholder={t("resultsUrlLabel")}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
disabled={form.formState.isSubmitting}
|
|
||||||
type="submit"
|
|
||||||
className="rounded-lg border border-transparent bg-primary-600 px-5 py-3 text-center text-sm font-medium text-white hover:bg-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300 disabled:opacity-25 dark:text-white dark:hover:bg-primary-700 dark:focus:ring-primary-800 sm:w-fit"
|
|
||||||
>
|
|
||||||
{t("fetchResultsButton")}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</FormProvider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
import { FormProvider, useFieldArray, useForm } from "react-hook-form";
|
||||||
|
import { IoAdd, IoCloseOutline } from "react-icons/io5";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { SelectField } from "@/components/form/SelectField";
|
||||||
|
import { TextField } from "@/components/form/TextField";
|
||||||
|
import { getNewRating } from "@/utils/eloCalculator";
|
||||||
|
|
||||||
|
const resultsSchema = z.object({
|
||||||
|
currentElo: z.number().int().positive(),
|
||||||
|
kFactor: z.enum(["40", "30", "20", "15", "10"]),
|
||||||
|
games: z.array(
|
||||||
|
z.object({
|
||||||
|
opponentElo: z.number().int().positive(),
|
||||||
|
result: z.enum(["win", "draw", "loss"]),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
type DeepPartial<T> = T extends object
|
||||||
|
? {
|
||||||
|
[P in keyof T]?: DeepPartial<T[P]>;
|
||||||
|
}
|
||||||
|
: T;
|
||||||
|
|
||||||
|
type EloFormValues = DeepPartial<z.infer<typeof resultsSchema>>;
|
||||||
|
|
||||||
|
export const ManualEloForm = () => {
|
||||||
|
const t = useTranslations("Elo");
|
||||||
|
|
||||||
|
const form = useForm<EloFormValues>({
|
||||||
|
resolver: zodResolver(resultsSchema),
|
||||||
|
defaultValues: {
|
||||||
|
kFactor: "20",
|
||||||
|
games: [{}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
fields: gameFields,
|
||||||
|
append: appendGame,
|
||||||
|
remove: removeGame,
|
||||||
|
} = useFieldArray({
|
||||||
|
control: form.control,
|
||||||
|
name: "games",
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async (data: EloFormValues) => {};
|
||||||
|
|
||||||
|
const [currentElo, kFactor, games] = form.watch([
|
||||||
|
"currentElo",
|
||||||
|
"kFactor",
|
||||||
|
"games",
|
||||||
|
]);
|
||||||
|
|
||||||
|
type Deltas = {
|
||||||
|
rating: number;
|
||||||
|
deltas: { rating: number; delta: number | undefined }[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculations = !Number.isNaN(currentElo)
|
||||||
|
? (games ?? []).reduce<Deltas>(
|
||||||
|
(acc, game) => {
|
||||||
|
if (!Number.isNaN(game?.opponentElo) && game?.result) {
|
||||||
|
const result =
|
||||||
|
game?.result === "win" ? 1 : game?.result === "loss" ? 0 : 0.5;
|
||||||
|
|
||||||
|
const { delta } = getNewRating(
|
||||||
|
currentElo!,
|
||||||
|
game.opponentElo!,
|
||||||
|
result,
|
||||||
|
parseInt(kFactor!, 10),
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
rating: acc.rating + delta,
|
||||||
|
deltas: [...acc.deltas, { rating: acc.rating + delta, delta }],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
rating: acc.rating,
|
||||||
|
deltas: [...acc.deltas, { rating: acc.rating, delta: undefined }],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ rating: currentElo!, deltas: [] },
|
||||||
|
)
|
||||||
|
: { rating: currentElo!, deltas: [] };
|
||||||
|
|
||||||
|
const deltas = calculations.deltas;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormProvider {...form}>
|
||||||
|
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||||
|
<div className="grid w-full grid-cols-1 gap-2 sm:grid-cols-2">
|
||||||
|
<TextField
|
||||||
|
name="currentElo"
|
||||||
|
label={t("currentEloLabel")}
|
||||||
|
placeholder={t("currentEloPlaceholder")}
|
||||||
|
type="number"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SelectField
|
||||||
|
name="kFactor"
|
||||||
|
label={t("yourKFactorLabel")}
|
||||||
|
options={["40", "20", "10"].map((k) => ({
|
||||||
|
value: k,
|
||||||
|
label: k,
|
||||||
|
}))}
|
||||||
|
isClearable={false}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 className="my-4 text-lg text-gray-900 dark:text-white">
|
||||||
|
{t("resultsTitle")}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div className="flex w-full flex-col gap-6 sm:gap-2">
|
||||||
|
{gameFields.map((game, i) => {
|
||||||
|
return (
|
||||||
|
<div key={i} className="flex w-full flex-col">
|
||||||
|
<div key={i} className="flex w-full items-center space-x-2">
|
||||||
|
<div className="grid w-full grid-cols-1 gap-2 sm:grid-cols-2">
|
||||||
|
<TextField
|
||||||
|
name={`games.${i}.opponentElo`}
|
||||||
|
placeholder={t("opponentEloPlaceholder")}
|
||||||
|
type="number"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<SelectField
|
||||||
|
name={`games.${i}.result`}
|
||||||
|
placeholder={t("gameResultPlaceholder")}
|
||||||
|
options={["win", "draw", "loss"].map((result) => ({
|
||||||
|
value: result,
|
||||||
|
label: t("gameResult", { result }),
|
||||||
|
}))}
|
||||||
|
isClearable={false}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
{gameFields.length > 1 && (
|
||||||
|
<button
|
||||||
|
className="hidden h-8 w-8 items-center justify-center rounded-md bg-neutral-100 hover:bg-neutral-200 dark:bg-neutral-600 dark:hover:bg-neutral-700 sm:flex"
|
||||||
|
type="button"
|
||||||
|
onClick={() => removeGame(i)}
|
||||||
|
>
|
||||||
|
<IoCloseOutline className="h-6 w-6 text-gray-900 transition-all duration-200 hover:text-primary dark:text-neutral-400 hover:dark:text-white" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{gameFields.length > 1 && (
|
||||||
|
<button
|
||||||
|
className="flex h-8 w-8 items-center justify-center rounded-md bg-neutral-100 hover:bg-neutral-200 dark:bg-neutral-600 dark:hover:bg-neutral-700 sm:hidden"
|
||||||
|
type="button"
|
||||||
|
onClick={() => removeGame(i)}
|
||||||
|
>
|
||||||
|
<IoCloseOutline className="h-6 w-6 text-gray-900 transition-all duration-200 hover:text-primary dark:text-neutral-400 hover:dark:text-white" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{deltas[i]?.delta !== undefined && (
|
||||||
|
<div
|
||||||
|
className={twMerge(
|
||||||
|
"mt-2 flex justify-end text-gray-900 dark:text-neutral-400",
|
||||||
|
gameFields.length > 1 && "mr-10",
|
||||||
|
i === deltas.length - 1 && "font-bold",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{Math.round(deltas[i]!.rating)} (
|
||||||
|
<span
|
||||||
|
className={twMerge(
|
||||||
|
deltas[i].delta! > 0 && "text-success",
|
||||||
|
deltas[i].delta! < 0 && "text-error",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{deltas[i]!.delta! >= 0 ? "+" : ""}
|
||||||
|
{deltas[i].delta!}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-8 flex justify-end">
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
appendGame({});
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="rounded-lg bg-primary-600 px-5 py-3 text-center text-sm font-medium text-white hover:bg-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300 disabled:opacity-25 dark:text-white dark:hover:bg-primary-700 dark:focus:ring-primary-800 sm:w-fit"
|
||||||
|
>
|
||||||
|
<IoAdd className="mr-2 inline-block h-5 w-5" />
|
||||||
|
{t("addGameButton")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</FormProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,213 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { last } from "lodash";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
import { getNewRating } from "@/utils/eloCalculator";
|
||||||
|
import { TournamentResultsData } from "@/utils/trpc";
|
||||||
|
|
||||||
|
type TournamentResultsProps = {
|
||||||
|
results: TournamentResultsData;
|
||||||
|
playerId: string;
|
||||||
|
kFactor: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TournamentResults = ({
|
||||||
|
results,
|
||||||
|
playerId,
|
||||||
|
kFactor,
|
||||||
|
}: TournamentResultsProps) => {
|
||||||
|
const t = useTranslations("Elo");
|
||||||
|
|
||||||
|
const playerResults = results?.find((p) => p.id === playerId);
|
||||||
|
if (!playerResults) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Deltas = {
|
||||||
|
rating: number;
|
||||||
|
deltas: {
|
||||||
|
rating: number;
|
||||||
|
delta: number | undefined;
|
||||||
|
opponentName: string | null;
|
||||||
|
opponentElo: number | null;
|
||||||
|
result: number | null;
|
||||||
|
lostByForfeit: boolean;
|
||||||
|
wonByForfeit: boolean;
|
||||||
|
estimated: boolean;
|
||||||
|
national: boolean;
|
||||||
|
colour: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentElo = playerResults.elo;
|
||||||
|
|
||||||
|
const calculations = !Number.isNaN(currentElo)
|
||||||
|
? (playerResults.results ?? []).reduce<Deltas>(
|
||||||
|
(acc, game) => {
|
||||||
|
const info = {
|
||||||
|
opponentName: game.opponent,
|
||||||
|
opponentElo: game.elo,
|
||||||
|
lostByForfeit: game.lostByForfeit,
|
||||||
|
wonByForfeit: game.wonByForfeit,
|
||||||
|
estimated: game.estimated,
|
||||||
|
national: game.national,
|
||||||
|
colour: game.colour,
|
||||||
|
result: game.result,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (
|
||||||
|
!game.wonByForfeit &&
|
||||||
|
!game.lostByForfeit &&
|
||||||
|
!game.estimated &&
|
||||||
|
!game.national &&
|
||||||
|
game.result !== null
|
||||||
|
) {
|
||||||
|
const { delta } = getNewRating(
|
||||||
|
currentElo!,
|
||||||
|
game.elo!,
|
||||||
|
game.result as 1 | 0 | 0.5,
|
||||||
|
kFactor,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
rating: acc.rating + delta,
|
||||||
|
deltas: [
|
||||||
|
...acc.deltas,
|
||||||
|
{ rating: acc.rating + delta, delta, ...info },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
rating: acc.rating,
|
||||||
|
deltas: [
|
||||||
|
...acc.deltas,
|
||||||
|
{ rating: acc.rating, delta: undefined, ...info },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ rating: currentElo!, deltas: [] },
|
||||||
|
)
|
||||||
|
: { rating: currentElo!, deltas: [] };
|
||||||
|
|
||||||
|
const deltas = calculations.deltas;
|
||||||
|
const totalDelta = Math.round(
|
||||||
|
deltas.reduce((acc, delta) => acc + (delta.delta ?? 0), 0),
|
||||||
|
);
|
||||||
|
|
||||||
|
const noChangeCount = (deltas ?? []).filter(
|
||||||
|
({ wonByForfeit, lostByForfeit, estimated, national }) =>
|
||||||
|
wonByForfeit || lostByForfeit || estimated || national,
|
||||||
|
).length;
|
||||||
|
|
||||||
|
if (playerResults.estimated || playerResults.national)
|
||||||
|
return <div className="my-8 text-center text-error">{t("needRating")}</div>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="my-8 text-gray-900 dark:text-neutral-400">
|
||||||
|
{t("initialRating", { rating: Math.round(playerResults.elo) })}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table className="mt-8 w-full">
|
||||||
|
{deltas.map((delta, i) => {
|
||||||
|
const { estimated, national, lostByForfeit, wonByForfeit } = delta;
|
||||||
|
const opponentElo = delta.opponentElo
|
||||||
|
? ` (${delta.opponentElo} ${
|
||||||
|
estimated ? "E" : national ? "N" : "F"
|
||||||
|
})`
|
||||||
|
: "";
|
||||||
|
|
||||||
|
const opponentName = delta.opponentName ? (
|
||||||
|
<span>
|
||||||
|
<span className="whitespace-nowrap font-bold">
|
||||||
|
{delta.opponentName}
|
||||||
|
</span>
|
||||||
|
{opponentElo}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
"-"
|
||||||
|
);
|
||||||
|
|
||||||
|
const playedWhite = delta.colour === "white";
|
||||||
|
|
||||||
|
const whitePlayer = playedWhite ? playerResults.name : opponentName;
|
||||||
|
const blackPlayer = !playedWhite ? playerResults.name : opponentName;
|
||||||
|
const noChange =
|
||||||
|
wonByForfeit || lostByForfeit || estimated || national;
|
||||||
|
|
||||||
|
const forfeit = delta.opponentName === null;
|
||||||
|
|
||||||
|
let result = "";
|
||||||
|
if (wonByForfeit) {
|
||||||
|
result = t("wonByForfeit");
|
||||||
|
} else if (lostByForfeit) {
|
||||||
|
result = t("lostByForfeit");
|
||||||
|
} else if (delta.result === 0.5) {
|
||||||
|
result = t("draw");
|
||||||
|
} else if (playedWhite && delta.result === 1) {
|
||||||
|
result = t("whiteWin");
|
||||||
|
} else result = t("blackWin");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className="text-gray-900 dark:text-neutral-400">
|
||||||
|
{forfeit ? (
|
||||||
|
<td className="pb-2">{t("forfeit")}</td>
|
||||||
|
) : (
|
||||||
|
<td className="pb-2">
|
||||||
|
{whitePlayer}
|
||||||
|
{t("vs")}
|
||||||
|
{blackPlayer}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
<td className="whitespace-nowrap px-2 pb-2 text-center">
|
||||||
|
{!forfeit && result}
|
||||||
|
</td>
|
||||||
|
<td className="pb-2 text-right">
|
||||||
|
{noChange ? (
|
||||||
|
"-"
|
||||||
|
) : (
|
||||||
|
<span
|
||||||
|
className={twMerge(
|
||||||
|
deltas[i].delta! > 0 && "text-success",
|
||||||
|
deltas[i].delta! < 0 && "text-error",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{deltas[i]!.delta! >= 0 ? "+" : ""}
|
||||||
|
{deltas[i].delta!}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{noChangeCount > 0 && (
|
||||||
|
<div className="mt-4 rounded border border-gray-500 p-4 text-center text-gray-500 dark:border-neutral-400 dark:text-neutral-400">
|
||||||
|
{t("noChangeInfo", { noChangeCount })}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{deltas.length > 0 && (
|
||||||
|
<div className="mt-8 text-right text-lg font-bold text-gray-900 dark:text-neutral-400">
|
||||||
|
{t.rich("finalRating", {
|
||||||
|
rating: Math.round(last(deltas)!.rating),
|
||||||
|
delta: () => (
|
||||||
|
<span
|
||||||
|
className={twMerge(
|
||||||
|
totalDelta! > 0 && "text-success",
|
||||||
|
totalDelta! < 0 && "text-error",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{totalDelta >= 0 ? "+" : ""}
|
||||||
|
{totalDelta}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
+140
-177
@@ -1,99 +1,85 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { isEmpty } from "lodash";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { FormProvider, useFieldArray, useForm } from "react-hook-form";
|
import Link from "next/link";
|
||||||
import { IoAdd, IoCloseOutline } from "react-icons/io5";
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
import { twMerge } from "tailwind-merge";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { Spinner } from "@/components/Spinner";
|
||||||
import { SelectField } from "@/components/form/SelectField";
|
import { SelectField } from "@/components/form/SelectField";
|
||||||
import { TextField } from "@/components/form/TextField";
|
import { TextField } from "@/components/form/TextField";
|
||||||
import { getNewRating } from "@/utils/eloCalculator";
|
import { fetchTournamentResultsSchema } from "@/schemas";
|
||||||
|
import { trpc } from "@/utils/trpc";
|
||||||
|
|
||||||
import { FetchResultsForm } from "./FetchResultsForm";
|
import { ManualEloForm } from "./ManualEloForm";
|
||||||
|
import { TournamentResults } from "./TournamentResults";
|
||||||
|
|
||||||
const resultsSchema = z.object({
|
const formSchema = fetchTournamentResultsSchema.extend({
|
||||||
currentElo: z.number().int().positive(),
|
player: z.string().optional(),
|
||||||
kFactor: z.enum(["40", "30", "20", "15", "10"]),
|
kFactor: z.enum(["40", "30", "20", "15", "10"]),
|
||||||
games: z.array(
|
|
||||||
z.object({
|
|
||||||
opponentElo: z.number().int().positive(),
|
|
||||||
result: z.enum(["win", "draw", "loss"]),
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
type DeepPartial<T> = T extends object
|
type FetchResultsFormValues = z.infer<typeof formSchema>;
|
||||||
? {
|
|
||||||
[P in keyof T]?: DeepPartial<T[P]>;
|
|
||||||
}
|
|
||||||
: T;
|
|
||||||
|
|
||||||
type EloFormValues = DeepPartial<z.infer<typeof resultsSchema>>;
|
|
||||||
|
|
||||||
export default function Elo() {
|
export default function Elo() {
|
||||||
const t = useTranslations("Elo");
|
const t = useTranslations("Elo");
|
||||||
|
type TranslationKey = Parameters<typeof t>[0];
|
||||||
|
|
||||||
const form = useForm<EloFormValues>({
|
const [formInput, setFormInput] = useState<FetchResultsFormValues>({
|
||||||
resolver: zodResolver(resultsSchema),
|
url: "",
|
||||||
|
kFactor: "20",
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasUrl = !isEmpty(formInput?.url.trim());
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: allResults,
|
||||||
|
isFetching,
|
||||||
|
error,
|
||||||
|
} = trpc.fetchTournamentResults.useQuery(
|
||||||
|
{
|
||||||
|
url: formInput?.url.trim(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
staleTime: Infinity,
|
||||||
|
cacheTime: 10 * 60 * 1000,
|
||||||
|
enabled: hasUrl,
|
||||||
|
retry: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const playerOptions = (allResults ?? []).map((player) => ({
|
||||||
|
value: player.id,
|
||||||
|
label: player.name,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const form = useForm<FetchResultsFormValues>({
|
||||||
|
resolver: zodResolver(fetchTournamentResultsSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
kFactor: "20",
|
kFactor: "20",
|
||||||
games: [{}],
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const [player, kFactor] = form.watch(["player", "kFactor"]);
|
||||||
fields: gameFields,
|
const playerResults = allResults?.find((p) => p.id === player);
|
||||||
append: appendGame,
|
|
||||||
remove: removeGame,
|
|
||||||
} = useFieldArray({
|
|
||||||
control: form.control,
|
|
||||||
name: "games",
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: EloFormValues) => {};
|
const onSubmit = async (input: FetchResultsFormValues) => {
|
||||||
|
setFormInput(input);
|
||||||
const [currentElo, kFactor, games] = form.watch([
|
|
||||||
"currentElo",
|
|
||||||
"kFactor",
|
|
||||||
"games",
|
|
||||||
]);
|
|
||||||
|
|
||||||
type Deltas = {
|
|
||||||
rating: number;
|
|
||||||
deltas: { rating: number; delta: number | undefined }[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const calculations = !Number.isNaN(currentElo)
|
const clearForm = () => {
|
||||||
? (games ?? []).reduce<Deltas>(
|
form.setValue("url", "");
|
||||||
(acc, game) => {
|
setFormInput({ ...formInput, url: "" });
|
||||||
if (!Number.isNaN(game?.opponentElo) && game?.result) {
|
};
|
||||||
const result =
|
|
||||||
game?.result === "win" ? 1 : game?.result === "loss" ? 0 : 0.5;
|
|
||||||
|
|
||||||
const { delta } = getNewRating(
|
if (error) {
|
||||||
currentElo!,
|
console.error(error);
|
||||||
game.opponentElo!,
|
}
|
||||||
result,
|
|
||||||
parseInt(kFactor!, 10),
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
rating: acc.rating + delta,
|
|
||||||
deltas: [...acc.deltas, { rating: acc.rating + delta, delta }],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
rating: acc.rating,
|
|
||||||
deltas: [...acc.deltas, { rating: acc.rating, delta: undefined }],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{ rating: currentElo!, deltas: [] },
|
|
||||||
)
|
|
||||||
: { rating: currentElo!, deltas: [] };
|
|
||||||
|
|
||||||
const deltas = calculations.deltas;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="grid place-items-center bg-white pb-20 dark:bg-gray-800">
|
<section className="grid place-items-center bg-white pb-20 dark:bg-gray-800">
|
||||||
@@ -108,124 +94,101 @@ export default function Elo() {
|
|||||||
{t("info")}
|
{t("info")}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="mb-10">
|
{hasUrl && !isFetching && !error && (
|
||||||
<FetchResultsForm />
|
<div className="mx-auto mb-8 flex justify-center">
|
||||||
</div>
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={clearForm}
|
||||||
|
className="rounded-lg border border-primary px-3 py-2 text-center text-sm text-primary hover:bg-primary hover:text-white focus:outline-none focus:ring-4 focus:ring-primary-300 disabled:opacity-25 dark:text-white dark:focus:ring-primary-800 sm:w-fit"
|
||||||
|
>
|
||||||
|
{t("enterManualResultsButton")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<FormProvider {...form}>
|
<FormProvider {...form}>
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||||
<div className="grid w-full grid-cols-1 gap-2 sm:grid-cols-2">
|
<div className="flex items-end gap-4">
|
||||||
<TextField
|
<TextField
|
||||||
name="currentElo"
|
name="url"
|
||||||
label={t("currentEloLabel")}
|
label={t("resultsUrlLabel")}
|
||||||
placeholder={t("currentEloPlaceholder")}
|
placeholder={t("resultsUrlLabel")}
|
||||||
type="number"
|
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SelectField
|
|
||||||
name="kFactor"
|
|
||||||
label={t("kFactorLabel")}
|
|
||||||
options={["40", "20", "10"].map((k) => ({
|
|
||||||
value: k,
|
|
||||||
label: k,
|
|
||||||
}))}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 className="my-4 text-lg text-gray-900 dark:text-white">
|
|
||||||
{t("resultsTitle")}
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div className="flex w-full flex-col gap-6 sm:gap-2">
|
|
||||||
{gameFields.map((game, i) => {
|
|
||||||
return (
|
|
||||||
<div key={i} className="flex w-full flex-col">
|
|
||||||
<div key={i} className="flex w-full items-center space-x-2">
|
|
||||||
<div className="grid w-full grid-cols-1 gap-2 sm:grid-cols-2">
|
|
||||||
<TextField
|
|
||||||
name={`games.${i}.opponentElo`}
|
|
||||||
placeholder={t("opponentEloPlaceholder")}
|
|
||||||
type="number"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex items-center space-x-2">
|
|
||||||
<SelectField
|
|
||||||
name={`games.${i}.result`}
|
|
||||||
placeholder={t("gameResultPlaceholder")}
|
|
||||||
options={["win", "draw", "loss"].map((result) => ({
|
|
||||||
value: result,
|
|
||||||
label: t("gameResult", { result }),
|
|
||||||
}))}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
{gameFields.length > 1 && (
|
|
||||||
<button
|
|
||||||
className="hidden h-8 w-8 items-center justify-center rounded-md bg-neutral-100 hover:bg-neutral-200 dark:bg-neutral-600 dark:hover:bg-neutral-700 sm:flex"
|
|
||||||
type="button"
|
|
||||||
onClick={() => removeGame(i)}
|
|
||||||
>
|
|
||||||
<IoCloseOutline className="h-6 w-6 text-gray-900 transition-all duration-200 hover:text-primary dark:text-neutral-400 hover:dark:text-white" />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{gameFields.length > 1 && (
|
|
||||||
<button
|
|
||||||
className="flex h-8 w-8 items-center justify-center rounded-md bg-neutral-100 hover:bg-neutral-200 dark:bg-neutral-600 dark:hover:bg-neutral-700 sm:hidden"
|
|
||||||
type="button"
|
|
||||||
onClick={() => removeGame(i)}
|
|
||||||
>
|
|
||||||
<IoCloseOutline className="h-6 w-6 text-gray-900 transition-all duration-200 hover:text-primary dark:text-neutral-400 hover:dark:text-white" />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{deltas[i]?.delta !== undefined && (
|
|
||||||
<div
|
|
||||||
className={twMerge(
|
|
||||||
"mt-2 flex justify-end text-gray-900 dark:text-neutral-400",
|
|
||||||
gameFields.length > 1 && "mr-10",
|
|
||||||
i === deltas.length - 1 && "font-bold",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{Math.round(deltas[i]!.rating)} (
|
|
||||||
<span
|
|
||||||
className={twMerge(
|
|
||||||
deltas[i].delta! > 0 && "text-success",
|
|
||||||
deltas[i].delta! < 0 && "text-error",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{deltas[i]!.delta! >= 0 ? "+" : ""}
|
|
||||||
{deltas[i].delta!}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-8 flex justify-end">
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
disabled={form.formState.isSubmitting}
|
||||||
appendGame({});
|
type="submit"
|
||||||
}}
|
className="rounded-lg border border-transparent bg-primary-600 px-5 py-3 text-center text-sm font-medium text-white hover:bg-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300 disabled:opacity-25 dark:text-white dark:hover:bg-primary-700 dark:focus:ring-primary-800 sm:w-fit"
|
||||||
type="button"
|
|
||||||
className="rounded-lg bg-primary-600 px-5 py-3 text-center text-sm font-medium text-white hover:bg-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300 disabled:opacity-25 dark:text-white dark:hover:bg-primary-700 dark:focus:ring-primary-800 sm:w-fit"
|
|
||||||
>
|
>
|
||||||
<IoAdd className="mr-2 inline-block h-5 w-5" />
|
{t("fetchResultsButton")}
|
||||||
{t("addGameButton")}
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isFetching && (
|
||||||
|
<div className="mt-8 flex justify-center">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<div className="mt-8 text-center text-error">
|
||||||
|
{error.message.startsWith("ERR_")
|
||||||
|
? t(error.message as TranslationKey)
|
||||||
|
: t.rich("unknownError", {
|
||||||
|
contact: (chunks) => (
|
||||||
|
<Link className="underline" href="/contactez-nous">
|
||||||
|
{chunks}
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isFetching && playerOptions.length > 0 && (
|
||||||
|
<div className="grid w-full grid-cols-1 gap-2 sm:grid-cols-2">
|
||||||
|
<SelectField
|
||||||
|
name="player"
|
||||||
|
required
|
||||||
|
label={t("choosePlayerLabel")}
|
||||||
|
placeholder={t("choosePlayerPlaceholder")}
|
||||||
|
options={playerOptions}
|
||||||
|
isClearable={false}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SelectField
|
||||||
|
name="kFactor"
|
||||||
|
label={t("kFactorLabel")}
|
||||||
|
options={["40", "20", "10"].map((k) => ({
|
||||||
|
value: k,
|
||||||
|
label: k,
|
||||||
|
}))}
|
||||||
|
isClearable={false}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
|
|
||||||
<div></div>
|
{hasUrl && !isFetching && player && playerResults && !error && (
|
||||||
|
<TournamentResults
|
||||||
|
playerId={player}
|
||||||
|
kFactor={parseInt(kFactor)}
|
||||||
|
results={allResults ?? []}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{((!hasUrl && !isFetching) || !!error) && (
|
||||||
|
<>
|
||||||
|
<div className="relative my-8">
|
||||||
|
<div className="absolute top-1/2 z-10 h-[1px] w-full bg-gray-500 dark:bg-gray-400" />
|
||||||
|
<div className="relative z-20 mx-auto w-fit bg-white px-2 py-1 text-gray-500 dark:bg-gray-800 dark:text-gray-400">
|
||||||
|
{t("useManualLabel")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ManualEloForm />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,19 +1,156 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
import { fetchTournamentResultsSchema } from "@/schemas";
|
import { fetchTournamentResultsSchema } from "@/schemas";
|
||||||
import { errorLog } from "@/utils/logger";
|
import { errorLog } from "@/utils/logger";
|
||||||
|
|
||||||
import { publicProcedure } from "../trpc";
|
import { publicProcedure } from "../trpc";
|
||||||
|
|
||||||
|
const scrapedSchema = z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
elo: z.string(),
|
||||||
|
results: z.array(
|
||||||
|
z.object({
|
||||||
|
colour: z.enum(["B", "N", ""]),
|
||||||
|
result: z.string(),
|
||||||
|
opponent_name: z.string().nullable(),
|
||||||
|
opponent_elo: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const outputSchema = z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
elo: z.number(),
|
||||||
|
estimated: z.boolean(),
|
||||||
|
national: z.boolean(),
|
||||||
|
results: z.array(
|
||||||
|
z.object({
|
||||||
|
colour: z.enum(["white", "black", ""]),
|
||||||
|
result: z.number().nullable(),
|
||||||
|
lostByForfeit: z.boolean(),
|
||||||
|
wonByForfeit: z.boolean(),
|
||||||
|
opponent: z.string().nullable(),
|
||||||
|
elo: z.number().nullable(),
|
||||||
|
estimated: z.boolean(),
|
||||||
|
national: z.boolean(),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const getEloDetails = (elo: string | null) => {
|
||||||
|
if (elo === null || elo === "") {
|
||||||
|
return { elo: 0, estimated: false, national: false };
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
elo: parseInt(elo),
|
||||||
|
estimated: elo.endsWith("E"),
|
||||||
|
national: elo.endsWith("N"),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getResultDetails = (
|
||||||
|
results: z.infer<typeof scrapedSchema>[number]["results"][number],
|
||||||
|
) => {
|
||||||
|
if (results.opponent_name === null) {
|
||||||
|
return { result: 0, lostByForfeit: true, wonByForfeit: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.result === "<") {
|
||||||
|
return { result: 0, lostByForfeit: true, wonByForfeit: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.result === ">") {
|
||||||
|
return { result: 1, lostByForfeit: false, wonByForfeit: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
result: parseFloat(results.result),
|
||||||
|
lostByForfeit: false,
|
||||||
|
wonByForfeit: false,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const reportFetchError = async (url: string, error: any) => {
|
||||||
|
if (typeof process.env.DISCORD_WEBHOOK_URL === "string") {
|
||||||
|
await fetch(process.env.DISCORD_WEBHOOK_URL as string, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
title: "Error Fetching Tournament Results",
|
||||||
|
fields: [
|
||||||
|
{ name: "url", value: url },
|
||||||
|
{
|
||||||
|
name: "error.message",
|
||||||
|
value: "message" in error ? error.message : "",
|
||||||
|
},
|
||||||
|
{ name: "error", value: JSON.stringify(error, null, 2) },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const fetchTournamentResults = publicProcedure
|
export const fetchTournamentResults = publicProcedure
|
||||||
.input(fetchTournamentResultsSchema)
|
.input(fetchTournamentResultsSchema)
|
||||||
.mutation(async ({ input }) => {
|
.output(outputSchema)
|
||||||
|
.query(async ({ input }) => {
|
||||||
try {
|
try {
|
||||||
console.log(input.url);
|
// Depending on which page the user copied the URL from, we need to extract the tournament ID
|
||||||
|
|
||||||
// Fetch the tournament results using Python
|
// http://echecs.asso.fr/FicheTournoi.aspx?Ref=59975
|
||||||
|
// http://echecs.asso.fr/Resultats.aspx?URL=Tournois/Id/59975/59975&Action=Ls
|
||||||
|
|
||||||
return true;
|
const tournamentId =
|
||||||
|
input.url.match(/Ref=(\d+)/)?.[1] ?? input.url.match(/Id\/(\d+)/)?.[1];
|
||||||
|
|
||||||
|
if (!tournamentId) {
|
||||||
|
throw new Error("ERR_NO_TOURNAMENT_ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawResults = await fetch(
|
||||||
|
`${process.env.RESULTS_SCRAPER_URL}${tournamentId}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const results = await rawResults.json();
|
||||||
|
|
||||||
|
if ("detail" in results && results.detail === "Not found") {
|
||||||
|
throw new Error("ERR_TOURNAMENT_NOT_FOUND");
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedResults = scrapedSchema.parse(results);
|
||||||
|
return parsedResults.map<z.infer<typeof outputSchema>[number]>(
|
||||||
|
(player) => ({
|
||||||
|
id: player.id,
|
||||||
|
name: player.name,
|
||||||
|
...getEloDetails(player.elo),
|
||||||
|
results: player.results.map((result) => ({
|
||||||
|
colour:
|
||||||
|
result.colour === "B"
|
||||||
|
? "white"
|
||||||
|
: result.colour === "N"
|
||||||
|
? "black"
|
||||||
|
: "",
|
||||||
|
opponent: result.opponent_name,
|
||||||
|
...getResultDetails(result),
|
||||||
|
...getEloDetails(result.opponent_elo),
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errorLog(error);
|
reportFetchError(input.url, error);
|
||||||
|
errorLog(JSON.stringify(error, null, 2));
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
export const Spinner = () => {
|
||||||
|
return (
|
||||||
|
<div role="status">
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
className="mr-2 h-8 w-8 animate-spin fill-primary text-gray-200 dark:text-gray-600"
|
||||||
|
viewBox="0 0 100 101"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||||
|
fill="currentFill"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
+138
-164
@@ -1,200 +1,174 @@
|
|||||||
import { Fragment, useRef } from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { Listbox, Transition } from "@headlessui/react";
|
import { flatMap, get, isArray, isNil, isObject } from "lodash";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
import { Controller, useFormContext } from "react-hook-form";
|
||||||
import {
|
import Select, {
|
||||||
IoChevronDown,
|
ActionMeta,
|
||||||
IoCloseOutline,
|
ClassNamesConfig,
|
||||||
IoSearchOutline,
|
GroupBase,
|
||||||
} from "react-icons/io5";
|
OnChangeValue,
|
||||||
|
Props,
|
||||||
|
} from "react-select";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import { Field, FieldProps } from "./Field";
|
import { Field, FieldProps } from "./Field";
|
||||||
|
|
||||||
export type SelectOption = {
|
export type BaseOption<T = string, D = unknown> = {
|
||||||
value: string;
|
value: T;
|
||||||
label: React.ReactNode;
|
label: string | JSX.Element;
|
||||||
selectedLabel?: React.ReactNode;
|
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
data?: D;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SelectFieldProps = FieldProps & {
|
export const classNames = <Option, IsMulti extends boolean = false>(
|
||||||
required?: boolean;
|
hasError: boolean,
|
||||||
placeholder?: string;
|
): ClassNamesConfig<Option, IsMulti, GroupBase<Option>> => ({
|
||||||
noOptionsMessage?: string;
|
container: () => "w-full",
|
||||||
options: SelectOption[];
|
valueContainer: () => "text-gray-900 dark:text-white",
|
||||||
searchable?: boolean;
|
indicatorsContainer: () => "flex items-center self-stretch shrink-0",
|
||||||
listboxClassName?: string;
|
clearIndicator: () =>
|
||||||
dropdownClassName?: string;
|
"pointer-events-none flex items-center pr-2 text-gray-900 dark:text-white",
|
||||||
searchValue?: string;
|
dropdownIndicator: () =>
|
||||||
onChangeSearchValue?: (value: string) => void;
|
"pointer-events-none flex items-center pr-2 text-gray-900 dark:text-white",
|
||||||
onOptionSelected?: (option: SelectOption) => void;
|
indicatorSeparator: () => "w-px text-gray-900 dark:text-white",
|
||||||
};
|
control: (state) =>
|
||||||
|
twMerge(
|
||||||
|
"group flex w-full items-center justify-between rounded-lg border p-3 text-sm",
|
||||||
|
"border-gray-300 bg-gray-50 text-gray-900 shadow-sm focus-within:border-primary-500 focus-within:ring-primary-500",
|
||||||
|
"dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus-within:border-primary-500 dark:focus-within:ring-primary-500",
|
||||||
|
|
||||||
export const SelectField = ({
|
hasError && "ring-1 ring-error",
|
||||||
|
state.isDisabled && "cursor-not-allowed",
|
||||||
|
state.isFocused && "border-primary ring ring-primary ring-opacity-50",
|
||||||
|
),
|
||||||
|
multiValue: () => "bg-fieldGray border rounded-lg flex space-x-1 pl-1 m-1",
|
||||||
|
multiValueLabel: () => "",
|
||||||
|
multiValueRemove: () => "items-center px-1 hover:text-primary",
|
||||||
|
placeholder: () =>
|
||||||
|
"block truncate pr-2 placeholder-gray dark:placeholder-gray-400",
|
||||||
|
menu: () =>
|
||||||
|
twMerge(
|
||||||
|
"!z-10 mt-2 rounded-lg border border-gray-200 bg-white p-1",
|
||||||
|
"border-gray-300 bg-gray-50 text-gray-900",
|
||||||
|
"dark:border-gray-600 dark:bg-gray-700 dark:text-white",
|
||||||
|
),
|
||||||
|
groupHeading: () => "ml-3 mt-2 mb-1 text-textGray text-sm uppercase",
|
||||||
|
option: ({ isFocused, isSelected, isDisabled }) =>
|
||||||
|
twMerge(
|
||||||
|
"px-3 py-2 hover:cursor-pointer",
|
||||||
|
isDisabled && "opacity-50",
|
||||||
|
isFocused && "hover:bg-primary-500 hover:text-white",
|
||||||
|
),
|
||||||
|
noOptionsMessage: () =>
|
||||||
|
"text-textGray p-2 bg-gray-50 border border-dashed border-gray-200 rounded-sm",
|
||||||
|
});
|
||||||
|
|
||||||
|
export type SelectFieldProps<
|
||||||
|
IsMulti extends boolean = false,
|
||||||
|
T = string,
|
||||||
|
D = unknown,
|
||||||
|
> = FieldProps &
|
||||||
|
Omit<
|
||||||
|
Props<BaseOption<T, D>, IsMulti, GroupBase<BaseOption<T, D>>>,
|
||||||
|
"onChange" | "value" | "classNames"
|
||||||
|
> & {
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SelectField = <
|
||||||
|
IsMulti extends boolean = false,
|
||||||
|
T = string,
|
||||||
|
D = unknown,
|
||||||
|
>({
|
||||||
name,
|
name,
|
||||||
label,
|
|
||||||
className,
|
className,
|
||||||
labelClassName,
|
labelClassName,
|
||||||
childrenWrapperClassName,
|
childrenWrapperClassName,
|
||||||
hideErrorMessage = false,
|
label,
|
||||||
|
hideErrorMessage,
|
||||||
required,
|
required,
|
||||||
|
|
||||||
placeholder,
|
placeholder,
|
||||||
noOptionsMessage,
|
|
||||||
options,
|
options,
|
||||||
searchable,
|
...selectProps
|
||||||
searchValue = "",
|
}: SelectFieldProps<IsMulti, T, D>) => {
|
||||||
onChangeSearchValue,
|
const t = useTranslations("App");
|
||||||
onOptionSelected,
|
|
||||||
listboxClassName,
|
|
||||||
dropdownClassName,
|
|
||||||
}: SelectFieldProps) => {
|
|
||||||
const at = useTranslations("App");
|
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
|
|
||||||
// We need to keep track of the selected option to be able to continue to
|
const {
|
||||||
// display it when the user searches for something else
|
formState: { errors },
|
||||||
const curOption = useRef<SelectOption | null>(null);
|
} = form;
|
||||||
|
|
||||||
|
const hasError = !!get(errors, name)?.message;
|
||||||
|
|
||||||
|
const isGroup = (
|
||||||
|
option: BaseOption<T, D> | GroupBase<BaseOption<T, D>>,
|
||||||
|
): option is GroupBase<BaseOption<T, D>> =>
|
||||||
|
isObject(option) && "options" in option;
|
||||||
|
|
||||||
|
const flattenedOptions = flatMap(options, (option) => {
|
||||||
|
return isGroup(option) ? option.options : option;
|
||||||
|
});
|
||||||
|
|
||||||
|
const valueToOption = (value: T): BaseOption<T, D> =>
|
||||||
|
flattenedOptions.find((o) => o.value === value) ?? { value, label: "" };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Field
|
<Field
|
||||||
{...{
|
{...{
|
||||||
name,
|
name,
|
||||||
label,
|
|
||||||
required,
|
|
||||||
className,
|
className,
|
||||||
|
label,
|
||||||
labelClassName,
|
labelClassName,
|
||||||
childrenWrapperClassName,
|
childrenWrapperClassName,
|
||||||
hideErrorMessage,
|
hideErrorMessage,
|
||||||
|
required,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex w-full flex-col">
|
<Controller
|
||||||
<Controller
|
name={name}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name={name}
|
render={({ field: { onChange, value } }) => {
|
||||||
render={({ field: { onChange, value, name } }) => {
|
const onSelectChange = (
|
||||||
const selectedOption =
|
newValue: OnChangeValue<BaseOption<T, D>, IsMulti>,
|
||||||
curOption.current?.value === value
|
actionMeta: ActionMeta<BaseOption<T, D>>,
|
||||||
? curOption.current
|
) => {
|
||||||
: options.find((option) => option.value === value);
|
if (isNil(newValue)) onChange(null);
|
||||||
|
else if (isArray(newValue)) {
|
||||||
|
onChange(newValue.map((option) => option.value));
|
||||||
|
} else onChange((newValue as BaseOption<T, D>).value);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
const optionValue = isNil(value)
|
||||||
<Listbox
|
? null
|
||||||
value={value ?? null}
|
: isArray(value)
|
||||||
name={name}
|
? value.map(valueToOption)
|
||||||
onChange={(value) => {
|
: valueToOption(value);
|
||||||
curOption.current =
|
|
||||||
options.find((option) => option.value === value) ?? null;
|
|
||||||
onChangeSearchValue?.("");
|
|
||||||
onChange(value);
|
|
||||||
onOptionSelected?.(curOption.current!);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ open }) => (
|
|
||||||
<div className="relative w-full">
|
|
||||||
<Listbox.Button
|
|
||||||
className={twMerge(
|
|
||||||
"group flex w-full items-center justify-between rounded-lg border p-3 text-sm",
|
|
||||||
"border-gray-300 bg-gray-50 text-gray-900 shadow-sm focus-within:border-primary-500 focus-within:ring-primary-500",
|
|
||||||
"dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus-within:border-primary-500 dark:focus-within:ring-primary-500",
|
|
||||||
listboxClassName,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<span className="block truncate pr-2 text-gray-900 dark:text-white">
|
|
||||||
{selectedOption?.selectedLabel ??
|
|
||||||
selectedOption?.label ??
|
|
||||||
placeholder ??
|
|
||||||
at("selectPlaceholder")}
|
|
||||||
</span>
|
|
||||||
<span className="pointer-events-none flex items-center pr-2">
|
|
||||||
<IoChevronDown
|
|
||||||
className="h-3 w-3 text-gray-900 dark:text-white"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Listbox.Button>
|
|
||||||
|
|
||||||
<Transition
|
return (
|
||||||
as={Fragment}
|
<Select
|
||||||
show={open}
|
isClearable
|
||||||
leave="transition ease-in duration-200"
|
value={optionValue}
|
||||||
leaveFrom="opacity-100"
|
onChange={onSelectChange}
|
||||||
leaveTo="opacity-0"
|
options={options}
|
||||||
>
|
noOptionsMessage={() => t("noOptionsMessage")}
|
||||||
<div
|
placeholder={placeholder ?? t("selectPlaceholder")}
|
||||||
className={twMerge(
|
unstyled
|
||||||
"absolute z-10 mt-1 flex w-full flex-col overflow-y-hidden rounded border py-3 text-white focus:outline-none [&>ul]:outline-none",
|
styles={{
|
||||||
"border-gray-300 bg-gray-50 text-gray-900",
|
input: (base) => ({
|
||||||
"dark:border-gray-600 dark:bg-gray-700 dark:text-white",
|
...base,
|
||||||
|
"input:focus": {
|
||||||
dropdownClassName,
|
boxShadow: "none",
|
||||||
)}
|
},
|
||||||
>
|
}),
|
||||||
<Listbox.Options className="flex max-h-[180px] flex-1 flex-col justify-stretch">
|
}}
|
||||||
{searchable && (
|
classNames={classNames<BaseOption<T, D>, IsMulti>(hasError)}
|
||||||
<div className="mx-3 mb-4 flex h-[40px] w-auto flex-1 items-center justify-between rounded border px-4 dark:border-neutral-500 dark:bg-neutral-600 focus-within:dark:border-neutral-200">
|
{...selectProps}
|
||||||
<IoSearchOutline
|
/>
|
||||||
width="16px"
|
);
|
||||||
className="h-4 w-4 flex-shrink-0 text-gray-900 dark:text-white"
|
}}
|
||||||
/>
|
/>
|
||||||
<input
|
|
||||||
className="w-full flex-1 border-none bg-transparent ring-0 focus:outline-none focus:ring-0 focus:ring-offset-0"
|
|
||||||
value={searchValue}
|
|
||||||
onChange={
|
|
||||||
onChangeSearchValue
|
|
||||||
? (e) => onChangeSearchValue(e.target.value)
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
placeholder={at("searchPlaceholder")}
|
|
||||||
type="search"
|
|
||||||
/>
|
|
||||||
{searchValue.trim() !== "" && (
|
|
||||||
<button
|
|
||||||
className="flex h-4 w-4 flex-shrink-0 items-center justify-center"
|
|
||||||
type="button"
|
|
||||||
onClick={() => onChangeSearchValue?.("")}
|
|
||||||
>
|
|
||||||
<IoCloseOutline className="h-4 w-4 text-gray-900 transition-all duration-200 dark:text-white" />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{options.length === 0 ? (
|
|
||||||
<div className="w-full text-center">
|
|
||||||
{noOptionsMessage ?? at("noOptionsMessage")}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="flex-1 overflow-scroll">
|
|
||||||
{options.map((option) => (
|
|
||||||
<Listbox.Option
|
|
||||||
key={option.value}
|
|
||||||
value={option.value}
|
|
||||||
disabled={option.disabled}
|
|
||||||
className={twMerge(
|
|
||||||
"w-full px-3 py-2 text-left",
|
|
||||||
!option.disabled &&
|
|
||||||
"hover:bg-primary-500 hover:text-white",
|
|
||||||
option.disabled && "opacity-50",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{option.label}
|
|
||||||
</Listbox.Option>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Listbox.Options>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Listbox>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Field>
|
</Field>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+28
-2
@@ -123,14 +123,40 @@
|
|||||||
"Elo": {
|
"Elo": {
|
||||||
"title": "Elo Calculator",
|
"title": "Elo Calculator",
|
||||||
"info": "Use this calculator to give yourself an idea of your new Elo rating after a tournament.",
|
"info": "Use this calculator to give yourself an idea of your new Elo rating after a tournament.",
|
||||||
|
|
||||||
|
"useManualLabel": "or enter your results manually",
|
||||||
|
|
||||||
"currentEloLabel": "Your current Elo",
|
"currentEloLabel": "Your current Elo",
|
||||||
"currentEloPlaceholder": "Elo",
|
"currentEloPlaceholder": "Elo",
|
||||||
"kFactorLabel": "Your K-Factor",
|
"yourKFactorLabel": "Your K-Factor",
|
||||||
|
"kFactorLabel": "Coefficient",
|
||||||
"kFactorPlaceholder": "K-Factor",
|
"kFactorPlaceholder": "K-Factor",
|
||||||
"resultsTitle": "Results",
|
"resultsTitle": "Results",
|
||||||
"opponentEloPlaceholder": "Opponent Elo",
|
"opponentEloPlaceholder": "Opponent Elo",
|
||||||
"gameResultPlaceholder": "Result...",
|
"gameResultPlaceholder": "Result...",
|
||||||
"gameResult": "{result, select, win {Win} draw {Draw} loss {Loss} other {{result}}}",
|
"gameResult": "{result, select, win {Win} draw {Draw} loss {Loss} other {{result}}}",
|
||||||
"addGameButton": "Add another game result"
|
"addGameButton": "Add another game result",
|
||||||
|
|
||||||
|
"resultsUrlLabel": "Paste a link to the FFE results page",
|
||||||
|
"resultsUrlPlaceholder": "https://echecs.asso.fr/Resultats.aspx?URL=Tournois/Id/12345/12345&Action=Ga",
|
||||||
|
"fetchResultsButton": "Fetch",
|
||||||
|
"enterManualResultsButton": "Enter results manually",
|
||||||
|
"choosePlayerLabel": "Choose a player",
|
||||||
|
"choosePlayerPlaceholder": "Player",
|
||||||
|
"needRating": "This calculator requires an initial FIDE rating. The selected player has either an estimated rating or a National rating.",
|
||||||
|
"forfeit": "Forfeit",
|
||||||
|
"vs": " vs ",
|
||||||
|
"wonByForfeit": "Won by forfeit",
|
||||||
|
"lostByForfeit": "Lost by forfeit",
|
||||||
|
"draw": "½ - ½",
|
||||||
|
"whiteWin": "1 - 0",
|
||||||
|
"blackWin": "0 - 1",
|
||||||
|
"initialRating": "Your initial Rating: {rating}",
|
||||||
|
"finalRating": "Final Rating: {rating} (<delta></delta>)",
|
||||||
|
"noChangeInfo": "Note that {noChangeCount, plural, one {one of your games} other {# of your games}} resulted in no change to the Elo. Forfeited games and games played against players that do not yet have a FIDE rating are not included in the calculation.",
|
||||||
|
|
||||||
|
"unknownError": "We were unable to fetch results from this URL. Please <contact>contact us</contact> if the problem persists.",
|
||||||
|
"ERR_TOURNAMENT_NOT_FOUND": "Tournament not found",
|
||||||
|
"ERR_NO_TOURNAMENT_ID": "The link you provided is incorrect"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-3
@@ -125,9 +125,13 @@
|
|||||||
|
|
||||||
"Elo": {
|
"Elo": {
|
||||||
"title": "Calculette Elo",
|
"title": "Calculette Elo",
|
||||||
"info": "Utilisez ce calculateur pour vous donner une idée de votre nouveau classement Elo après un tournoi.",
|
"info": "Utilisez ce calculateur pour estimer votre nouveau classement Elo après un tournoi.",
|
||||||
|
|
||||||
|
"useManualLabel": "ou saisissez vos résultats manuellement",
|
||||||
|
|
||||||
"currentEloLabel": "Votre Elo actuel",
|
"currentEloLabel": "Votre Elo actuel",
|
||||||
"currentEloPlaceholder": "Elo",
|
"currentEloPlaceholder": "Elo",
|
||||||
|
"yourKFactorLabel": "Votre coefficient",
|
||||||
"kFactorLabel": "Coefficient",
|
"kFactorLabel": "Coefficient",
|
||||||
"resultsTitle": "Résultats",
|
"resultsTitle": "Résultats",
|
||||||
"opponentEloPlaceholder": "Classement de l'adversaire",
|
"opponentEloPlaceholder": "Classement de l'adversaire",
|
||||||
@@ -135,8 +139,26 @@
|
|||||||
"gameResult": "{result, select, win {Victoire} draw {Match nul} loss {Défaite} other {{result}}}",
|
"gameResult": "{result, select, win {Victoire} draw {Match nul} loss {Défaite} other {{result}}}",
|
||||||
"addGameButton": "Ajouter un autre résultat de partie",
|
"addGameButton": "Ajouter un autre résultat de partie",
|
||||||
|
|
||||||
"resultsUrlLabel": "Paste a link to the FFE results page",
|
"resultsUrlLabel": "Collez un lien vers la page de résultats de la FFE",
|
||||||
"resultsUrlPlaceholder": "https://echecs.asso.fr/Resultats.aspx?URL=Tournois/Id/12345/12345&Action=Ga",
|
"resultsUrlPlaceholder": "https://echecs.asso.fr/Resultats.aspx?URL=Tournois/Id/12345/12345&Action=Ga",
|
||||||
"fetchResultsButton": "Fetch"
|
"fetchResultsButton": "Récupérer",
|
||||||
|
"enterManualResultsButton": "Saisir les résultats manuellement",
|
||||||
|
"choosePlayerLabel": "Choisissez un joueur",
|
||||||
|
"choosePlayerPlaceholder": "Joueur",
|
||||||
|
"needRating": "Ce calculateur nécessite un classement FIDE initial. Le joueur sélectionné a soit un classement estimé, soit un classement national.",
|
||||||
|
"forfeit": "Forfait",
|
||||||
|
"vs": " - ",
|
||||||
|
"wonByForfeit": "Gagné par forfait",
|
||||||
|
"lostByForfeit": "Perdu par forfait",
|
||||||
|
"draw": "½ - ½",
|
||||||
|
"whiteWin": "1 - 0",
|
||||||
|
"blackWin": "0 - 1",
|
||||||
|
"initialRating": "Votre classement initial : {rating}",
|
||||||
|
"finalRating": "Classement final : {rating} (<delta></delta>)",
|
||||||
|
"noChangeInfo": "Notez que {noChangeCount, plural, one {une de vos parties} other {# de vos parties}} n'a pas modifié l'Elo. Les parties perdues par forfait et les parties jouées contre des joueurs qui n'ont pas encore de classement FIDE ne sont pas prises en compte dans le calcul.",
|
||||||
|
|
||||||
|
"unknownError": "Nous n'avons pas pu récupérer les résultats à partir de cette URL. Veuillez <contact>nous contacter</contact> si le problème persiste.",
|
||||||
|
"ERR_TOURNAMENT_NOT_FOUND": "Tournoi introuvable",
|
||||||
|
"ERR_NO_TOURNAMENT_ID": "L'identifiant du tournoi fourni est incorrect"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+306
-9
@@ -43,6 +43,7 @@
|
|||||||
"react-input-mask": "^2.0.4",
|
"react-input-mask": "^2.0.4",
|
||||||
"react-leaflet": "^4.2.1",
|
"react-leaflet": "^4.2.1",
|
||||||
"react-leaflet-cluster": "^2.1.0",
|
"react-leaflet-cluster": "^2.1.0",
|
||||||
|
"react-select": "^5.7.4",
|
||||||
"react-tooltip": "^5.18.0",
|
"react-tooltip": "^5.18.0",
|
||||||
"sharp": "^0.32.3",
|
"sharp": "^0.32.3",
|
||||||
"superjson": "^1.13.1",
|
"superjson": "^1.13.1",
|
||||||
@@ -241,6 +242,30 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/helper-module-imports": {
|
||||||
|
"version": "7.22.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
|
||||||
|
"integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.22.15"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-module-imports/node_modules/@babel/types": {
|
||||||
|
"version": "7.22.19",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz",
|
||||||
|
"integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-string-parser": "^7.22.5",
|
||||||
|
"@babel/helper-validator-identifier": "^7.22.19",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/helper-split-export-declaration": {
|
"node_modules/@babel/helper-split-export-declaration": {
|
||||||
"version": "7.22.6",
|
"version": "7.22.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
||||||
@@ -274,9 +299,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-validator-identifier": {
|
"node_modules/@babel/helper-validator-identifier": {
|
||||||
"version": "7.22.15",
|
"version": "7.22.20",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||||
"integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==",
|
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
@@ -438,6 +463,109 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@emotion/babel-plugin": {
|
||||||
|
"version": "11.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
|
||||||
|
"integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-module-imports": "^7.16.7",
|
||||||
|
"@babel/runtime": "^7.18.3",
|
||||||
|
"@emotion/hash": "^0.9.1",
|
||||||
|
"@emotion/memoize": "^0.8.1",
|
||||||
|
"@emotion/serialize": "^1.1.2",
|
||||||
|
"babel-plugin-macros": "^3.1.0",
|
||||||
|
"convert-source-map": "^1.5.0",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"find-root": "^1.1.0",
|
||||||
|
"source-map": "^0.5.7",
|
||||||
|
"stylis": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/cache": {
|
||||||
|
"version": "11.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
|
||||||
|
"integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/memoize": "^0.8.1",
|
||||||
|
"@emotion/sheet": "^1.2.2",
|
||||||
|
"@emotion/utils": "^1.2.1",
|
||||||
|
"@emotion/weak-memoize": "^0.3.1",
|
||||||
|
"stylis": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/hash": {
|
||||||
|
"version": "0.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
|
||||||
|
"integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/memoize": {
|
||||||
|
"version": "0.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
|
||||||
|
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/react": {
|
||||||
|
"version": "11.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz",
|
||||||
|
"integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.18.3",
|
||||||
|
"@emotion/babel-plugin": "^11.11.0",
|
||||||
|
"@emotion/cache": "^11.11.0",
|
||||||
|
"@emotion/serialize": "^1.1.2",
|
||||||
|
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
|
||||||
|
"@emotion/utils": "^1.2.1",
|
||||||
|
"@emotion/weak-memoize": "^0.3.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/serialize": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/hash": "^0.9.1",
|
||||||
|
"@emotion/memoize": "^0.8.1",
|
||||||
|
"@emotion/unitless": "^0.8.1",
|
||||||
|
"@emotion/utils": "^1.2.1",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/sheet": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/unitless": {
|
||||||
|
"version": "0.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
|
||||||
|
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/utils": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg=="
|
||||||
|
},
|
||||||
|
"node_modules/@emotion/weak-memoize": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
|
||||||
|
"integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww=="
|
||||||
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||||
@@ -1244,6 +1372,11 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/parse-json": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
|
||||||
|
},
|
||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
"version": "15.7.5",
|
"version": "15.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||||
@@ -1288,6 +1421,14 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-transition-group": {
|
||||||
|
"version": "4.4.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
|
||||||
|
"integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/scheduler": {
|
"node_modules/@types/scheduler": {
|
||||||
"version": "0.16.3",
|
"version": "0.16.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
||||||
@@ -1734,6 +1875,20 @@
|
|||||||
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
|
||||||
"integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
|
"integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/babel-plugin-macros": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"cosmiconfig": "^7.0.0",
|
||||||
|
"resolve": "^1.19.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10",
|
||||||
|
"npm": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
@@ -1886,7 +2041,6 @@
|
|||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@@ -2033,6 +2187,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/convert-source-map": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
|
||||||
|
},
|
||||||
"node_modules/copy-anything": {
|
"node_modules/copy-anything": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
|
||||||
@@ -2047,6 +2206,29 @@
|
|||||||
"url": "https://github.com/sponsors/mesqueeb"
|
"url": "https://github.com/sponsors/mesqueeb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cosmiconfig": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/parse-json": "^4.0.0",
|
||||||
|
"import-fresh": "^3.2.1",
|
||||||
|
"parse-json": "^5.0.0",
|
||||||
|
"path-type": "^4.0.0",
|
||||||
|
"yaml": "^1.10.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cosmiconfig/node_modules/yaml": {
|
||||||
|
"version": "1.10.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||||
|
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
@@ -2265,6 +2447,15 @@
|
|||||||
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/dom-helpers": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.8.7",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/duplexer": {
|
"node_modules/duplexer": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
||||||
@@ -2302,6 +2493,19 @@
|
|||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/error-ex": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||||
|
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||||
|
"dependencies": {
|
||||||
|
"is-arrayish": "^0.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/error-ex/node_modules/is-arrayish": {
|
||||||
|
"version": "0.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||||
|
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
|
||||||
|
},
|
||||||
"node_modules/es-abstract": {
|
"node_modules/es-abstract": {
|
||||||
"version": "1.22.1",
|
"version": "1.22.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
|
||||||
@@ -2449,7 +2653,6 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
@@ -3018,6 +3221,11 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/find-root": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
|
||||||
|
},
|
||||||
"node_modules/find-up": {
|
"node_modules/find-up": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||||
@@ -3373,6 +3581,19 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hoist-non-react-statics": {
|
||||||
|
"version": "3.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||||
|
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||||
|
"dependencies": {
|
||||||
|
"react-is": "^16.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hoist-non-react-statics/node_modules/react-is": {
|
||||||
|
"version": "16.13.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
|
},
|
||||||
"node_modules/ieee754": {
|
"node_modules/ieee754": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
@@ -3405,7 +3626,6 @@
|
|||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"parent-module": "^1.0.0",
|
"parent-module": "^1.0.0",
|
||||||
"resolve-from": "^4.0.0"
|
"resolve-from": "^4.0.0"
|
||||||
@@ -3953,6 +4173,11 @@
|
|||||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/json-parse-even-better-errors": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
|
||||||
|
},
|
||||||
"node_modules/json-schema-traverse": {
|
"node_modules/json-schema-traverse": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||||
@@ -4122,6 +4347,11 @@
|
|||||||
"lz-string": "bin/bin.js"
|
"lz-string": "bin/bin.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/memoize-one": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
||||||
|
},
|
||||||
"node_modules/memory-pager": {
|
"node_modules/memory-pager": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||||
@@ -4646,7 +4876,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"callsites": "^3.0.0"
|
"callsites": "^3.0.0"
|
||||||
},
|
},
|
||||||
@@ -4654,6 +4883,23 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/parse-json": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.0.0",
|
||||||
|
"error-ex": "^1.3.1",
|
||||||
|
"json-parse-even-better-errors": "^2.3.0",
|
||||||
|
"lines-and-columns": "^1.1.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-exists": {
|
"node_modules/path-exists": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
@@ -4689,7 +4935,6 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@@ -5241,6 +5486,26 @@
|
|||||||
"react-dom": "^16.8.0 || ^17 || ^18"
|
"react-dom": "^16.8.0 || ^17 || ^18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-select": {
|
||||||
|
"version": "5.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.4.tgz",
|
||||||
|
"integrity": "sha512-NhuE56X+p9QDFh4BgeygHFIvJJszO1i1KSkg/JPcIJrbovyRtI+GuOEa4XzFCEpZRAEoEI8u/cAHK+jG/PgUzQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.0",
|
||||||
|
"@emotion/cache": "^11.4.0",
|
||||||
|
"@emotion/react": "^11.8.1",
|
||||||
|
"@floating-ui/dom": "^1.0.1",
|
||||||
|
"@types/react-transition-group": "^4.4.0",
|
||||||
|
"memoize-one": "^6.0.0",
|
||||||
|
"prop-types": "^15.6.0",
|
||||||
|
"react-transition-group": "^4.3.0",
|
||||||
|
"use-isomorphic-layout-effect": "^1.1.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-tooltip": {
|
"node_modules/react-tooltip": {
|
||||||
"version": "5.21.3",
|
"version": "5.21.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.21.3.tgz",
|
||||||
@@ -5254,6 +5519,21 @@
|
|||||||
"react-dom": ">=16.14.0"
|
"react-dom": ">=16.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-transition-group": {
|
||||||
|
"version": "4.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||||
|
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.5.5",
|
||||||
|
"dom-helpers": "^5.0.1",
|
||||||
|
"loose-envify": "^1.4.0",
|
||||||
|
"prop-types": "^15.6.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.6.0",
|
||||||
|
"react-dom": ">=16.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
@@ -5361,7 +5641,6 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
@@ -5859,6 +6138,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/stylis": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
|
||||||
|
},
|
||||||
"node_modules/sucrase": {
|
"node_modules/sucrase": {
|
||||||
"version": "3.34.0",
|
"version": "3.34.0",
|
||||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
|
||||||
@@ -6280,6 +6564,19 @@
|
|||||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-isomorphic-layout-effect": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/use-sync-external-store": {
|
"node_modules/use-sync-external-store": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
"react-input-mask": "^2.0.4",
|
"react-input-mask": "^2.0.4",
|
||||||
"react-leaflet": "^4.2.1",
|
"react-leaflet": "^4.2.1",
|
||||||
"react-leaflet-cluster": "^2.1.0",
|
"react-leaflet-cluster": "^2.1.0",
|
||||||
|
"react-select": "^5.7.4",
|
||||||
"react-tooltip": "^5.18.0",
|
"react-tooltip": "^5.18.0",
|
||||||
"sharp": "^0.32.3",
|
"sharp": "^0.32.3",
|
||||||
"superjson": "^1.13.1",
|
"superjson": "^1.13.1",
|
||||||
|
|||||||
@@ -6,4 +6,6 @@ import type { AppRouter } from "@/app/server/appRouter";
|
|||||||
export type APIRouterInput = inferRouterInputs<AppRouter>;
|
export type APIRouterInput = inferRouterInputs<AppRouter>;
|
||||||
export type APIRouterOutput = inferRouterOutputs<AppRouter>;
|
export type APIRouterOutput = inferRouterOutputs<AppRouter>;
|
||||||
|
|
||||||
|
export type TournamentResultsData = APIRouterOutput["fetchTournamentResults"];
|
||||||
|
|
||||||
export const trpc = createTRPCReact<AppRouter>();
|
export const trpc = createTRPCReact<AppRouter>();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz"
|
resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz"
|
||||||
integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
|
integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
|
||||||
|
|
||||||
"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13":
|
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13":
|
||||||
version "7.22.13"
|
version "7.22.13"
|
||||||
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz"
|
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz"
|
||||||
integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
|
integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
|
||||||
@@ -54,6 +54,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.22.5"
|
"@babel/types" "^7.22.5"
|
||||||
|
|
||||||
|
"@babel/helper-module-imports@^7.16.7":
|
||||||
|
version "7.22.15"
|
||||||
|
resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz"
|
||||||
|
integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.22.15"
|
||||||
|
|
||||||
"@babel/helper-split-export-declaration@^7.16.7":
|
"@babel/helper-split-export-declaration@^7.16.7":
|
||||||
version "7.22.6"
|
version "7.22.6"
|
||||||
resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz"
|
resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz"
|
||||||
@@ -66,10 +73,10 @@
|
|||||||
resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz"
|
resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz"
|
||||||
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
|
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
|
||||||
|
|
||||||
"@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.22.15", "@babel/helper-validator-identifier@^7.22.5":
|
"@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.22.15", "@babel/helper-validator-identifier@^7.22.19", "@babel/helper-validator-identifier@^7.22.5":
|
||||||
version "7.22.15"
|
version "7.22.20"
|
||||||
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz"
|
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz"
|
||||||
integrity sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==
|
integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
|
||||||
|
|
||||||
"@babel/highlight@^7.22.13":
|
"@babel/highlight@^7.22.13":
|
||||||
version "7.22.13"
|
version "7.22.13"
|
||||||
@@ -85,7 +92,7 @@
|
|||||||
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz"
|
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz"
|
||||||
integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==
|
integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==
|
||||||
|
|
||||||
"@babel/runtime@^7.12.5", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.9.2":
|
"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||||
version "7.22.15"
|
version "7.22.15"
|
||||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz"
|
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz"
|
||||||
integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==
|
integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==
|
||||||
@@ -126,12 +133,12 @@
|
|||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@babel/types@^7.22.15":
|
"@babel/types@^7.22.15":
|
||||||
version "7.22.17"
|
version "7.22.19"
|
||||||
resolved "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz"
|
resolved "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz"
|
||||||
integrity sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==
|
integrity sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-string-parser" "^7.22.5"
|
"@babel/helper-string-parser" "^7.22.5"
|
||||||
"@babel/helper-validator-identifier" "^7.22.15"
|
"@babel/helper-validator-identifier" "^7.22.19"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@babel/types@^7.22.5":
|
"@babel/types@^7.22.5":
|
||||||
@@ -143,6 +150,94 @@
|
|||||||
"@babel/helper-validator-identifier" "^7.22.15"
|
"@babel/helper-validator-identifier" "^7.22.15"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@emotion/babel-plugin@^11.11.0":
|
||||||
|
version "11.11.0"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz"
|
||||||
|
integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-module-imports" "^7.16.7"
|
||||||
|
"@babel/runtime" "^7.18.3"
|
||||||
|
"@emotion/hash" "^0.9.1"
|
||||||
|
"@emotion/memoize" "^0.8.1"
|
||||||
|
"@emotion/serialize" "^1.1.2"
|
||||||
|
babel-plugin-macros "^3.1.0"
|
||||||
|
convert-source-map "^1.5.0"
|
||||||
|
escape-string-regexp "^4.0.0"
|
||||||
|
find-root "^1.1.0"
|
||||||
|
source-map "^0.5.7"
|
||||||
|
stylis "4.2.0"
|
||||||
|
|
||||||
|
"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0":
|
||||||
|
version "11.11.0"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz"
|
||||||
|
integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/memoize" "^0.8.1"
|
||||||
|
"@emotion/sheet" "^1.2.2"
|
||||||
|
"@emotion/utils" "^1.2.1"
|
||||||
|
"@emotion/weak-memoize" "^0.3.1"
|
||||||
|
stylis "4.2.0"
|
||||||
|
|
||||||
|
"@emotion/hash@^0.9.1":
|
||||||
|
version "0.9.1"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz"
|
||||||
|
integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==
|
||||||
|
|
||||||
|
"@emotion/memoize@^0.8.1":
|
||||||
|
version "0.8.1"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz"
|
||||||
|
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
|
||||||
|
|
||||||
|
"@emotion/react@^11.8.1":
|
||||||
|
version "11.11.1"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz"
|
||||||
|
integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.18.3"
|
||||||
|
"@emotion/babel-plugin" "^11.11.0"
|
||||||
|
"@emotion/cache" "^11.11.0"
|
||||||
|
"@emotion/serialize" "^1.1.2"
|
||||||
|
"@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
|
||||||
|
"@emotion/utils" "^1.2.1"
|
||||||
|
"@emotion/weak-memoize" "^0.3.1"
|
||||||
|
hoist-non-react-statics "^3.3.1"
|
||||||
|
|
||||||
|
"@emotion/serialize@^1.1.2":
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz"
|
||||||
|
integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/hash" "^0.9.1"
|
||||||
|
"@emotion/memoize" "^0.8.1"
|
||||||
|
"@emotion/unitless" "^0.8.1"
|
||||||
|
"@emotion/utils" "^1.2.1"
|
||||||
|
csstype "^3.0.2"
|
||||||
|
|
||||||
|
"@emotion/sheet@^1.2.2":
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz"
|
||||||
|
integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==
|
||||||
|
|
||||||
|
"@emotion/unitless@^0.8.1":
|
||||||
|
version "0.8.1"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz"
|
||||||
|
integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==
|
||||||
|
|
||||||
|
"@emotion/use-insertion-effect-with-fallbacks@^1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz"
|
||||||
|
integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==
|
||||||
|
|
||||||
|
"@emotion/utils@^1.2.1":
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz"
|
||||||
|
integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==
|
||||||
|
|
||||||
|
"@emotion/weak-memoize@^0.3.1":
|
||||||
|
version "0.3.1"
|
||||||
|
resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz"
|
||||||
|
integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
|
||||||
|
|
||||||
"@eslint-community/eslint-utils@^4.2.0":
|
"@eslint-community/eslint-utils@^4.2.0":
|
||||||
version "4.4.0"
|
version "4.4.0"
|
||||||
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
|
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
|
||||||
@@ -182,7 +277,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@floating-ui/utils" "^0.1.1"
|
"@floating-ui/utils" "^0.1.1"
|
||||||
|
|
||||||
"@floating-ui/dom@^1.0.0":
|
"@floating-ui/dom@^1.0.0", "@floating-ui/dom@^1.0.1":
|
||||||
version "1.5.2"
|
version "1.5.2"
|
||||||
resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.2.tgz"
|
resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.2.tgz"
|
||||||
integrity sha512-6ArmenS6qJEWmwzczWyhvrXRdI/rI78poBcW0h/456+onlabit+2G+QxHx5xTOX60NBJQXjsCLFbW2CmsXpUog==
|
integrity sha512-6ArmenS6qJEWmwzczWyhvrXRdI/rI78poBcW0h/456+onlabit+2G+QxHx5xTOX60NBJQXjsCLFbW2CmsXpUog==
|
||||||
@@ -543,6 +638,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/parse-json@^4.0.0":
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz"
|
||||||
|
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
|
||||||
|
|
||||||
"@types/prop-types@*":
|
"@types/prop-types@*":
|
||||||
version "15.7.5"
|
version "15.7.5"
|
||||||
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
|
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
|
||||||
@@ -572,6 +672,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-transition-group@^4.4.0":
|
||||||
|
version "4.4.6"
|
||||||
|
resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz"
|
||||||
|
integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@>=17.0.0", "@types/react@18.2.21":
|
"@types/react@*", "@types/react@>=17.0.0", "@types/react@18.2.21":
|
||||||
version "18.2.21"
|
version "18.2.21"
|
||||||
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz"
|
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz"
|
||||||
@@ -860,6 +967,15 @@ b4a@^1.6.4:
|
|||||||
resolved "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz"
|
resolved "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz"
|
||||||
integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==
|
integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==
|
||||||
|
|
||||||
|
babel-plugin-macros@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz"
|
||||||
|
integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.12.5"
|
||||||
|
cosmiconfig "^7.0.0"
|
||||||
|
resolve "^1.19.0"
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
|
||||||
@@ -1070,6 +1186,11 @@ concat-map@0.0.1:
|
|||||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||||
|
|
||||||
|
convert-source-map@^1.5.0:
|
||||||
|
version "1.9.0"
|
||||||
|
resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz"
|
||||||
|
integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
|
||||||
|
|
||||||
copy-anything@^3.0.2:
|
copy-anything@^3.0.2:
|
||||||
version "3.0.5"
|
version "3.0.5"
|
||||||
resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz"
|
resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz"
|
||||||
@@ -1077,6 +1198,17 @@ copy-anything@^3.0.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-what "^4.1.8"
|
is-what "^4.1.8"
|
||||||
|
|
||||||
|
cosmiconfig@^7.0.0:
|
||||||
|
version "7.1.0"
|
||||||
|
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz"
|
||||||
|
integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==
|
||||||
|
dependencies:
|
||||||
|
"@types/parse-json" "^4.0.0"
|
||||||
|
import-fresh "^3.2.1"
|
||||||
|
parse-json "^5.0.0"
|
||||||
|
path-type "^4.0.0"
|
||||||
|
yaml "^1.10.0"
|
||||||
|
|
||||||
cross-spawn@^7.0.2:
|
cross-spawn@^7.0.2:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
|
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
|
||||||
@@ -1232,6 +1364,14 @@ dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9:
|
|||||||
resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz"
|
resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz"
|
||||||
integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==
|
integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==
|
||||||
|
|
||||||
|
dom-helpers@^5.0.1:
|
||||||
|
version "5.2.1"
|
||||||
|
resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz"
|
||||||
|
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.8.7"
|
||||||
|
csstype "^3.0.2"
|
||||||
|
|
||||||
duplexer@^0.1.2:
|
duplexer@^0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz"
|
resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz"
|
||||||
@@ -1262,6 +1402,13 @@ enhanced-resolve@^5.12.0:
|
|||||||
graceful-fs "^4.2.4"
|
graceful-fs "^4.2.4"
|
||||||
tapable "^2.2.0"
|
tapable "^2.2.0"
|
||||||
|
|
||||||
|
error-ex@^1.3.1:
|
||||||
|
version "1.3.2"
|
||||||
|
resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz"
|
||||||
|
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
|
||||||
|
dependencies:
|
||||||
|
is-arrayish "^0.2.1"
|
||||||
|
|
||||||
es-abstract@^1.22.1:
|
es-abstract@^1.22.1:
|
||||||
version "1.22.1"
|
version "1.22.1"
|
||||||
resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz"
|
resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz"
|
||||||
@@ -1654,6 +1801,11 @@ fill-range@^7.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
to-regex-range "^5.0.1"
|
to-regex-range "^5.0.1"
|
||||||
|
|
||||||
|
find-root@^1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz"
|
||||||
|
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
|
||||||
|
|
||||||
find-up@^5.0.0:
|
find-up@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
|
resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
|
||||||
@@ -1904,6 +2056,13 @@ has@^1.0.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
function-bind "^1.1.1"
|
function-bind "^1.1.1"
|
||||||
|
|
||||||
|
hoist-non-react-statics@^3.3.1:
|
||||||
|
version "3.3.2"
|
||||||
|
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
|
||||||
|
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||||
|
dependencies:
|
||||||
|
react-is "^16.7.0"
|
||||||
|
|
||||||
ieee754@^1.1.13:
|
ieee754@^1.1.13:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
|
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
|
||||||
@@ -1998,6 +2157,11 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2:
|
|||||||
get-intrinsic "^1.2.0"
|
get-intrinsic "^1.2.0"
|
||||||
is-typed-array "^1.1.10"
|
is-typed-array "^1.1.10"
|
||||||
|
|
||||||
|
is-arrayish@^0.2.1:
|
||||||
|
version "0.2.1"
|
||||||
|
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
|
||||||
|
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
|
||||||
|
|
||||||
is-arrayish@^0.3.1:
|
is-arrayish@^0.3.1:
|
||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz"
|
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz"
|
||||||
@@ -2227,6 +2391,11 @@ json-buffer@3.0.1:
|
|||||||
resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz"
|
resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz"
|
||||||
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
|
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
|
||||||
|
|
||||||
|
json-parse-even-better-errors@^2.3.0:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz"
|
||||||
|
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
|
||||||
|
|
||||||
json-schema-traverse@^0.4.1:
|
json-schema-traverse@^0.4.1:
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
|
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
|
||||||
@@ -2347,6 +2516,11 @@ lz-string@^1.5.0:
|
|||||||
resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz"
|
resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz"
|
||||||
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==
|
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==
|
||||||
|
|
||||||
|
memoize-one@^6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz"
|
||||||
|
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
|
||||||
|
|
||||||
memory-pager@^1.0.2:
|
memory-pager@^1.0.2:
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz"
|
resolved "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz"
|
||||||
@@ -2649,6 +2823,16 @@ parent-module@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
callsites "^3.0.0"
|
callsites "^3.0.0"
|
||||||
|
|
||||||
|
parse-json@^5.0.0:
|
||||||
|
version "5.2.0"
|
||||||
|
resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz"
|
||||||
|
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.0.0"
|
||||||
|
error-ex "^1.3.1"
|
||||||
|
json-parse-even-better-errors "^2.3.0"
|
||||||
|
lines-and-columns "^1.1.6"
|
||||||
|
|
||||||
path-exists@^4.0.0:
|
path-exists@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
|
resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
|
||||||
@@ -2798,7 +2982,7 @@ pretty-format@^27.0.2:
|
|||||||
ansi-styles "^5.0.0"
|
ansi-styles "^5.0.0"
|
||||||
react-is "^17.0.1"
|
react-is "^17.0.1"
|
||||||
|
|
||||||
prop-types@^15.7.2, prop-types@^15.8.1:
|
prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||||
version "15.8.1"
|
version "15.8.1"
|
||||||
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
|
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
|
||||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||||
@@ -2852,7 +3036,7 @@ react-datepicker@^4.17.0:
|
|||||||
react-onclickoutside "^6.13.0"
|
react-onclickoutside "^6.13.0"
|
||||||
react-popper "^2.3.0"
|
react-popper "^2.3.0"
|
||||||
|
|
||||||
"react-dom@^15.5.x || ^16.x || ^17.x || ^18.x", "react-dom@^16 || ^17 || ^18", "react-dom@^16.8.0 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.9.0 || ^17 || ^18", react-dom@^18.0.0, react-dom@^18.2.0, react-dom@>=0.14.0, react-dom@>=16.14.0, react-dom@>=16.8.0:
|
"react-dom@^15.5.x || ^16.x || ^17.x || ^18.x", "react-dom@^16 || ^17 || ^18", "react-dom@^16.8.0 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.9.0 || ^17 || ^18", react-dom@^18.0.0, react-dom@^18.2.0, react-dom@>=0.14.0, react-dom@>=16.14.0, react-dom@>=16.6.0, react-dom@>=16.8.0:
|
||||||
version "18.2.0"
|
version "18.2.0"
|
||||||
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
|
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
|
||||||
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
|
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
|
||||||
@@ -2888,6 +3072,11 @@ react-is@^16.13.1:
|
|||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-is@^16.7.0:
|
||||||
|
version "16.13.1"
|
||||||
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
||||||
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
react-is@^17.0.1:
|
react-is@^17.0.1:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
|
||||||
@@ -2920,6 +3109,21 @@ react-popper@^2.2.5, react-popper@^2.3.0:
|
|||||||
react-fast-compare "^3.0.1"
|
react-fast-compare "^3.0.1"
|
||||||
warning "^4.0.2"
|
warning "^4.0.2"
|
||||||
|
|
||||||
|
react-select@^5.7.4:
|
||||||
|
version "5.7.4"
|
||||||
|
resolved "https://registry.npmjs.org/react-select/-/react-select-5.7.4.tgz"
|
||||||
|
integrity sha512-NhuE56X+p9QDFh4BgeygHFIvJJszO1i1KSkg/JPcIJrbovyRtI+GuOEa4XzFCEpZRAEoEI8u/cAHK+jG/PgUzQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.12.0"
|
||||||
|
"@emotion/cache" "^11.4.0"
|
||||||
|
"@emotion/react" "^11.8.1"
|
||||||
|
"@floating-ui/dom" "^1.0.1"
|
||||||
|
"@types/react-transition-group" "^4.4.0"
|
||||||
|
memoize-one "^6.0.0"
|
||||||
|
prop-types "^15.6.0"
|
||||||
|
react-transition-group "^4.3.0"
|
||||||
|
use-isomorphic-layout-effect "^1.1.2"
|
||||||
|
|
||||||
react-tooltip@^5.18.0:
|
react-tooltip@^5.18.0:
|
||||||
version "5.21.3"
|
version "5.21.3"
|
||||||
resolved "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.21.3.tgz"
|
resolved "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.21.3.tgz"
|
||||||
@@ -2928,7 +3132,17 @@ react-tooltip@^5.18.0:
|
|||||||
"@floating-ui/dom" "^1.0.0"
|
"@floating-ui/dom" "^1.0.0"
|
||||||
classnames "^2.3.0"
|
classnames "^2.3.0"
|
||||||
|
|
||||||
react@*, "react@^15.5.x || ^16.x || ^17.x || ^18.x", "react@^16 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17 || ^18", react@^18.0.0, react@^18.2.0, "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=0.14.0, react@>=16.14.0, react@>=16.8, react@>=16.8.0, react@>=17.0.0:
|
react-transition-group@^4.3.0:
|
||||||
|
version "4.4.5"
|
||||||
|
resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz"
|
||||||
|
integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.5.5"
|
||||||
|
dom-helpers "^5.0.1"
|
||||||
|
loose-envify "^1.4.0"
|
||||||
|
prop-types "^15.6.2"
|
||||||
|
|
||||||
|
react@*, "react@^15.5.x || ^16.x || ^17.x || ^18.x", "react@^16 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.9.0 || ^17 || ^18", react@^18.0.0, react@^18.2.0, "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=0.14.0, react@>=16.14.0, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=17.0.0:
|
||||||
version "18.2.0"
|
version "18.2.0"
|
||||||
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
||||||
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
||||||
@@ -3002,7 +3216,7 @@ resolve-pkg-maps@^1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz"
|
resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz"
|
||||||
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
|
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
|
||||||
|
|
||||||
resolve@^1.1.7, resolve@^1.22.2, resolve@^1.22.4:
|
resolve@^1.1.7, resolve@^1.19.0, resolve@^1.22.2, resolve@^1.22.4:
|
||||||
version "1.22.4"
|
version "1.22.4"
|
||||||
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz"
|
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz"
|
||||||
integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==
|
integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==
|
||||||
@@ -3189,7 +3403,7 @@ source-map-js@^1.0.2:
|
|||||||
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
|
||||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||||
|
|
||||||
source-map@^0.5.0:
|
source-map@^0.5.0, source-map@^0.5.7:
|
||||||
version "0.5.7"
|
version "0.5.7"
|
||||||
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
|
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
|
||||||
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
|
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
|
||||||
@@ -3306,6 +3520,11 @@ styled-jsx@5.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
client-only "0.0.1"
|
client-only "0.0.1"
|
||||||
|
|
||||||
|
stylis@4.2.0:
|
||||||
|
version "4.2.0"
|
||||||
|
resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz"
|
||||||
|
integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==
|
||||||
|
|
||||||
sucrase@^3.32.0:
|
sucrase@^3.32.0:
|
||||||
version "3.34.0"
|
version "3.34.0"
|
||||||
resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz"
|
resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz"
|
||||||
@@ -3586,6 +3805,11 @@ use-intl@3.0.0-beta.3:
|
|||||||
"@formatjs/ecma402-abstract" "^1.11.4"
|
"@formatjs/ecma402-abstract" "^1.11.4"
|
||||||
intl-messageformat "^9.3.18"
|
intl-messageformat "^9.3.18"
|
||||||
|
|
||||||
|
use-isomorphic-layout-effect@^1.1.2:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz"
|
||||||
|
integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
|
||||||
|
|
||||||
use-sync-external-store@^1.2.0:
|
use-sync-external-store@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
|
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
|
||||||
@@ -3711,6 +3935,11 @@ yallist@^4.0.0:
|
|||||||
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
|
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
|
||||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||||
|
|
||||||
|
yaml@^1.10.0:
|
||||||
|
version "1.10.2"
|
||||||
|
resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
|
||||||
|
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||||
|
|
||||||
yaml@^2.1.1:
|
yaml@^2.1.1:
|
||||||
version "2.3.2"
|
version "2.3.2"
|
||||||
resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz"
|
resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user