The weeb for the next gen discord boat - Wamellow wamellow.com
bot discord

stricter linting

shi.gg c3e7e9c9 fe748608

verified
Changed files
+972 -1002
app
(dynamic-assets)
bluesky
bluesky-client-metadata.json
favicon.ico
luna.webp
sitemap.xml
waya-v3.webp
(home)
dashboard
docs
[...pathname]
leaderboard
login
[social]
open-graph
passport
profile
common
components
lib
public
utils
+2 -3
app/(dynamic-assets)/bluesky-client-metadata.json/route.ts
··· 1 - import { createPublicKey } from "crypto"; 2 - 3 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 4 5 - export const revalidate = 691200; // 8 days 6 7 const PUB_KEY = "-----BEGIN PUBLIC KEY-----\n" + process.env.BLUESKY_PUBLIC_KEY + "\n-----END PUBLIC KEY-----"; 8
··· 1 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 2 + import { createPublicKey } from "node:crypto"; 3 4 + export const revalidate = 691_200; // 8 days 5 6 const PUB_KEY = "-----BEGIN PUBLIC KEY-----\n" + process.env.BLUESKY_PUBLIC_KEY + "\n-----END PUBLIC KEY-----"; 7
+1 -1
app/(dynamic-assets)/bluesky/route.ts
··· 1 import { redirect } from "next/navigation"; 2 3 - export const revalidate = 691200; // 8 days 4 5 export function GET(request: Request) { 6 const agent = request.headers.get("user-agent");
··· 1 import { redirect } from "next/navigation"; 2 3 + export const revalidate = 691_200; // 8 days 4 5 export function GET(request: Request) { 6 const agent = request.headers.get("user-agent");
+2 -3
app/(dynamic-assets)/favicon.ico/route.ts
··· 1 import sharp from "sharp"; 2 3 - import { getUser } from "@/lib/discord/user"; 4 - 5 - export const revalidate = 691200; // 8 days 6 7 export async function GET() { 8 const user = await getUser(process.env.NEXT_PUBLIC_CLIENT_ID as string);
··· 1 + import { getUser } from "@/lib/discord/user"; 2 import sharp from "sharp"; 3 4 + export const revalidate = 691_200; // 8 days 5 6 export async function GET() { 7 const user = await getUser(process.env.NEXT_PUBLIC_CLIENT_ID as string);
+1 -1
app/(dynamic-assets)/luna.webp/route.ts
··· 1 import { getUser } from "@/lib/discord/user"; 2 3 - export const revalidate = 691200; // 8 days 4 5 export async function GET() { 6 const user = await getUser("821472922140803112");
··· 1 import { getUser } from "@/lib/discord/user"; 2 3 + export const revalidate = 691_200; // 8 days 4 5 export async function GET() { 6 const user = await getUser("821472922140803112");
+1 -1
app/(dynamic-assets)/sitemap.xml/route.ts
··· 6 priority: number; 7 } 8 9 - export const revalidate = 691200; // 8 days 10 11 const fetchOptions = { 12 headers: {
··· 6 priority: number; 7 } 8 9 + export const revalidate = 691_200; // 8 days 10 11 const fetchOptions = { 12 headers: {
+1 -1
app/(dynamic-assets)/waya-v3.webp/route.ts
··· 1 import { getUser } from "@/lib/discord/user"; 2 3 - export const revalidate = 691200; // 8 days 4 5 export async function GET() { 6 const user = await getUser(process.env.NEXT_PUBLIC_CLIENT_ID as string);
··· 1 import { getUser } from "@/lib/discord/user"; 2 3 + export const revalidate = 691_200; // 8 days 4 5 export async function GET() { 6 const user = await getUser(process.env.NEXT_PUBLIC_CLIENT_ID as string);
+1 -2
app/(home)/commands.component.tsx
··· 1 - import { HiFire, HiInformationCircle } from "react-icons/hi"; 2 - 3 import Box from "@/components/box"; 4 import { Badge } from "@/components/ui/badge"; 5 import { defaultFetchOptions } from "@/lib/api"; 6 import { intl } from "@/utils/numbers"; 7 8 interface Commands { 9 name: string;
··· 1 import Box from "@/components/box"; 2 import { Badge } from "@/components/ui/badge"; 3 import { defaultFetchOptions } from "@/lib/api"; 4 import { intl } from "@/utils/numbers"; 5 + import { HiFire, HiInformationCircle } from "react-icons/hi"; 6 7 interface Commands { 8 name: string;
+3 -4
app/(home)/debug/page.tsx
··· 1 import type { Metadata } from "next"; 2 import { cookies, headers } from "next/headers"; 3 import { HiTrash } from "react-icons/hi"; 4 - 5 - import { Shiggy } from "@/components/shiggy"; 6 - import { Button } from "@/components/ui/button"; 7 - import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 8 9 import Panel from "./panel.component"; 10
··· 1 + import { Shiggy } from "@/components/shiggy"; 2 + import { Button } from "@/components/ui/button"; 3 + import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 4 import type { Metadata } from "next"; 5 import { cookies, headers } from "next/headers"; 6 import { HiTrash } from "react-icons/hi"; 7 8 import Panel from "./panel.component"; 9
+2 -3
app/(home)/faq.component.tsx
··· 1 "use client"; 2 3 import { Accordion, AccordionItem, Code } from "@nextui-org/react"; 4 import { useCookies } from "next-client-cookies"; 5 import { HiBell, HiCash, HiChat, HiLockClosed, HiUserAdd } from "react-icons/hi"; 6 - 7 - import LinkTag from "@/components/link-tag"; 8 - import { Section } from "@/components/section"; 9 10 const data = [ 11 {
··· 1 "use client"; 2 3 + import LinkTag from "@/components/link-tag"; 4 + import { Section } from "@/components/section"; 5 import { Accordion, AccordionItem, Code } from "@nextui-org/react"; 6 import { useCookies } from "next-client-cookies"; 7 import { HiBell, HiCash, HiChat, HiLockClosed, HiUserAdd } from "react-icons/hi"; 8 9 const data = [ 10 {
+3 -4
app/(home)/impressum/page.tsx
··· 1 - import type { Metadata } from "next"; 2 - import Link from "next/link"; 3 - import { HiExternalLink } from "react-icons/hi"; 4 - 5 import { Section } from "@/components/section"; 6 import { Separator } from "@/components/ui/separator"; 7 import { cn } from "@/utils/cn"; 8 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 9 10 export const revalidate = false; 11
··· 1 import { Section } from "@/components/section"; 2 import { Separator } from "@/components/ui/separator"; 3 import { cn } from "@/utils/cn"; 4 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 5 + import type { Metadata } from "next"; 6 + import Link from "next/link"; 7 + import { HiExternalLink } from "react-icons/hi"; 8 9 export const revalidate = false; 10
+2 -3
app/(home)/layout.tsx
··· 1 import { Suspense } from "react"; 2 3 - import { Footer } from "@/components/footer"; 4 - 5 - export const revalidate = 43200; 6 7 export default function RootLayout({ 8 children
··· 1 + import { Footer } from "@/components/footer"; 2 import { Suspense } from "react"; 3 4 + export const revalidate = 43_200; 5 6 export default function RootLayout({ 7 children
+17 -18
app/(home)/page.tsx
··· 1 - import { Code } from "@nextui-org/react"; 2 - import { Montserrat, Patrick_Hand } from "next/font/google"; 3 - import { headers } from "next/headers"; 4 - import Image from "next/image"; 5 - import Link from "next/link"; 6 - import { Suspense } from "react"; 7 - import { BsYoutube } from "react-icons/bs"; 8 - import { HiArrowNarrowRight, HiArrowRight, HiCash, HiCheck, HiFire, HiLockOpen, HiUserAdd } from "react-icons/hi"; 9 - 10 import Box from "@/components/box"; 11 import Comment from "@/components/comment"; 12 import DiscordAppBadge from "@/components/discord/app-badge"; ··· 34 import { toFixedArrayLength } from "@/utils/fixed-array-length"; 35 import { actor } from "@/utils/tts"; 36 import { getCanonicalUrl } from "@/utils/urls"; 37 38 import { Commands } from "./commands.component"; 39 import { Faq } from "./faq.component"; ··· 42 const montserrat = Montserrat({ subsets: ["latin"] }); 43 const handwritten = Patrick_Hand({ subsets: ["latin"], weight: "400" }); 44 45 - export const revalidate = 43200; 46 47 const styles = { 48 h2: cn(montserrat.className, "lg:text-5xl text-4xl bg-gradient-to-b bg-clip-text text-transparent from-neutral-200 from-40% to-neutral-300 font-bold mb-4"), ··· 356 <DiscordMessageEmbed 357 mode="DARK" 358 title="My wife insisted I do this for her" 359 - color={0x8a57ff} 360 > 361 <Image 362 alt="" ··· 467 <Image 468 alt="example leaderboard card" 469 src={LeaderboardPic} 470 - height={1024 / 4} 471 itemProp="image" 472 loading="lazy" 473 - width={2048 / 4} 474 /> 475 </DiscordMessage> 476 </div> ··· 515 <DiscordMessage {...messageProps()}> 516 <DiscordMessageEmbed 517 mode={"DARK"} 518 - color={0xbd7fd6} 519 author={{ 520 text: "@mwlica", 521 icon_url: "/luna.webp" ··· 579 height={(256 + 16) / 2} 580 itemProp="image" 581 loading="lazy" 582 - width={1024 / 2} 583 /> 584 </DiscordMessage> 585 </div> ··· 634 alt="anime captcha verification example" 635 className="max-w-56" 636 src={CaptchaPic} 637 - height={1530 / 5} 638 itemProp="image" 639 loading="lazy" 640 - width={1070 / 5} 641 /> 642 </div> 643 </Box> ··· 700 > 701 <DiscordMessageEmbed 702 mode={"DARK"} 703 - color={0xbc7ed4} 704 > 705 <DiscordMarkdown mode={"DARK"} text="To create a custom command, go to [your server's dashboard](/dashboard?to=custom-commands), click on `Create`, fill in the response **content**, **embed title**, **embed description**, **embed color**, **embed images**, command **permissions** and more. When you're done you can start using the command 🎉" /> 706 </DiscordMessageEmbed>
··· 1 import Box from "@/components/box"; 2 import Comment from "@/components/comment"; 3 import DiscordAppBadge from "@/components/discord/app-badge"; ··· 25 import { toFixedArrayLength } from "@/utils/fixed-array-length"; 26 import { actor } from "@/utils/tts"; 27 import { getCanonicalUrl } from "@/utils/urls"; 28 + import { Code } from "@nextui-org/react"; 29 + import { Montserrat, Patrick_Hand } from "next/font/google"; 30 + import { headers } from "next/headers"; 31 + import Image from "next/image"; 32 + import Link from "next/link"; 33 + import { Suspense } from "react"; 34 + import { BsYoutube } from "react-icons/bs"; 35 + import { HiArrowNarrowRight, HiArrowRight, HiCash, HiCheck, HiFire, HiLockOpen, HiUserAdd } from "react-icons/hi"; 36 37 import { Commands } from "./commands.component"; 38 import { Faq } from "./faq.component"; ··· 41 const montserrat = Montserrat({ subsets: ["latin"] }); 42 const handwritten = Patrick_Hand({ subsets: ["latin"], weight: "400" }); 43 44 + export const revalidate = 43_200; 45 46 const styles = { 47 h2: cn(montserrat.className, "lg:text-5xl text-4xl bg-gradient-to-b bg-clip-text text-transparent from-neutral-200 from-40% to-neutral-300 font-bold mb-4"), ··· 355 <DiscordMessageEmbed 356 mode="DARK" 357 title="My wife insisted I do this for her" 358 + color={0x8A_57_FF} 359 > 360 <Image 361 alt="" ··· 466 <Image 467 alt="example leaderboard card" 468 src={LeaderboardPic} 469 + height={1_024 / 4} 470 itemProp="image" 471 loading="lazy" 472 + width={2_048 / 4} 473 /> 474 </DiscordMessage> 475 </div> ··· 514 <DiscordMessage {...messageProps()}> 515 <DiscordMessageEmbed 516 mode={"DARK"} 517 + color={0xBD_7F_D6} 518 author={{ 519 text: "@mwlica", 520 icon_url: "/luna.webp" ··· 578 height={(256 + 16) / 2} 579 itemProp="image" 580 loading="lazy" 581 + width={1_024 / 2} 582 /> 583 </DiscordMessage> 584 </div> ··· 633 alt="anime captcha verification example" 634 className="max-w-56" 635 src={CaptchaPic} 636 + height={1_530 / 5} 637 itemProp="image" 638 loading="lazy" 639 + width={1_070 / 5} 640 /> 641 </div> 642 </Box> ··· 699 > 700 <DiscordMessageEmbed 701 mode={"DARK"} 702 + color={0xBC_7E_D4} 703 > 704 <DiscordMarkdown mode={"DARK"} text="To create a custom command, go to [your server's dashboard](/dashboard?to=custom-commands), click on `Create`, fill in the response **content**, **embed title**, **embed description**, **embed color**, **embed images**, command **permissions** and more. When you're done you can start using the command 🎉" /> 705 </DiscordMessageEmbed>
+2 -2
app/(home)/premium/checkout/route.ts
··· 14 redirect("/login?callback=" + encodeURIComponent("/" + request.url.split("/").slice(3).join("/"))); 15 } 16 17 - const donationQuantity = parseInt(searchParams.get("donation") || "0"); 18 const referer = request.headers.get("referer") || ""; 19 20 const url = await createCheckout(session.value, donationQuantity, referer) 21 - .catch((e) => e); 22 23 if (url instanceof Error) { 24 console.log(url);
··· 14 redirect("/login?callback=" + encodeURIComponent("/" + request.url.split("/").slice(3).join("/"))); 15 } 16 17 + const donationQuantity = Number.parseInt(searchParams.get("donation") || "0", 10); 18 const referer = request.headers.get("referer") || ""; 19 20 const url = await createCheckout(session.value, donationQuantity, referer) 21 + .catch((error) => error); 22 23 if (url instanceof Error) { 24 console.log(url);
+8 -9
app/(home)/premium/page.tsx
··· 1 - import type { Metadata } from "next"; 2 - import { Montserrat, Patrick_Hand } from "next/font/google"; 3 - import Image from "next/image"; 4 - import Link from "next/link"; 5 - import { BsQuestionLg } from "react-icons/bs"; 6 - import { HiArrowRight, HiLightningBolt, HiOutlineCheck, HiOutlineInformationCircle, HiUser, HiUserGroup, HiX } from "react-icons/hi"; 7 - import { IoMdInfinite } from "react-icons/io"; 8 - 9 import Comment from "@/components/comment"; 10 import ImageGrid from "@/components/image-grid"; 11 import { OverviewLink } from "@/components/overview-link"; ··· 22 import type { ApiV1TopguildsGetResponse } from "@/typings"; 23 import { cn } from "@/utils/cn"; 24 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 25 26 import { Subscribe } from "./subscribe.component"; 27 ··· 53 { title: "Notification crosspost", free: false, premium: true } 54 ]; 55 56 - export const revalidate = 3600; 57 58 export const generateMetadata = (): Metadata => { 59
··· 1 import Comment from "@/components/comment"; 2 import ImageGrid from "@/components/image-grid"; 3 import { OverviewLink } from "@/components/overview-link"; ··· 14 import type { ApiV1TopguildsGetResponse } from "@/typings"; 15 import { cn } from "@/utils/cn"; 16 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 17 + import type { Metadata } from "next"; 18 + import { Montserrat, Patrick_Hand } from "next/font/google"; 19 + import Image from "next/image"; 20 + import Link from "next/link"; 21 + import { BsQuestionLg } from "react-icons/bs"; 22 + import { HiArrowRight, HiLightningBolt, HiOutlineCheck, HiOutlineInformationCircle, HiUser, HiUserGroup, HiX } from "react-icons/hi"; 23 + import { IoMdInfinite } from "react-icons/io"; 24 25 import { Subscribe } from "./subscribe.component"; 26 ··· 52 { title: "Notification crosspost", free: false, premium: true } 53 ]; 54 55 + export const revalidate = 3_600; 56 57 export const generateMetadata = (): Metadata => { 58
+4 -5
app/(home)/premium/subscribe.component.tsx
··· 1 "use client"; 2 - import Link from "next/link"; 3 - import { type HTMLProps, useState } from "react"; 4 - import { HiArrowDown, HiArrowUp, HiLightningBolt, HiOutlineInformationCircle } from "react-icons/hi"; 5 - 6 import { userStore } from "@/common/user"; 7 import { Button } from "@/components/ui/button"; 8 import { InputBase, InputBaseAdornment, InputBaseAdornmentButton, InputBaseControl, InputBaseInput } from "@/components/ui/input-base"; 9 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 10 import { cn } from "@/utils/cn"; 11 12 export function Subscribe() { 13 const premium = userStore((u) => u?.premium || false); ··· 92 defaultValue={0} 93 onChange={(e) => { 94 const num = Number(e.target.value); 95 - if (isNaN(num)) return; 96 97 setDonation(Math.max(Math.min(num, 100), 0)); 98 }}
··· 1 "use client"; 2 import { userStore } from "@/common/user"; 3 import { Button } from "@/components/ui/button"; 4 import { InputBase, InputBaseAdornment, InputBaseAdornmentButton, InputBaseControl, InputBaseInput } from "@/components/ui/input-base"; 5 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 6 import { cn } from "@/utils/cn"; 7 + import Link from "next/link"; 8 + import { type HTMLProps, useState } from "react"; 9 + import { HiArrowDown, HiArrowUp, HiLightningBolt, HiOutlineInformationCircle } from "react-icons/hi"; 10 11 export function Subscribe() { 12 const premium = userStore((u) => u?.premium || false); ··· 91 defaultValue={0} 92 onChange={(e) => { 93 const num = Number(e.target.value); 94 + if (Number.isNaN(num)) return; 95 96 setDonation(Math.max(Math.min(num, 100), 0)); 97 }}
+2 -3
app/(home)/privacy/page.tsx
··· 1 import { readFile } from "fs/promises"; 2 import type { Metadata } from "next"; 3 - 4 - import BeautifyMarkdown from "@/components/markdown"; 5 - import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 6 7 export const revalidate = false; 8
··· 1 + import BeautifyMarkdown from "@/components/markdown"; 2 + import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 3 import { readFile } from "fs/promises"; 4 import type { Metadata } from "next"; 5 6 export const revalidate = false; 7
+4 -5
app/(home)/ratings.component.tsx
··· 1 - import Image from "next/image"; 2 - import Link from "next/link"; 3 - 4 import StarIcon from "@/components/icons/star"; 5 import { getReviews } from "@/lib/topgg"; 6 import TopggIcon from "@/public/icons/topgg.webp"; 7 8 export async function Ratings() { 9 const reviews = await getReviews(); ··· 18 <div className="flex gap-1"> 19 {reviews.averageScore ? 20 <div className="flex gap-1"> 21 - {new Array(reviews.averageScore).fill(0).map((_, i) => 22 <StarIcon key={i} className="w-6 h-6 stroke-violet-500 fill-violet-400/20" /> 23 )} 24 </div> ··· 27 } 28 {5 - reviews.averageScore ? 29 <div className="flex gap-1"> 30 - {new Array(Math.max(5 - reviews.averageScore, 0)).fill(0).map((_, i) => 31 <StarIcon key={i} className="w-6 h-6 stroke-violet-500 fill-transparent opacity-40" /> 32 )} 33 </div>
··· 1 import StarIcon from "@/components/icons/star"; 2 import { getReviews } from "@/lib/topgg"; 3 import TopggIcon from "@/public/icons/topgg.webp"; 4 + import Image from "next/image"; 5 + import Link from "next/link"; 6 7 export async function Ratings() { 8 const reviews = await getReviews(); ··· 17 <div className="flex gap-1"> 18 {reviews.averageScore ? 19 <div className="flex gap-1"> 20 + {Array.from({ length: reviews.averageScore }).fill(0).map((_, i) => 21 <StarIcon key={i} className="w-6 h-6 stroke-violet-500 fill-violet-400/20" /> 22 )} 23 </div> ··· 26 } 27 {5 - reviews.averageScore ? 28 <div className="flex gap-1"> 29 + {Array.from({ length: Math.max(5 - reviews.averageScore, 0) }).fill(0).map((_, i) => 30 <StarIcon key={i} className="w-6 h-6 stroke-violet-500 fill-transparent opacity-40" /> 31 )} 32 </div>
+3 -5
app/(home)/status/cluster.component.tsx
··· 1 import Image from "next/image"; 2 import type { ReactNode } from "react"; 3 import { HiLightningBolt } from "react-icons/hi"; 4 - 5 - import { Badge } from "@/components/ui/badge"; 6 - import { cn } from "@/utils/cn"; 7 - import { intl } from "@/utils/numbers"; 8 9 import type { ApiCluster } from "./api"; 10 ··· 69 /> 70 ); 71 } 72 - 73 74 function Row({ name, children, className }: { name: string; children: ReactNode; className?: string; }) { 75 return (
··· 1 + import { Badge } from "@/components/ui/badge"; 2 + import { cn } from "@/utils/cn"; 3 + import { intl } from "@/utils/numbers"; 4 import Image from "next/image"; 5 import type { ReactNode } from "react"; 6 import { HiLightningBolt } from "react-icons/hi"; 7 8 import type { ApiCluster } from "./api"; 9 ··· 68 /> 69 ); 70 } 71 72 function Row({ name, children, className }: { name: string; children: ReactNode; className?: string; }) { 73 return (
+3 -4
app/(home)/status/layout.tsx
··· 1 import type { Metadata } from "next"; 2 import { Montserrat } from "next/font/google"; 3 import type { ReactNode } from "react"; 4 - 5 - import { Section } from "@/components/section"; 6 - import { cn } from "@/utils/cn"; 7 - import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 8 9 import { Commands } from "../commands.component"; 10
··· 1 + import { Section } from "@/components/section"; 2 + import { cn } from "@/utils/cn"; 3 + import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 4 import type { Metadata } from "next"; 5 import { Montserrat } from "next/font/google"; 6 import type { ReactNode } from "react"; 7 8 import { Commands } from "../commands.component"; 9
+3 -4
app/(home)/status/side.component.tsx
··· 1 "use client"; 2 3 import { Accordion, AccordionItem } from "@nextui-org/react"; 4 import { useCookies } from "next-client-cookies"; 5 import { type ReactNode, useEffect, useMemo, useState } from "react"; 6 - 7 - import DumbTextInput from "@/components/inputs/dumb-text-input"; 8 - import { Badge } from "@/components/ui/badge"; 9 - import { intl } from "@/utils/numbers"; 10 11 import type { ApiV1StatusGetResponse } from "./api"; 12
··· 1 "use client"; 2 3 + import DumbTextInput from "@/components/inputs/dumb-text-input"; 4 + import { Badge } from "@/components/ui/badge"; 5 + import { intl } from "@/utils/numbers"; 6 import { Accordion, AccordionItem } from "@nextui-org/react"; 7 import { useCookies } from "next-client-cookies"; 8 import { type ReactNode, useEffect, useMemo, useState } from "react"; 9 10 import type { ApiV1StatusGetResponse } from "./api"; 11
+3 -4
app/(home)/team/discord.component.tsx
··· 1 import Image from "next/image"; 2 import Link from "next/link"; 3 import { HiExternalLink } from "react-icons/hi"; 4 - 5 - import { getGuild } from "@/lib/discord/guild"; 6 - import { cn } from "@/utils/cn"; 7 - import { intl } from "@/utils/numbers"; 8 9 export async function DiscordServer({ 10 guildId
··· 1 + import { getGuild } from "@/lib/discord/guild"; 2 + import { cn } from "@/utils/cn"; 3 + import { intl } from "@/utils/numbers"; 4 import Image from "next/image"; 5 import Link from "next/link"; 6 import { HiExternalLink } from "react-icons/hi"; 7 8 export async function DiscordServer({ 9 guildId
+3 -4
app/(home)/team/page.tsx
··· 1 import type { Metadata } from "next"; 2 import { BsDiscord, BsGithub } from "react-icons/bs"; 3 - 4 - import { filterDuplicates } from "@/utils/filter-duplicates"; 5 - import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 6 7 import { members, repos } from "./constants"; 8 import { DiscordServer } from "./discord.component"; 9 import { Person } from "./person.component"; 10 import { Repository } from "./repository.component"; 11 12 - export const revalidate = 3600; 13 14 export const generateMetadata = (): Metadata => { 15 const title = "Team";
··· 1 + import { filterDuplicates } from "@/utils/filter-duplicates"; 2 + import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 3 import type { Metadata } from "next"; 4 import { BsDiscord, BsGithub } from "react-icons/bs"; 5 6 import { members, repos } from "./constants"; 7 import { DiscordServer } from "./discord.component"; 8 import { Person } from "./person.component"; 9 import { Repository } from "./repository.component"; 10 11 + export const revalidate = 3_600; 12 13 export const generateMetadata = (): Metadata => { 14 const title = "Team";
+3 -4
app/(home)/team/person.component.tsx
··· 1 import Image from "next/image"; 2 import Link from "next/link"; 3 import type { AnchorHTMLAttributes, DetailedHTMLProps, HTMLAttributes } from "react"; 4 - 5 - import { getUser } from "@/lib/discord/user"; 6 - import { cn } from "@/utils/cn"; 7 8 type DivProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>; 9 type LinkProps = DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>; ··· 46 } 47 48 function isLinkProps(props: DivProps | LinkProps): props is LinkProps { 49 - return "href" in props && !!props.href; 50 } 51 52 function Component(props: DivProps | LinkProps) {
··· 1 + import { getUser } from "@/lib/discord/user"; 2 + import { cn } from "@/utils/cn"; 3 import Image from "next/image"; 4 import Link from "next/link"; 5 import type { AnchorHTMLAttributes, DetailedHTMLProps, HTMLAttributes } from "react"; 6 7 type DivProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>; 8 type LinkProps = DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>; ··· 45 } 46 47 function isLinkProps(props: DivProps | LinkProps): props is LinkProps { 48 + return "href" in props && Boolean(props.href); 49 } 50 51 function Component(props: DivProps | LinkProps) {
+2 -3
app/(home)/team/repository.component.tsx
··· 1 - import Link from "next/link"; 2 - import { HiBeaker, HiExternalLink, HiStar } from "react-icons/hi"; 3 - 4 import { Badge } from "@/components/ui/badge"; 5 import { getRepository } from "@/lib/github"; 6 import { cn } from "@/utils/cn"; 7 8 export async function Repository({ 9 fullname
··· 1 import { Badge } from "@/components/ui/badge"; 2 import { getRepository } from "@/lib/github"; 3 import { cn } from "@/utils/cn"; 4 + import Link from "next/link"; 5 + import { HiBeaker, HiExternalLink, HiStar } from "react-icons/hi"; 6 7 export async function Repository({ 8 fullname
+2 -3
app/(home)/terms/page.tsx
··· 1 import { readFile } from "fs/promises"; 2 import type { Metadata } from "next"; 3 - 4 - import BeautifyMarkdown from "@/components/markdown"; 5 - import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 6 7 export const revalidate = false; 8
··· 1 + import BeautifyMarkdown from "@/components/markdown"; 2 + import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 3 import { readFile } from "fs/promises"; 4 import type { Metadata } from "next"; 5 6 export const revalidate = false; 7
+2 -3
app/(home)/terms/payment/page.tsx
··· 1 import { readFile } from "fs/promises"; 2 import type { Metadata } from "next"; 3 - 4 - import BeautifyMarkdown from "@/components/markdown"; 5 - import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 6 7 export const revalidate = false; 8
··· 1 + import BeautifyMarkdown from "@/components/markdown"; 2 + import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 3 import { readFile } from "fs/promises"; 4 import type { Metadata } from "next"; 5 6 export const revalidate = false; 7
+2 -3
app/dashboard/[guildId]/custom-commands/create.component.tsx
··· 1 "use client"; 2 3 - import { useState } from "react"; 4 - import { HiPencil } from "react-icons/hi"; 5 - 6 import DumbTextInput from "@/components/inputs/dumb-text-input"; 7 import Modal from "@/components/modal"; 8 import { Button } from "@/components/ui/button"; 9 import type { ApiV1GuildsModulesTagsGetResponse } from "@/typings"; 10 11 export enum Style { 12 Compact = 1,
··· 1 "use client"; 2 3 import DumbTextInput from "@/components/inputs/dumb-text-input"; 4 import Modal from "@/components/modal"; 5 import { Button } from "@/components/ui/button"; 6 import type { ApiV1GuildsModulesTagsGetResponse } from "@/typings"; 7 + import { useState } from "react"; 8 + import { HiPencil } from "react-icons/hi"; 9 10 export enum Style { 11 Compact = 1,
+2 -3
app/dashboard/[guildId]/custom-commands/delete.component.tsx
··· 1 "use client"; 2 3 - import { useState } from "react"; 4 - import { HiTrash } from "react-icons/hi"; 5 - 6 import Modal from "@/components/modal"; 7 import { Button } from "@/components/ui/button"; 8 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 9 10 interface Props { 11 guildId: string;
··· 1 "use client"; 2 3 import Modal from "@/components/modal"; 4 import { Button } from "@/components/ui/button"; 5 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 6 + import { useState } from "react"; 7 + import { HiTrash } from "react-icons/hi"; 8 9 interface Props { 10 guildId: string;
+10 -12
app/dashboard/[guildId]/custom-commands/page.tsx
··· 1 "use client"; 2 3 - import { useParams, usePathname, useRouter, useSearchParams } from "next/navigation"; 4 - import { useCallback, useEffect } from "react"; 5 - import { HiViewGridAdd } from "react-icons/hi"; 6 - import { useQuery, useQueryClient } from "react-query"; 7 - 8 import { guildStore } from "@/common/guilds"; 9 import { StatsBar } from "@/components/counter"; 10 import MessageCreatorEmbed from "@/components/embed-creator"; ··· 16 import { cacheOptions, getData } from "@/lib/api"; 17 import { Permissions } from "@/lib/discord/enum/permissions"; 18 import type { ApiV1GuildsModulesTagsGetResponse } from "@/typings"; 19 20 import { CreateTag, Style } from "./create.component"; 21 import { DeleteTag } from "./delete.component"; ··· 34 url, 35 () => getData<ApiV1GuildsModulesTagsGetResponse[]>(url), 36 { 37 - enabled: !!params.guildId, 38 ...cacheOptions 39 } 40 ); ··· 98 }; 99 100 return (<> 101 - 102 <div className="flex flex-wrap items-center gap-2 -mt-2 mb-5"> 103 {data 104 .sort((a, b) => a.name.localeCompare(b.name)) ··· 157 }, 158 { 159 name: "All time Command Uses", 160 - number: 69420, 161 gained: 42, 162 append: "yesterday" 163 } ··· 180 description="The name of the custom command." 181 defaultState={tag.name} 182 resetState={tag.name} 183 - onSave={(value) => editTag("name", value as string)} 184 /> 185 </div> 186 ··· 197 dataName="permission" 198 description="The permissions needed to execute this tag." 199 defaultState={tag.permission} 200 - onSave={(option) => editTag("permission", option.value as string)} 201 showClear 202 /> 203 </div> ··· 209 url={url + "/" + tag.id} 210 dataName="message" 211 defaultMessage={tag.message} 212 - onSave={(value) => editTag("message", value as string)} 213 /> 214 - </> } 215 216 {!data.length && 217 <div
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import { StatsBar } from "@/components/counter"; 5 import MessageCreatorEmbed from "@/components/embed-creator"; ··· 11 import { cacheOptions, getData } from "@/lib/api"; 12 import { Permissions } from "@/lib/discord/enum/permissions"; 13 import type { ApiV1GuildsModulesTagsGetResponse } from "@/typings"; 14 + import { useParams, usePathname, useRouter, useSearchParams } from "next/navigation"; 15 + import { useCallback, useEffect } from "react"; 16 + import { HiViewGridAdd } from "react-icons/hi"; 17 + import { useQuery, useQueryClient } from "react-query"; 18 19 import { CreateTag, Style } from "./create.component"; 20 import { DeleteTag } from "./delete.component"; ··· 33 url, 34 () => getData<ApiV1GuildsModulesTagsGetResponse[]>(url), 35 { 36 + enabled: Boolean(params.guildId), 37 ...cacheOptions 38 } 39 ); ··· 97 }; 98 99 return (<> 100 <div className="flex flex-wrap items-center gap-2 -mt-2 mb-5"> 101 {data 102 .sort((a, b) => a.name.localeCompare(b.name)) ··· 155 }, 156 { 157 name: "All time Command Uses", 158 + number: 69_420, 159 gained: 42, 160 append: "yesterday" 161 } ··· 178 description="The name of the custom command." 179 defaultState={tag.name} 180 resetState={tag.name} 181 + onSave={(value) => editTag("name", value)} 182 /> 183 </div> 184 ··· 195 dataName="permission" 196 description="The permissions needed to execute this tag." 197 defaultState={tag.permission} 198 + onSave={(option) => editTag("permission", option.value)} 199 showClear 200 /> 201 </div> ··· 207 url={url + "/" + tag.id} 208 dataName="message" 209 defaultMessage={tag.message} 210 + onSave={(value) => editTag("message", value)} 211 /> 212 + </>} 213 214 {!data.length && 215 <div
+4 -5
app/dashboard/[guildId]/dailyposts/create.component.tsx
··· 1 "use client"; 2 3 - import { useMemo, useState } from "react"; 4 - import { HiPencil } from "react-icons/hi"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import MultiSelectMenu from "@/components/inputs/multi-select-menu"; 8 import SelectMenu from "@/components/inputs/select-menu"; ··· 10 import { Button } from "@/components/ui/button"; 11 import { type ApiV1GuildsModulesDailypostsGetResponse, DailypostType } from "@/typings"; 12 import { createSelectableItems } from "@/utils/create-selectable-items"; 13 14 import { generateHourArray, typeToName } from "./util"; 15 ··· 105 items={hoursArray} 106 description="Select one or multiple hours when posts should be made." 107 onSave={(o) => { 108 - setHours(o.map((i) => i.value as number)); 109 }} 110 /> 111 ··· 115 items={ 116 Object.entries(DailypostType) 117 .filter(([key]) => key.length > 2) 118 - .map(([, value]) => ({ name: typeToName(parseInt(value as string)), value })) 119 } 120 description="Select what type of content should be posted daily." 121 onSave={(o) => {
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import MultiSelectMenu from "@/components/inputs/multi-select-menu"; 5 import SelectMenu from "@/components/inputs/select-menu"; ··· 7 import { Button } from "@/components/ui/button"; 8 import { type ApiV1GuildsModulesDailypostsGetResponse, DailypostType } from "@/typings"; 9 import { createSelectableItems } from "@/utils/create-selectable-items"; 10 + import { useMemo, useState } from "react"; 11 + import { HiPencil } from "react-icons/hi"; 12 13 import { generateHourArray, typeToName } from "./util"; 14 ··· 104 items={hoursArray} 105 description="Select one or multiple hours when posts should be made." 106 onSave={(o) => { 107 + setHours(o.map((i) => i.value)); 108 }} 109 /> 110 ··· 114 items={ 115 Object.entries(DailypostType) 116 .filter(([key]) => key.length > 2) 117 + .map(([, value]) => ({ name: typeToName(Number.parseInt(value as string, 10)), value })) 118 } 119 description="Select what type of content should be posted daily." 120 onSave={(o) => {
+2 -3
app/dashboard/[guildId]/dailyposts/delete.component.tsx
··· 1 "use client"; 2 3 - import { useState } from "react"; 4 - import { HiTrash } from "react-icons/hi"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import Modal from "@/components/modal"; 8 import { Button } from "@/components/ui/button"; 9 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 10 11 interface Props { 12 id: string | null;
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import Modal from "@/components/modal"; 5 import { Button } from "@/components/ui/button"; 6 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 7 + import { useState } from "react"; 8 + import { HiTrash } from "react-icons/hi"; 9 10 interface Props { 11 id: string | null;
+4 -5
app/dashboard/[guildId]/dailyposts/page.tsx
··· 1 "use client"; 2 3 - import Image from "next/image"; 4 - import { useParams } from "next/navigation"; 5 - import { useMemo } from "react"; 6 - import { HiViewGridAdd } from "react-icons/hi"; 7 - 8 import { guildStore } from "@/common/guilds"; 9 import { CreateSplash } from "@/components/dashboard/lists/create-splash"; 10 import { useList } from "@/components/dashboard/lists/hook"; ··· 15 import { ScreenMessage } from "@/components/screen-message"; 16 import type { ApiV1GuildsModulesDailypostsGetResponse } from "@/typings"; 17 import { createSelectableItems } from "@/utils/create-selectable-items"; 18 19 import { CreateDailypost, Style } from "./create.component"; 20 import { DeleteDailypost } from "./delete.component";
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import { CreateSplash } from "@/components/dashboard/lists/create-splash"; 5 import { useList } from "@/components/dashboard/lists/hook"; ··· 10 import { ScreenMessage } from "@/components/screen-message"; 11 import type { ApiV1GuildsModulesDailypostsGetResponse } from "@/typings"; 12 import { createSelectableItems } from "@/utils/create-selectable-items"; 13 + import Image from "next/image"; 14 + import { useParams } from "next/navigation"; 15 + import { useMemo } from "react"; 16 + import { HiViewGridAdd } from "react-icons/hi"; 17 18 import { CreateDailypost, Style } from "./create.component"; 19 import { DeleteDailypost } from "./delete.component";
+6 -7
app/dashboard/[guildId]/greeting/farewell/page.tsx
··· 1 "use client"; 2 - import Image from "next/image"; 3 - import Link from "next/link"; 4 - import { useParams } from "next/navigation"; 5 - import { HiArrowLeft, HiChat, HiExternalLink } from "react-icons/hi"; 6 - 7 import { guildStore } from "@/common/guilds"; 8 import { userStore } from "@/common/user"; 9 import Fetch from "@/components/button-fetch"; ··· 18 import type { ApiV1GuildsModulesByeGetResponse } from "@/typings"; 19 import { cn } from "@/utils/cn"; 20 import { createSelectableItems } from "@/utils/create-selectable-items"; 21 22 export default function Home() { 23 const guild = guildStore((g) => g); ··· 111 defaultMessage={data.message} 112 messageAttachmentComponent={data.card.enabled && ( 113 <Image 114 - src={`https://image-api.wamellow.com/?type=leave&username=${encodeURIComponent(user?.username as string)}&members=1090&hash=${encodeURIComponent(user?.id as string)}/${encodeURIComponent(user?.avatar as string)}${data.card.background ? `&background=${encodeURIComponent(data.card.background)}` : ""}`} 115 - width={1024 / 2} 116 height={(256 + 16) / 2} 117 loading="lazy" 118 alt=""
··· 1 "use client"; 2 import { guildStore } from "@/common/guilds"; 3 import { userStore } from "@/common/user"; 4 import Fetch from "@/components/button-fetch"; ··· 13 import type { ApiV1GuildsModulesByeGetResponse } from "@/typings"; 14 import { cn } from "@/utils/cn"; 15 import { createSelectableItems } from "@/utils/create-selectable-items"; 16 + import Image from "next/image"; 17 + import Link from "next/link"; 18 + import { useParams } from "next/navigation"; 19 + import { HiArrowLeft, HiChat, HiExternalLink } from "react-icons/hi"; 20 21 export default function Home() { 22 const guild = guildStore((g) => g); ··· 110 defaultMessage={data.message} 111 messageAttachmentComponent={data.card.enabled && ( 112 <Image 113 + src={`https://image-api.wamellow.com/?type=leave&username=${encodeURIComponent(user!.username)}&members=1090&hash=${encodeURIComponent(user!.id)}/${encodeURIComponent(user!.avatar!)}${data.card.background ? `&background=${encodeURIComponent(data.card.background)}` : ""}`} 114 + width={1_024 / 2} 115 height={(256 + 16) / 2} 116 loading="lazy" 117 alt=""
+1 -2
app/dashboard/[guildId]/greeting/page.tsx
··· 1 "use client"; 2 import { HiFingerPrint, HiUserAdd, HiUserRemove } from "react-icons/hi"; 3 - 4 - import { guildStore } from "@/common/guilds"; 5 6 import { OverviewLink } from "../../../../components/overview-link"; 7
··· 1 "use client"; 2 + import { guildStore } from "@/common/guilds"; 3 import { HiFingerPrint, HiUserAdd, HiUserRemove } from "react-icons/hi"; 4 5 import { OverviewLink } from "../../../../components/overview-link"; 6
+4 -5
app/dashboard/[guildId]/greeting/passport/complete-setup.tsx
··· 1 - import { useEffect, useState } from "react"; 2 - 3 import type { Guild } from "@/common/guilds"; 4 import SelectMenu from "@/components/inputs/select-menu"; 5 import Modal from "@/components/modal"; 6 import type { ApiEdit } from "@/lib/api/hook"; 7 import type { ApiV1GuildsModulesPassportGetResponse } from "@/typings"; 8 import { createSelectableItems } from "@/utils/create-selectable-items"; 9 10 enum ModalType { 11 None = 0, ··· 38 39 if (data.punishment === 2 && !data.punishmentRoleId) { 40 setModal(ModalType.PunishmentRole); 41 - return; 42 } 43 }, [data]); 44 ··· 46 <Modal 47 title="Verified role" 48 className="!overflow-visible" 49 - isOpen={!!guild && modal === ModalType.VerifiedRole} 50 onClose={() => setModal(ModalType.None)} 51 onSubmit={() => { 52 return fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${guild?.id}/modules/passport`, { ··· 74 <Modal 75 title="Punishment role" 76 className="!overflow-visible" 77 - isOpen={!!guild && modal === ModalType.PunishmentRole} 78 onClose={() => setModal(ModalType.None)} 79 onSubmit={() => { 80 return fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${guild?.id}/modules/passport`, {
··· 1 import type { Guild } from "@/common/guilds"; 2 import SelectMenu from "@/components/inputs/select-menu"; 3 import Modal from "@/components/modal"; 4 import type { ApiEdit } from "@/lib/api/hook"; 5 import type { ApiV1GuildsModulesPassportGetResponse } from "@/typings"; 6 import { createSelectableItems } from "@/utils/create-selectable-items"; 7 + import { useEffect, useState } from "react"; 8 9 enum ModalType { 10 None = 0, ··· 37 38 if (data.punishment === 2 && !data.punishmentRoleId) { 39 setModal(ModalType.PunishmentRole); 40 + 41 } 42 }, [data]); 43 ··· 45 <Modal 46 title="Verified role" 47 className="!overflow-visible" 48 + isOpen={Boolean(guild) && modal === ModalType.VerifiedRole} 49 onClose={() => setModal(ModalType.None)} 50 onSubmit={() => { 51 return fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${guild?.id}/modules/passport`, { ··· 73 <Modal 74 title="Punishment role" 75 className="!overflow-visible" 76 + isOpen={Boolean(guild) && modal === ModalType.PunishmentRole} 77 onClose={() => setModal(ModalType.None)} 78 onSubmit={() => { 79 return fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${guild?.id}/modules/passport`, {
+7 -9
app/dashboard/[guildId]/greeting/passport/page.tsx
··· 1 "use client"; 2 - import Link from "next/link"; 3 - import { useParams } from "next/navigation"; 4 - import { HiArrowLeft, HiExternalLink, HiFingerPrint } from "react-icons/hi"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import { CopyToClipboardButton } from "@/components/copy-to-clipboard"; 8 import SelectInput from "@/components/inputs/select-menu"; ··· 14 import type { ApiV1GuildsModulesPassportGetResponse } from "@/typings"; 15 import { createSelectableItems } from "@/utils/create-selectable-items"; 16 import { getCanonicalUrl } from "@/utils/urls"; 17 18 import CompleteSetup from "./complete-setup"; 19 ··· 61 return (<> 62 <Head /> 63 64 - {data.enabled && data.punishment === 2 && !data.punishmentRoleId && 65 <Notice message="A punishment role must be set when using 'Assign role to member'." /> 66 - } 67 68 - {data.enabled && !data.successRoleId && 69 <Notice message="A verified role must be set for passport to work." /> 70 - } 71 72 <CompleteSetup 73 guild={guild} ··· 176 <div className="w-fit"> 177 <CopyToClipboardButton title="Copy link to passport" text={getCanonicalUrl("passport", guild?.id as string)} /> 178 </div> 179 - 180 </>); 181 }
··· 1 "use client"; 2 import { guildStore } from "@/common/guilds"; 3 import { CopyToClipboardButton } from "@/components/copy-to-clipboard"; 4 import SelectInput from "@/components/inputs/select-menu"; ··· 10 import type { ApiV1GuildsModulesPassportGetResponse } from "@/typings"; 11 import { createSelectableItems } from "@/utils/create-selectable-items"; 12 import { getCanonicalUrl } from "@/utils/urls"; 13 + import Link from "next/link"; 14 + import { useParams } from "next/navigation"; 15 + import { HiArrowLeft, HiExternalLink, HiFingerPrint } from "react-icons/hi"; 16 17 import CompleteSetup from "./complete-setup"; 18 ··· 60 return (<> 61 <Head /> 62 63 + {data.enabled && data.punishment === 2 && !data.punishmentRoleId && ( 64 <Notice message="A punishment role must be set when using 'Assign role to member'." /> 65 + )} 66 67 + {data.enabled && !data.successRoleId && ( 68 <Notice message="A verified role must be set for passport to work." /> 69 + )} 70 71 <CompleteSetup 72 guild={guild} ··· 175 <div className="w-fit"> 176 <CopyToClipboardButton title="Copy link to passport" text={getCanonicalUrl("passport", guild?.id as string)} /> 177 </div> 178 </>); 179 }
+4 -5
app/dashboard/[guildId]/greeting/welcome/page.tsx
··· 1 "use client"; 2 - import Image from "next/image"; 3 - import Link from "next/link"; 4 - import { useParams } from "next/navigation"; 5 - import { HiArrowLeft, HiChat, HiExternalLink } from "react-icons/hi"; 6 - 7 import { guildStore } from "@/common/guilds"; 8 import { userStore } from "@/common/user"; 9 import Fetch from "@/components/button-fetch"; ··· 20 import type { ApiV1GuildsModulesWelcomeGetResponse } from "@/typings"; 21 import { cn } from "@/utils/cn"; 22 import { createSelectableEmojiItems, createSelectableItems } from "@/utils/create-selectable-items"; 23 24 export default function Home() { 25 const guild = guildStore((g) => g);
··· 1 "use client"; 2 import { guildStore } from "@/common/guilds"; 3 import { userStore } from "@/common/user"; 4 import Fetch from "@/components/button-fetch"; ··· 15 import type { ApiV1GuildsModulesWelcomeGetResponse } from "@/typings"; 16 import { cn } from "@/utils/cn"; 17 import { createSelectableEmojiItems, createSelectableItems } from "@/utils/create-selectable-items"; 18 + import Image from "next/image"; 19 + import Link from "next/link"; 20 + import { useParams } from "next/navigation"; 21 + import { HiArrowLeft, HiChat, HiExternalLink } from "react-icons/hi"; 22 23 export default function Home() { 24 const guild = guildStore((g) => g);
+10 -11
app/dashboard/[guildId]/layout.tsx
··· 1 "use client"; 2 3 - import Head from "next/head"; 4 - import Link from "next/link"; 5 - import { redirect, useParams } from "next/navigation"; 6 - import { useCookies } from "next-client-cookies"; 7 - import { Suspense, useEffect, useMemo, useState } from "react"; 8 - import { HiArrowNarrowLeft, HiBell, HiChartBar, HiCode, HiEye, HiHome, HiPaperAirplane, HiStar, HiUserAdd, HiUsers, HiViewGridAdd } from "react-icons/hi"; 9 - import { useQuery } from "react-query"; 10 - 11 import { guildStore } from "@/common/guilds"; 12 import ImageReduceMotion from "@/components/image-reduce-motion"; 13 import { ListTab } from "@/components/list"; ··· 17 import { cacheOptions, getData } from "@/lib/api"; 18 import type { ApiV1GuildsChannelsGetResponse, ApiV1GuildsEmojisGetResponse, ApiV1GuildsGetResponse, ApiV1GuildsRolesGetResponse } from "@/typings"; 19 import { intl } from "@/utils/numbers"; 20 21 function useGuildData<T extends unknown[]>( 22 url: string, ··· 26 url, 27 () => getData<T>(url), 28 { 29 - enabled: !!guildStore((g) => g)?.id, 30 onSettled: (data) => { 31 const isError = !data || "message" in data; 32 onLoad(isError ? [] as unknown as T : data, isError); ··· 59 url, 60 () => getData<ApiV1GuildsGetResponse>(url), 61 { 62 - enabled: !!params.guildId, 63 ...cacheOptions, 64 refetchOnMount: true 65 } ··· 191 } 192 ]} 193 url={`/dashboard/${params.guildId}`} 194 - disabled={!guild || !!error} 195 /> 196 </Suspense> 197
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import ImageReduceMotion from "@/components/image-reduce-motion"; 5 import { ListTab } from "@/components/list"; ··· 9 import { cacheOptions, getData } from "@/lib/api"; 10 import type { ApiV1GuildsChannelsGetResponse, ApiV1GuildsEmojisGetResponse, ApiV1GuildsGetResponse, ApiV1GuildsRolesGetResponse } from "@/typings"; 11 import { intl } from "@/utils/numbers"; 12 + import Head from "next/head"; 13 + import Link from "next/link"; 14 + import { redirect, useParams } from "next/navigation"; 15 + import { useCookies } from "next-client-cookies"; 16 + import { Suspense, useEffect, useMemo, useState } from "react"; 17 + import { HiArrowNarrowLeft, HiBell, HiChartBar, HiCode, HiEye, HiHome, HiPaperAirplane, HiStar, HiUserAdd, HiUsers, HiViewGridAdd } from "react-icons/hi"; 18 + import { useQuery } from "react-query"; 19 20 function useGuildData<T extends unknown[]>( 21 url: string, ··· 25 url, 26 () => getData<T>(url), 27 { 28 + enabled: Boolean(guildStore((g) => g)?.id), 29 onSettled: (data) => { 30 const isError = !data || "message" in data; 31 onLoad(isError ? [] as unknown as T : data, isError); ··· 58 url, 59 () => getData<ApiV1GuildsGetResponse>(url), 60 { 61 + enabled: Boolean(params.guildId), 62 ...cacheOptions, 63 refetchOnMount: true 64 } ··· 190 } 191 ]} 192 url={`/dashboard/${params.guildId}`} 193 + disabled={!guild || Boolean(error)} 194 /> 195 </Suspense> 196
+4 -7
app/dashboard/[guildId]/leaderboards/page.tsx
··· 1 "use client"; 2 3 - import { ChannelType } from "discord-api-types/v10"; 4 - import { useParams } from "next/navigation"; 5 - import { HiChartBar, HiViewGridAdd } from "react-icons/hi"; 6 - 7 import { type Guild, guildStore } from "@/common/guilds"; 8 import ImageUrlInput from "@/components/inputs/image-url-input"; 9 import MultiSelectMenu from "@/components/inputs/multi-select-menu"; ··· 12 import { useApi } from "@/lib/api/hook"; 13 import type { ApiV1GuildsModulesLeaderboardGetResponse } from "@/typings"; 14 import { createSelectableItems } from "@/utils/create-selectable-items"; 15 16 - import { OverviewLink } from "../../../../components/overview-link"; 17 import Permissions from "./permissions.component"; 18 import ResetLeaderboard from "./reset.component"; 19 import UpdatingLeaderboardCard from "./updating.component"; 20 import DiscordWidget from "./widget.component"; 21 22 export default function Home() { 23 const guild = guildStore((g) => g); ··· 39 /> 40 ); 41 } 42 - 43 44 return (<> 45 <div className="flex flex-col-reverse md:flex-row gap-6"> ··· 121 <UpdatingLeaderboardCard guild={guild as Guild} lb={data.updating.find((lb) => lb.type === "voiceminutes")} type="voiceminutes" /> 122 <UpdatingLeaderboardCard guild={guild as Guild} lb={data.updating.find((lb) => lb.type === "invites")} type="invites" /> 123 </div> 124 - 125 126 <Section 127 title="Privacy"
··· 1 "use client"; 2 3 import { type Guild, guildStore } from "@/common/guilds"; 4 import ImageUrlInput from "@/components/inputs/image-url-input"; 5 import MultiSelectMenu from "@/components/inputs/multi-select-menu"; ··· 8 import { useApi } from "@/lib/api/hook"; 9 import type { ApiV1GuildsModulesLeaderboardGetResponse } from "@/typings"; 10 import { createSelectableItems } from "@/utils/create-selectable-items"; 11 + import { ChannelType } from "discord-api-types/v10"; 12 + import { useParams } from "next/navigation"; 13 + import { HiChartBar, HiViewGridAdd } from "react-icons/hi"; 14 15 import Permissions from "./permissions.component"; 16 import ResetLeaderboard from "./reset.component"; 17 import UpdatingLeaderboardCard from "./updating.component"; 18 import DiscordWidget from "./widget.component"; 19 + import { OverviewLink } from "../../../../components/overview-link"; 20 21 export default function Home() { 22 const guild = guildStore((g) => g); ··· 38 /> 39 ); 40 } 41 42 return (<> 43 <div className="flex flex-col-reverse md:flex-row gap-6"> ··· 119 <UpdatingLeaderboardCard guild={guild as Guild} lb={data.updating.find((lb) => lb.type === "voiceminutes")} type="voiceminutes" /> 120 <UpdatingLeaderboardCard guild={guild as Guild} lb={data.updating.find((lb) => lb.type === "invites")} type="invites" /> 121 </div> 122 123 <Section 124 title="Privacy"
+3 -4
app/dashboard/[guildId]/leaderboards/permissions.component.tsx
··· 1 - import { PermissionFlagsBits } from "discord-api-types/v10"; 2 - import { useMemo } from "react"; 3 - import { HiExclamation } from "react-icons/hi"; 4 - 5 import type { Guild } from "@/common/guilds"; 6 import DiscordChannel from "@/components/discord/channel"; 7 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 8 import type { ApiV1GuildsChannelsGetResponse } from "@/typings"; 9 import { cn } from "@/utils/cn"; 10 11 interface Props { 12 className: string;
··· 1 import type { Guild } from "@/common/guilds"; 2 import DiscordChannel from "@/components/discord/channel"; 3 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 4 import type { ApiV1GuildsChannelsGetResponse } from "@/typings"; 5 import { cn } from "@/utils/cn"; 6 + import { PermissionFlagsBits } from "discord-api-types/v10"; 7 + import { useMemo } from "react"; 8 + import { HiExclamation } from "react-icons/hi"; 9 10 interface Props { 11 className: string;
+2 -3
app/dashboard/[guildId]/leaderboards/reset.component.tsx
··· 1 - import { useState } from "react"; 2 - import { HiTrash, HiUsers } from "react-icons/hi"; 3 - 4 import type { Guild } from "@/common/guilds"; 5 import ImageReduceMotion from "@/components/image-reduce-motion"; 6 import Modal from "@/components/modal"; 7 import Notice, { NoticeType } from "@/components/notice"; 8 import { Button } from "@/components/ui/button"; 9 import { intl } from "@/utils/numbers"; 10 11 interface Props { 12 guild: Guild;
··· 1 import type { Guild } from "@/common/guilds"; 2 import ImageReduceMotion from "@/components/image-reduce-motion"; 3 import Modal from "@/components/modal"; 4 import Notice, { NoticeType } from "@/components/notice"; 5 import { Button } from "@/components/ui/button"; 6 import { intl } from "@/utils/numbers"; 7 + import { useState } from "react"; 8 + import { HiTrash, HiUsers } from "react-icons/hi"; 9 10 interface Props { 11 guild: Guild;
+14 -15
app/dashboard/[guildId]/leaderboards/updating.component.tsx
··· 1 "use client"; 2 3 - import { Tab, Tabs } from "@nextui-org/react"; 4 - import Link from "next/link"; 5 - import { useCookies } from "next-client-cookies"; 6 - import { useState } from "react"; 7 - import { HiExternalLink, HiPencil, HiTrash } from "react-icons/hi"; 8 - 9 import type { Guild } from "@/common/guilds"; 10 import SelectInput from "@/components/inputs/select-menu"; 11 import Switch from "@/components/inputs/switch"; ··· 13 import Modal from "@/components/modal"; 14 import type { ApiV1GuildsModulesLeaderboardUpdatingPostResponse } from "@/typings"; 15 import { createSelectableEmojiItems, createSelectableItems } from "@/utils/create-selectable-items"; 16 17 interface Props { 18 guild: Guild; ··· 111 <Modal 112 className="flex flex-col gap-3" 113 title={`${type.replace(/^\w/, (match) => match.toUpperCase())} leaderboard`} 114 - isOpen={modal === ModalType.CreateAndEdit && !!guild} 115 isDisabled={!channelId} 116 onClose={() => { 117 setModal(undefined); ··· 141 ...leaderboard, 142 type, 143 // @ts-expect-error it works 144 - channelId, structure, emoji, 145 display, 146 styles 147 }); ··· 169 name="Channel" 170 items={createSelectableItems(guild.channels, ["ViewChannel", "SendMessages", "EmbedLinks", "AttachFiles"])} 171 description="Select a channel where the leaderboard should be send into." 172 - defaultState={leaderboard?.channelId || undefined} 173 - onSave={(o) => { 174 - setChannelId(o.value as string); 175 - }} 176 /> 177 178 <div className="mb-3"> ··· 183 color="secondary" 184 variant="bordered" 185 defaultSelectedKey={structure?.toString()} 186 - onSelectionChange={(i) => setStructure(parseInt(i as string))} 187 fullWidth 188 > 189 <Tab ··· 218 <TextInput 219 name="Title" 220 description="The title of the embed" 221 - defaultState={"☕ " + `${type.replace(/^\w/, (match) => match.toUpperCase())} leaderboard`} 222 max={256} 223 onSave={(v) => { 224 setEmbed({ ··· 299 buttonName="Delete" 300 variant="destructive" 301 title={`Delete ${type.replace(/^\w/, (match) => match.toUpperCase())} leaderboard`} 302 - isOpen={modal === ModalType.Delete && !!guild} 303 onClose={() => { 304 setModal(undefined); 305 }}
··· 1 "use client"; 2 3 import type { Guild } from "@/common/guilds"; 4 import SelectInput from "@/components/inputs/select-menu"; 5 import Switch from "@/components/inputs/switch"; ··· 7 import Modal from "@/components/modal"; 8 import type { ApiV1GuildsModulesLeaderboardUpdatingPostResponse } from "@/typings"; 9 import { createSelectableEmojiItems, createSelectableItems } from "@/utils/create-selectable-items"; 10 + import { Tab, Tabs } from "@nextui-org/react"; 11 + import Link from "next/link"; 12 + import { useCookies } from "next-client-cookies"; 13 + import { useState } from "react"; 14 + import { HiExternalLink, HiPencil, HiTrash } from "react-icons/hi"; 15 16 interface Props { 17 guild: Guild; ··· 110 <Modal 111 className="flex flex-col gap-3" 112 title={`${type.replace(/^\w/, (match) => match.toUpperCase())} leaderboard`} 113 + isOpen={modal === ModalType.CreateAndEdit && Boolean(guild)} 114 isDisabled={!channelId} 115 onClose={() => { 116 setModal(undefined); ··· 140 ...leaderboard, 141 type, 142 // @ts-expect-error it works 143 + channelId, 144 + structure, 145 + emoji: emoji || null, 146 display, 147 styles 148 }); ··· 170 name="Channel" 171 items={createSelectableItems(guild.channels, ["ViewChannel", "SendMessages", "EmbedLinks", "AttachFiles"])} 172 description="Select a channel where the leaderboard should be send into." 173 + defaultState={leaderboard?.channelId} 174 + onSave={(o) => setChannelId(o.value as string)} 175 /> 176 177 <div className="mb-3"> ··· 182 color="secondary" 183 variant="bordered" 184 defaultSelectedKey={structure?.toString()} 185 + onSelectionChange={(i) => setStructure(Number.parseInt(i as string, 10))} 186 fullWidth 187 > 188 <Tab ··· 217 <TextInput 218 name="Title" 219 description="The title of the embed" 220 + defaultState={`☕ ${type.replace(/^\w/, (match) => match.toUpperCase())} leaderboard`} 221 max={256} 222 onSave={(v) => { 223 setEmbed({ ··· 298 buttonName="Delete" 299 variant="destructive" 300 title={`Delete ${type.replace(/^\w/, (match) => match.toUpperCase())} leaderboard`} 301 + isOpen={modal === ModalType.Delete && Boolean(guild)} 302 onClose={() => { 303 setModal(undefined); 304 }}
+2 -3
app/dashboard/[guildId]/leaderboards/widget-button.component.tsx
··· 1 import React, { useState } from "react"; 2 import { HiEmojiHappy, HiLockClosed } from "react-icons/hi"; 3 - 4 - import { Button } from "@/components/ui/button"; 5 6 enum State { 7 Idle = 0, ··· 38 39 if (res.status === 429) { 40 setState(State.Ratelimited); 41 - setTimeout(() => setState(State.Idle), 6 * 1000); 42 } else setState(State.Idle); 43 44 if (res.ok) {
··· 1 + import { Button } from "@/components/ui/button"; 2 import React, { useState } from "react"; 3 import { HiEmojiHappy, HiLockClosed } from "react-icons/hi"; 4 5 enum State { 6 Idle = 0, ··· 37 38 if (res.status === 429) { 39 setState(State.Ratelimited); 40 + setTimeout(() => setState(State.Idle), 6 * 1_000); 41 } else setState(State.Idle); 42 43 if (res.ok) {
+6 -7
app/dashboard/[guildId]/leaderboards/widget.component.tsx
··· 1 - import type { RESTError, RESTGetAPIGuildWidgetJSONResult } from "discord-api-types/v10"; 2 - import { useState } from "react"; 3 - import { HiEmojiHappy, HiLockClosed } from "react-icons/hi"; 4 - import { useQuery } from "react-query"; 5 - 6 import type { Guild } from "@/common/guilds"; 7 import Notice from "@/components/notice"; 8 import { Skeleton } from "@/components/ui/skeleton"; 9 import { cacheOptions } from "@/lib/api"; 10 import { cn } from "@/utils/cn"; 11 12 import DiscordWidgetButton from "./widget-button.component"; 13 ··· 24 url, 25 () => fetch(url).then((res) => res.json()) as Promise<RESTGetAPIGuildWidgetJSONResult | RESTError>, 26 { 27 - enabled: !!guild.id, 28 ...cacheOptions, 29 onSuccess: (data) => setEnabled(!("code" in data)), 30 refetchOnMount: true 31 } 32 ); 33 34 - if (error || (data && "message" in data && data.code !== 50004)) { 35 return ( 36 <div className="md:w-1/2"> 37 <Notice
··· 1 import type { Guild } from "@/common/guilds"; 2 import Notice from "@/components/notice"; 3 import { Skeleton } from "@/components/ui/skeleton"; 4 import { cacheOptions } from "@/lib/api"; 5 import { cn } from "@/utils/cn"; 6 + import type { RESTError, RESTGetAPIGuildWidgetJSONResult } from "discord-api-types/v10"; 7 + import { useState } from "react"; 8 + import { HiEmojiHappy, HiLockClosed } from "react-icons/hi"; 9 + import { useQuery } from "react-query"; 10 11 import DiscordWidgetButton from "./widget-button.component"; 12 ··· 23 url, 24 () => fetch(url).then((res) => res.json()) as Promise<RESTGetAPIGuildWidgetJSONResult | RESTError>, 25 { 26 + enabled: Boolean(guild.id), 27 ...cacheOptions, 28 onSuccess: (data) => setEnabled(!("code" in data)), 29 refetchOnMount: true 30 } 31 ); 32 33 + if (error || (data && "message" in data && data.code !== 50_004)) { 34 return ( 35 <div className="md:w-1/2"> 36 <Notice
+5 -6
app/dashboard/[guildId]/moderation/page.tsx
··· 1 "use client"; 2 3 - import { ChannelType } from "discord-api-types/v10"; 4 - import { useParams } from "next/navigation"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import MultiSelectMenu from "@/components/inputs/multi-select-menu"; 8 import Switch from "@/components/inputs/switch"; ··· 11 import { useApi } from "@/lib/api/hook"; 12 import { type ApiV1GuildsModulesAutomodGetResponse, AutomodType } from "@/typings"; 13 import { createSelectableItems } from "@/utils/create-selectable-items"; 14 15 const AUTOMOD_TYPES = Object 16 .values(AutomodType) ··· 61 max={50} 62 disabled={!enabled} 63 onSave={(value) => { 64 - edit("whitelistChannelIds", value.map((entry) => entry.value as string)); 65 }} 66 /> 67 </div> ··· 76 max={20} 77 disabled={!enabled} 78 onSave={(value) => { 79 - edit("whitelistRoleIds", value.map((entry) => entry.value as string)); 80 }} 81 /> 82 </div> ··· 90 defaultState={data.keywordFilter.join(", ")} 91 max={Infinity} 92 onSave={(value) => { 93 - edit("keywordFilter", (value as string | null)?.split(/,|\n/).map((word) => word.trim()) || []); 94 }} 95 /> 96 </>);
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import MultiSelectMenu from "@/components/inputs/multi-select-menu"; 5 import Switch from "@/components/inputs/switch"; ··· 8 import { useApi } from "@/lib/api/hook"; 9 import { type ApiV1GuildsModulesAutomodGetResponse, AutomodType } from "@/typings"; 10 import { createSelectableItems } from "@/utils/create-selectable-items"; 11 + import { ChannelType } from "discord-api-types/v10"; 12 + import { useParams } from "next/navigation"; 13 14 const AUTOMOD_TYPES = Object 15 .values(AutomodType) ··· 60 max={50} 61 disabled={!enabled} 62 onSave={(value) => { 63 + edit("whitelistChannelIds", value.map((entry) => entry.value)); 64 }} 65 /> 66 </div> ··· 75 max={20} 76 disabled={!enabled} 77 onSave={(value) => { 78 + edit("whitelistRoleIds", value.map((entry) => entry.value)); 79 }} 80 /> 81 </div> ··· 89 defaultState={data.keywordFilter.join(", ")} 90 max={Infinity} 91 onSave={(value) => { 92 + edit("keywordFilter", (value)?.split(/,|\n/).map((word) => word.trim()) || []); 93 }} 94 /> 95 </>);
+1 -1
app/dashboard/[guildId]/notifications/api.ts
··· 14 .catch(() => null) as ApiGetPost | null; 15 16 if (!res) return false; 17 - return !!res.feed.length; 18 }
··· 14 .catch(() => null) as ApiGetPost | null; 15 16 if (!res) return false; 17 + return Boolean(res.feed.length); 18 }
+9 -10
app/dashboard/[guildId]/notifications/create-bluesky.component.tsx
··· 1 "use client"; 2 3 - import { useState } from "react"; 4 - 5 import { guildStore } from "@/common/guilds"; 6 import DumbTextInput from "@/components/inputs/dumb-text-input"; 7 import SelectMenu from "@/components/inputs/select-menu"; ··· 9 import { Section } from "@/components/section"; 10 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 11 import { createSelectableItems } from "@/utils/create-selectable-items"; 12 13 - const URL_CHANNEL_REGEX = /^https?:\/\/((www|m)\.)?bsky\.app\/profile\/did:plc:[a-z0-9]{20,30}$/; 14 - const URL_HANDLE_REGEX = /^https?:\/\/((www|m)\.)?bsky\.app\/profile\/[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/; 15 - const CHANNEL_ID = /^did:plc:[a-z0-9]{20,30}$/; 16 - const CHANNE_HANDLE = /^@?[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/; 17 18 function validateAccount(input: string) { 19 - if (URL_CHANNEL_REGEX.exec(input)) return input.split("/profile/")[1]; 20 - if (URL_HANDLE_REGEX.exec(input)) return input.split("/profile/")[1]; 21 22 - if (CHANNEL_ID.exec(input)) return input; 23 - if (CHANNE_HANDLE.exec(input)) return input.replace("@", ""); 24 25 return null; 26 }
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import DumbTextInput from "@/components/inputs/dumb-text-input"; 5 import SelectMenu from "@/components/inputs/select-menu"; ··· 7 import { Section } from "@/components/section"; 8 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 9 import { createSelectableItems } from "@/utils/create-selectable-items"; 10 + import { useState } from "react"; 11 12 + const URL_CHANNEL_REGEX = /^https?:\/\/((www|m)\.)?bsky\.app\/profile\/did:plc:[\da-z]{20,30}$/; 13 + const URL_HANDLE_REGEX = /^https?:\/\/((www|m)\.)?bsky\.app\/profile\/[\dA-Za-z-]+(\.[\dA-Za-z-]+)+$/; 14 + const CHANNEL_ID = /^did:plc:[\da-z]{20,30}$/; 15 + const CHANNE_HANDLE = /^@?[\dA-Za-z-]+(\.[\dA-Za-z-]+)+$/; 16 17 function validateAccount(input: string) { 18 + if (URL_CHANNEL_REGEX.test(input)) return input.split("/profile/")[1]; 19 + if (URL_HANDLE_REGEX.test(input)) return input.split("/profile/")[1]; 20 21 + if (CHANNEL_ID.test(input)) return input; 22 + if (CHANNE_HANDLE.test(input)) return input.replace("@", ""); 23 24 return null; 25 }
+5 -6
app/dashboard/[guildId]/notifications/create-reddit.component.tsx
··· 1 "use client"; 2 3 - import { useState } from "react"; 4 - 5 import { guildStore } from "@/common/guilds"; 6 import DumbTextInput from "@/components/inputs/dumb-text-input"; 7 import SelectMenu from "@/components/inputs/select-menu"; ··· 9 import { Section } from "@/components/section"; 10 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 11 import { createSelectableItems } from "@/utils/create-selectable-items"; 12 13 - const URL_CHANNEL_REGEX = /^https?:\/\/((www|m|old|oauth)\.)?reddit\.com\/r\/(?=.{3,21}$)[A-Za-z][A-Za-z0-9_]*\/?$/; 14 - const CHANNE_HANDLE = /^((\/)?r\/)?(?=.{3,21}$)[A-Za-z][A-Za-z0-9_]*$/; 15 16 function validateAccount(input: string) { 17 - if (URL_CHANNEL_REGEX.exec(input)) return input.split("/r/")[1].replace(/\/$/, ""); 18 - if (CHANNE_HANDLE.exec(input)) return input.replace(/^(\/)?r\//, ""); 19 return null; 20 } 21
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import DumbTextInput from "@/components/inputs/dumb-text-input"; 5 import SelectMenu from "@/components/inputs/select-menu"; ··· 7 import { Section } from "@/components/section"; 8 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 9 import { createSelectableItems } from "@/utils/create-selectable-items"; 10 + import { useState } from "react"; 11 12 + const URL_CHANNEL_REGEX = /^https?:\/\/((www|m|old|oauth)\.)?reddit\.com\/r\/(?=.{3,21}$)[A-Za-z]\w*\/?$/; 13 + const CHANNE_HANDLE = /^((\/)?r\/)?(?=.{3,21}$)[A-Za-z]\w*$/; 14 15 function validateAccount(input: string) { 16 + if (URL_CHANNEL_REGEX.test(input)) return input.split("/r/")[1].replace(/\/$/, ""); 17 + if (CHANNE_HANDLE.test(input)) return input.replace(/^(\/)?r\//, ""); 18 return null; 19 } 20
+6 -7
app/dashboard/[guildId]/notifications/create-twitch.component.tsx
··· 1 "use client"; 2 3 - import Image from "next/image"; 4 - import { useState } from "react"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import DumbTextInput from "@/components/inputs/dumb-text-input"; 8 import SelectMenu from "@/components/inputs/select-menu"; ··· 11 import TutorialPic from "@/public/docs-assets/notifications-channel-urls.webp"; 12 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 13 import { createSelectableItems } from "@/utils/create-selectable-items"; 14 15 - const URL_CHANNEL_REGEX = /^https?:\/\/((www|m)\.)?twitch\.tv\/([a-zA-Z0-9_-]{1,32})$/; 16 - const CHANNE_HANDLE = /^@?[a-zA-Z0-9._-]{1,32}$/; 17 18 function validateAccount(input: string) { 19 - if (URL_CHANNEL_REGEX.exec(input)) return input.split(".tv/")[1]; 20 - if (CHANNE_HANDLE.exec(input)) return input.replace("@", ""); 21 return null; 22 } 23
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import DumbTextInput from "@/components/inputs/dumb-text-input"; 5 import SelectMenu from "@/components/inputs/select-menu"; ··· 8 import TutorialPic from "@/public/docs-assets/notifications-channel-urls.webp"; 9 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 10 import { createSelectableItems } from "@/utils/create-selectable-items"; 11 + import Image from "next/image"; 12 + import { useState } from "react"; 13 14 + const URL_CHANNEL_REGEX = /^https?:\/\/((www|m)\.)?twitch\.tv\/([\w-]{1,32})$/; 15 + const CHANNE_HANDLE = /^@?[\w.-]{1,32}$/; 16 17 function validateAccount(input: string) { 18 + if (URL_CHANNEL_REGEX.test(input)) return input.split(".tv/")[1]; 19 + if (CHANNE_HANDLE.test(input)) return input.replace("@", ""); 20 return null; 21 } 22
+10 -11
app/dashboard/[guildId]/notifications/create-youtube.component.tsx
··· 1 "use client"; 2 3 - import Image from "next/image"; 4 - import { useState } from "react"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import DumbTextInput from "@/components/inputs/dumb-text-input"; 8 import SelectMenu from "@/components/inputs/select-menu"; ··· 11 import TutorialPic from "@/public/docs-assets/notifications-channel-urls.webp"; 12 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 13 import { createSelectableItems } from "@/utils/create-selectable-items"; 14 15 - const URL_CHANNEL_REGEX = /^https?:\/\/((www|m)\.)?youtube\.com\/channel\/UC([a-zA-Z0-9_-]{16,32})$/; 16 - const URL_HANDLE_REGEX = /^https?:\/\/((www|m)\.)?youtube\.com\/@([a-zA-Z0-9._-]{3,30})$/; 17 - const CHANNEL_ID = /^UC[a-zA-Z0-9_-]{16,32}$/; 18 - const CHANNE_HANDLE = /^@?[a-zA-Z0-9._-]{3,30}$/; 19 20 function validateAccount(input: string) { 21 - if (URL_CHANNEL_REGEX.exec(input)) return input.split("/channel/")[1]; 22 - if (URL_HANDLE_REGEX.exec(input)) return input.split("/@")[1]; 23 24 - if (CHANNEL_ID.exec(input)) return input; 25 - if (CHANNE_HANDLE.exec(input)) return input.replace("@", ""); 26 27 return null; 28 }
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import DumbTextInput from "@/components/inputs/dumb-text-input"; 5 import SelectMenu from "@/components/inputs/select-menu"; ··· 8 import TutorialPic from "@/public/docs-assets/notifications-channel-urls.webp"; 9 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 10 import { createSelectableItems } from "@/utils/create-selectable-items"; 11 + import Image from "next/image"; 12 + import { useState } from "react"; 13 14 + const URL_CHANNEL_REGEX = /^https?:\/\/((www|m)\.)?youtube\.com\/channel\/UC([\w-]{16,32})$/; 15 + const URL_HANDLE_REGEX = /^https?:\/\/((www|m)\.)?youtube\.com\/@([\w.-]{3,30})$/; 16 + const CHANNEL_ID = /^UC[\w-]{16,32}$/; 17 + const CHANNE_HANDLE = /^@?[\w.-]{3,30}$/; 18 19 function validateAccount(input: string) { 20 + if (URL_CHANNEL_REGEX.test(input)) return input.split("/channel/")[1]; 21 + if (URL_HANDLE_REGEX.test(input)) return input.split("/@")[1]; 22 23 + if (CHANNEL_ID.test(input)) return input; 24 + if (CHANNE_HANDLE.test(input)) return input.replace("@", ""); 25 26 return null; 27 }
+2 -4
app/dashboard/[guildId]/notifications/delete.component.tsx
··· 1 "use client"; 2 3 - 4 - import { useState } from "react"; 5 - import { HiTrash } from "react-icons/hi"; 6 - 7 import { guildStore } from "@/common/guilds"; 8 import Modal from "@/components/modal"; 9 import { Button } from "@/components/ui/button"; 10 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 11 12 interface Props { 13 id: string | null;
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import Modal from "@/components/modal"; 5 import { Button } from "@/components/ui/button"; 6 import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; 7 + import { useState } from "react"; 8 + import { HiTrash } from "react-icons/hi"; 9 10 interface Props { 11 id: string | null;
+6 -7
app/dashboard/[guildId]/notifications/page.tsx
··· 1 "use client"; 2 3 - import { LoaderCircleIcon } from "lucide-react"; 4 - import Image from "next/image"; 5 - import { useParams } from "next/navigation"; 6 - import { type ReactNode, useMemo } from "react"; 7 - import { HiChat, HiViewGridAdd } from "react-icons/hi"; 8 - import { useQuery } from "react-query"; 9 - 10 import { guildStore } from "@/common/guilds"; 11 import Fetch from "@/components/button-fetch"; 12 import { ClientBadge } from "@/components/client"; ··· 25 import { BitfieldManager, bitfieldToArray } from "@/utils/bitfields"; 26 import { createSelectableItems } from "@/utils/create-selectable-items"; 27 import { getCanonicalUrl } from "@/utils/urls"; 28 29 import { hasBlueskyPost } from "./api"; 30 import { DeleteNotification } from "./delete.component";
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import Fetch from "@/components/button-fetch"; 5 import { ClientBadge } from "@/components/client"; ··· 18 import { BitfieldManager, bitfieldToArray } from "@/utils/bitfields"; 19 import { createSelectableItems } from "@/utils/create-selectable-items"; 20 import { getCanonicalUrl } from "@/utils/urls"; 21 + import { LoaderCircleIcon } from "lucide-react"; 22 + import Image from "next/image"; 23 + import { useParams } from "next/navigation"; 24 + import { type ReactNode, useMemo } from "react"; 25 + import { HiChat, HiViewGridAdd } from "react-icons/hi"; 26 + import { useQuery } from "react-query"; 27 28 import { hasBlueskyPost } from "./api"; 29 import { DeleteNotification } from "./delete.component";
+4 -5
app/dashboard/[guildId]/notifications/select.component.tsx
··· 1 - import { PopoverClose } from "@radix-ui/react-popover"; 2 - import React, { useState } from "react"; 3 - import { BsReddit, BsTwitch, BsYoutube } from "react-icons/bs"; 4 - import { FaBluesky } from "react-icons/fa6"; 5 - 6 import { badgeVariants } from "@/components/ui/badge"; 7 import { Button } from "@/components/ui/button"; 8 import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; 9 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 10 import { cn } from "@/utils/cn"; 11 12 import { BlueskyNotificationModal } from "./create-bluesky.component"; 13 import { RedditNotificationModal } from "./create-reddit.component";
··· 1 import { badgeVariants } from "@/components/ui/badge"; 2 import { Button } from "@/components/ui/button"; 3 import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; 4 import { type ApiV1GuildsModulesNotificationsGetResponse, NotificationType } from "@/typings"; 5 import { cn } from "@/utils/cn"; 6 + import { PopoverClose } from "@radix-ui/react-popover"; 7 + import React, { useState } from "react"; 8 + import { BsReddit, BsTwitch, BsYoutube } from "react-icons/bs"; 9 + import { FaBluesky } from "react-icons/fa6"; 10 11 import { BlueskyNotificationModal } from "./create-bluesky.component"; 12 import { RedditNotificationModal } from "./create-reddit.component";
+5 -7
app/dashboard/[guildId]/notifications/style.component.tsx
··· 1 "use client"; 2 - import Link from "next/link"; 3 - import { useCallback, useEffect, useMemo, useRef, useState } from "react"; 4 - import { HiOutlineUpload, HiPencil, HiSparkles, HiX } from "react-icons/hi"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import { DiscordMarkdown } from "@/components/discord/markdown"; 8 import DiscordMessage from "@/components/discord/message"; ··· 14 import type { ApiError, ApiV1GuildsModulesNotificationsGetResponse, ApiV1GuildsModulesNotificationStylePatchResponse } from "@/typings"; 15 import { State } from "@/utils/captcha"; 16 import { cn } from "@/utils/cn"; 17 18 const ALLOWED_FILE_TYPES = ["image/png", "image/jpeg", "image/webp"]; 19 - const MAX_FILE_SIZE = 8 * 1024 * 1024; 20 21 export function NotificationStyle({ 22 item, ··· 224 } 225 226 if (file.size > MAX_FILE_SIZE) { 227 - setError(`File size must be less than ${MAX_FILE_SIZE / 1024 / 1024}MiB`); 228 return; 229 } 230 - 231 232 file.arrayBuffer().then((buffer) => { 233 setAvatar(buffer);
··· 1 "use client"; 2 import { guildStore } from "@/common/guilds"; 3 import { DiscordMarkdown } from "@/components/discord/markdown"; 4 import DiscordMessage from "@/components/discord/message"; ··· 10 import type { ApiError, ApiV1GuildsModulesNotificationsGetResponse, ApiV1GuildsModulesNotificationStylePatchResponse } from "@/typings"; 11 import { State } from "@/utils/captcha"; 12 import { cn } from "@/utils/cn"; 13 + import Link from "next/link"; 14 + import { useCallback, useEffect, useMemo, useRef, useState } from "react"; 15 + import { HiOutlineUpload, HiPencil, HiSparkles, HiX } from "react-icons/hi"; 16 17 const ALLOWED_FILE_TYPES = ["image/png", "image/jpeg", "image/webp"]; 18 + const MAX_FILE_SIZE = 8 * 1_024 * 1_024; 19 20 export function NotificationStyle({ 21 item, ··· 223 } 224 225 if (file.size > MAX_FILE_SIZE) { 226 + setError(`File size must be less than ${MAX_FILE_SIZE / 1_024 / 1_024}MiB`); 227 return; 228 } 229 230 file.arrayBuffer().then((buffer) => { 231 setAvatar(buffer);
+3 -4
app/dashboard/[guildId]/page.tsx
··· 1 "use client"; 2 3 - import { useParams } from "next/navigation"; 4 - import { HiChartBar } from "react-icons/hi"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import Switch from "@/components/inputs/switch"; 8 import { Section } from "@/components/section"; 9 10 - import { OverviewLink } from "../../../components/overview-link"; 11 import { BotStyle } from "./style.component"; 12 import { TTSSettings } from "./tts.component"; 13 import FollowUpdates from "./updates.component"; 14 15 export default function Home() { 16 const guild = guildStore((g) => g);
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import Switch from "@/components/inputs/switch"; 5 import { Section } from "@/components/section"; 6 + import { useParams } from "next/navigation"; 7 + import { HiChartBar } from "react-icons/hi"; 8 9 import { BotStyle } from "./style.component"; 10 import { TTSSettings } from "./tts.component"; 11 import FollowUpdates from "./updates.component"; 12 + import { OverviewLink } from "../../../components/overview-link"; 13 14 export default function Home() { 15 const guild = guildStore((g) => g);
+1 -2
app/dashboard/[guildId]/starboard/hooks.ts
··· 1 import { useEffect, useState } from "react"; 2 - 3 - import { StarboardStyle } from "@/typings"; 4 5 interface Example { 6 avatar: string | null;
··· 1 + import { StarboardStyle } from "@/typings"; 2 import { useEffect, useState } from "react"; 3 4 interface Example { 5 avatar: string | null;
+6 -7
app/dashboard/[guildId]/starboard/page.tsx
··· 1 "use client"; 2 3 - import Image from "next/image"; 4 - import Link from "next/link"; 5 - import { useParams } from "next/navigation"; 6 - import { HiExternalLink } from "react-icons/hi"; 7 - 8 import { guildStore } from "@/common/guilds"; 9 import { DiscordMarkdown } from "@/components/discord/markdown"; 10 import DiscordMessage from "@/components/discord/message"; ··· 19 import { useApi } from "@/lib/api/hook"; 20 import { type ApiV1GuildsModulesStarboardGetResponse, StarboardStyle } from "@/typings"; 21 import { createSelectableItems } from "@/utils/create-selectable-items"; 22 23 import { useExample } from "./hooks"; 24 ··· 222 defaultState={data.blacklistChannelIds || []} 223 max={500} 224 disabled={!data.enabled} 225 - onSave={(o) => edit("blacklistChannelIds", o.map(({ value }) => value as string))} 226 /> 227 </div> 228 <div className="lg:w-1/2"> ··· 235 defaultState={data.blacklistRoleIds || []} 236 max={500} 237 disabled={!data.enabled} 238 - onSave={(o) => edit("blacklistChannelIds", o.map(({ value }) => value as string))} 239 /> 240 </div> 241 </div>
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import { DiscordMarkdown } from "@/components/discord/markdown"; 5 import DiscordMessage from "@/components/discord/message"; ··· 14 import { useApi } from "@/lib/api/hook"; 15 import { type ApiV1GuildsModulesStarboardGetResponse, StarboardStyle } from "@/typings"; 16 import { createSelectableItems } from "@/utils/create-selectable-items"; 17 + import Image from "next/image"; 18 + import Link from "next/link"; 19 + import { useParams } from "next/navigation"; 20 + import { HiExternalLink } from "react-icons/hi"; 21 22 import { useExample } from "./hooks"; 23 ··· 221 defaultState={data.blacklistChannelIds || []} 222 max={500} 223 disabled={!data.enabled} 224 + onSave={(o) => edit("blacklistChannelIds", o.map(({ value }) => value))} 225 /> 226 </div> 227 <div className="lg:w-1/2"> ··· 234 defaultState={data.blacklistRoleIds || []} 235 max={500} 236 disabled={!data.enabled} 237 + onSave={(o) => edit("blacklistChannelIds", o.map(({ value }) => value))} 238 /> 239 </div> 240 </div>
+7 -9
app/dashboard/[guildId]/style.component.tsx
··· 1 "use client"; 2 - import Image from "next/image"; 3 - import { useCallback, useEffect, useMemo, useRef, useState } from "react"; 4 - import { HiOutlineUpload, HiPencil, HiX } from "react-icons/hi"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import DiscordMessage from "@/components/discord/message"; 8 import DumbTextInput from "@/components/inputs/dumb-text-input"; ··· 13 import { type ApiError, type ApiV1GuildsGetResponse, type ApiV1GuildsStylePatchResponse, GuildFlags } from "@/typings"; 14 import { State } from "@/utils/captcha"; 15 import { cn } from "@/utils/cn"; 16 17 const ALLOWED_FILE_TYPES = ["image/jpg", "image/jpeg", "image/png", "image/webp", "image/gif", "image/apng"]; 18 - const MAX_FILE_SIZE = 8 * 1024 * 1024; 19 20 export function BotStyle() { 21 const guild = guildStore((g) => g!); ··· 40 41 <div className="space-y-2"> 42 <span className="text-3xl font-medium text-primary-foreground"> 43 - {guild.style.username ? guild.style.username : "Wamellow"} 44 </span> 45 <div className="flex"> 46 <Button onClick={() => setOpen(true)}> ··· 186 if (!name || !valid) return new Error("Invalid name"); 187 188 const formData = new FormData(); 189 - formData.append("json_payload", JSON.stringify({ username: name, bio: bio })); 190 if (avatar && typeof avatar !== "string") formData.append("file[0]", new Blob([avatar]), "avatar"); 191 if (banner && typeof banner !== "string") formData.append("file[1]", new Blob([banner]), "banner"); 192 ··· 293 } 294 295 if (file.size > MAX_FILE_SIZE) { 296 - setError(`File size must be less than ${MAX_FILE_SIZE / 1024 / 1024}MiB`); 297 return; 298 } 299 - 300 301 file.arrayBuffer().then((buffer) => { 302 setBuf(buffer);
··· 1 "use client"; 2 import { guildStore } from "@/common/guilds"; 3 import DiscordMessage from "@/components/discord/message"; 4 import DumbTextInput from "@/components/inputs/dumb-text-input"; ··· 9 import { type ApiError, type ApiV1GuildsGetResponse, type ApiV1GuildsStylePatchResponse, GuildFlags } from "@/typings"; 10 import { State } from "@/utils/captcha"; 11 import { cn } from "@/utils/cn"; 12 + import Image from "next/image"; 13 + import { useCallback, useEffect, useMemo, useRef, useState } from "react"; 14 + import { HiOutlineUpload, HiPencil, HiX } from "react-icons/hi"; 15 16 const ALLOWED_FILE_TYPES = ["image/jpg", "image/jpeg", "image/png", "image/webp", "image/gif", "image/apng"]; 17 + const MAX_FILE_SIZE = 8 * 1_024 * 1_024; 18 19 export function BotStyle() { 20 const guild = guildStore((g) => g!); ··· 39 40 <div className="space-y-2"> 41 <span className="text-3xl font-medium text-primary-foreground"> 42 + {guild.style.username || "Wamellow"} 43 </span> 44 <div className="flex"> 45 <Button onClick={() => setOpen(true)}> ··· 185 if (!name || !valid) return new Error("Invalid name"); 186 187 const formData = new FormData(); 188 + formData.append("json_payload", JSON.stringify({ username: name, bio })); 189 if (avatar && typeof avatar !== "string") formData.append("file[0]", new Blob([avatar]), "avatar"); 190 if (banner && typeof banner !== "string") formData.append("file[1]", new Blob([banner]), "banner"); 191 ··· 292 } 293 294 if (file.size > MAX_FILE_SIZE) { 295 + setError(`File size must be less than ${MAX_FILE_SIZE / 1_024 / 1_024}MiB`); 296 return; 297 } 298 299 file.arrayBuffer().then((buffer) => { 300 setBuf(buffer);
+5 -6
app/dashboard/[guildId]/tts.component.tsx
··· 1 - import { ChannelType } from "discord-api-types/v10"; 2 - import { useParams } from "next/navigation"; 3 - import { useCallback } from "react"; 4 - 5 import { type Guild, guildStore } from "@/common/guilds"; 6 import NumberInput from "@/components/inputs/number-input"; 7 import SelectMenu from "@/components/inputs/select-menu"; 8 import Switch from "@/components/inputs/switch"; 9 import { TTSFaq } from "@/components/tts-faq"; 10 import { createSelectableItems } from "@/utils/create-selectable-items"; 11 12 export function TTSSettings() { 13 const guild = guildStore((g) => g); ··· 89 description="The maximum length of a message that can be spoken." 90 url={`/guilds/${params.guildId}`} 91 dataName="tts.maxLength" 92 - defaultState={guild?.tts.maxLength || 4000} 93 - max={4000} 94 onSave={(value) => edit("maxLength", value)} 95 /> 96 </div>
··· 1 import { type Guild, guildStore } from "@/common/guilds"; 2 import NumberInput from "@/components/inputs/number-input"; 3 import SelectMenu from "@/components/inputs/select-menu"; 4 import Switch from "@/components/inputs/switch"; 5 import { TTSFaq } from "@/components/tts-faq"; 6 import { createSelectableItems } from "@/utils/create-selectable-items"; 7 + import { ChannelType } from "discord-api-types/v10"; 8 + import { useParams } from "next/navigation"; 9 + import { useCallback } from "react"; 10 11 export function TTSSettings() { 12 const guild = guildStore((g) => g); ··· 88 description="The maximum length of a message that can be spoken." 89 url={`/guilds/${params.guildId}`} 90 dataName="tts.maxLength" 91 + defaultState={guild?.tts.maxLength || 4_000} 92 + max={4_000} 93 onSave={(value) => edit("maxLength", value)} 94 /> 95 </div>
+4 -5
app/dashboard/[guildId]/updates.component.tsx
··· 1 "use client"; 2 3 - import { useState } from "react"; 4 - import { HiMail } from "react-icons/hi"; 5 - 6 import { guildStore } from "@/common/guilds"; 7 import SelectMenu from "@/components/inputs/select-menu"; 8 import Modal from "@/components/modal"; 9 import { createSelectableItems } from "@/utils/create-selectable-items"; 10 11 export default function FollowUpdates() { 12 const guild = guildStore((g) => g); ··· 44 <Modal 45 title="Wamellow updates" 46 className="!overflow-visible" 47 - isOpen={open && !!guild} 48 onClose={() => setOpen(false)} 49 onSubmit={() => { 50 return fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${guild?.id}/follow-updates`, { ··· 63 if (!g) return g; 64 65 g.follownewsChannel = { 66 - name: g!.channels!.find((c) => c.id === channelId)!.name, 67 id: channelId! 68 }; 69
··· 1 "use client"; 2 3 import { guildStore } from "@/common/guilds"; 4 import SelectMenu from "@/components/inputs/select-menu"; 5 import Modal from "@/components/modal"; 6 import { createSelectableItems } from "@/utils/create-selectable-items"; 7 + import { useState } from "react"; 8 + import { HiMail } from "react-icons/hi"; 9 10 export default function FollowUpdates() { 11 const guild = guildStore((g) => g); ··· 43 <Modal 44 title="Wamellow updates" 45 className="!overflow-visible" 46 + isOpen={open && Boolean(guild)} 47 onClose={() => setOpen(false)} 48 onSubmit={() => { 49 return fetch(`${process.env.NEXT_PUBLIC_API}/guilds/${guild?.id}/follow-updates`, { ··· 62 if (!g) return g; 63 64 g.follownewsChannel = { 65 + name: g.channels!.find((c) => c.id === channelId)!.name, 66 id: channelId! 67 }; 68
+2 -2
app/dashboard/page.tsx
··· 13 14 const params = new URLSearchParams(); 15 16 - Object.keys(obj).forEach((key) => { 17 const value = obj[key]; 18 if (value !== null && value !== undefined) { 19 params.append(key, value.toString()); 20 } 21 - }); 22 23 return params.toString(); 24 }
··· 13 14 const params = new URLSearchParams(); 15 16 + for (const key of Object.keys(obj)) { 17 const value = obj[key]; 18 if (value !== null && value !== undefined) { 19 params.append(key, value.toString()); 20 } 21 + } 22 23 return params.toString(); 24 }
+6 -7
app/docs/[...pathname]/layout.tsx
··· 1 - import type { Metadata } from "next"; 2 - import Link from "next/link"; 3 - import { BsDiscord, BsGithub } from "react-icons/bs"; 4 - import { HiUserAdd, HiViewGridAdd } from "react-icons/hi"; 5 - 6 import { Footer } from "@/components/footer"; 7 import { LinkButton } from "@/components/ui/button"; 8 import { Separator } from "@/components/ui/separator"; 9 import metadata from "@/public/docs/meta.json"; 10 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 11 12 interface Props { 13 params: Promise<{ pathname: string[]; }>; ··· 26 const images = { 27 url: meta?.image || `${getBaseUrl()}/waya-v3.webp?v=2`, 28 alt: meta?.description, 29 - heigth: 1008, 30 - width: 1935 31 }; 32 33 return {
··· 1 import { Footer } from "@/components/footer"; 2 import { LinkButton } from "@/components/ui/button"; 3 import { Separator } from "@/components/ui/separator"; 4 import metadata from "@/public/docs/meta.json"; 5 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 6 + import type { Metadata } from "next"; 7 + import Link from "next/link"; 8 + import { BsDiscord, BsGithub } from "react-icons/bs"; 9 + import { HiUserAdd, HiViewGridAdd } from "react-icons/hi"; 10 11 interface Props { 12 params: Promise<{ pathname: string[]; }>; ··· 25 const images = { 26 url: meta?.image || `${getBaseUrl()}/waya-v3.webp?v=2`, 27 alt: meta?.description, 28 + heigth: 1_008, 29 + width: 1_935 30 }; 31 32 return {
+1 -2
app/docs/[...pathname]/page.tsx
··· 1 - import { readFile } from "fs/promises"; 2 - 3 import { Faq } from "@/app/(home)/faq.component"; 4 import BeautifyMarkdown from "@/components/markdown"; 5 import Notice, { NoticeType } from "@/components/notice"; 6 import { ScreenMessage } from "@/components/screen-message"; 7 import { Badge } from "@/components/ui/badge"; 8 import metadata from "@/public/docs/meta.json"; 9 10 interface Props { 11 params: Promise<{ pathname: string[]; }>;
··· 1 import { Faq } from "@/app/(home)/faq.component"; 2 import BeautifyMarkdown from "@/components/markdown"; 3 import Notice, { NoticeType } from "@/components/notice"; 4 import { ScreenMessage } from "@/components/screen-message"; 5 import { Badge } from "@/components/ui/badge"; 6 import metadata from "@/public/docs/meta.json"; 7 + import { readFile } from "fs/promises"; 8 9 interface Props { 10 params: Promise<{ pathname: string[]; }>;
+6 -8
app/layout.tsx
··· 1 import "./globals.css"; 2 - 3 import type { Metadata, Viewport } from "next"; 4 import { Lexend, Noto_Sans_JP, Outfit } from "next/font/google"; 5 import { cookies } from "next/headers"; ··· 7 import Link from "next/link"; 8 import Script from "next/script"; 9 import { CookiesProvider } from "next-client-cookies/server"; 10 - 11 - import { Header } from "@/components/header"; 12 - import { LoginButton } from "@/components/login-button"; 13 - import { Button } from "@/components/ui/button"; 14 - import { Separator } from "@/components/ui/separator"; 15 - import { cn } from "@/utils/cn"; 16 - import { getBaseUrl } from "@/utils/urls"; 17 18 import { Provider } from "./provider"; 19
··· 1 import "./globals.css"; 2 + import { Header } from "@/components/header"; 3 + import { LoginButton } from "@/components/login-button"; 4 + import { Button } from "@/components/ui/button"; 5 + import { Separator } from "@/components/ui/separator"; 6 + import { cn } from "@/utils/cn"; 7 + import { getBaseUrl } from "@/utils/urls"; 8 import type { Metadata, Viewport } from "next"; 9 import { Lexend, Noto_Sans_JP, Outfit } from "next/font/google"; 10 import { cookies } from "next/headers"; ··· 12 import Link from "next/link"; 13 import Script from "next/script"; 14 import { CookiesProvider } from "next-client-cookies/server"; 15 16 import { Provider } from "./provider"; 17
+1 -2
app/leaderboard/[guildId]/icon.component.tsx
··· 1 - import type { SVGProps } from "react"; 2 - 3 import InvitesIcon from "@/components/icons/invites"; 4 import MessagesIcon from "@/components/icons/messages"; 5 import VoiceIcon from "@/components/icons/voice"; 6 import { cn } from "@/utils/cn"; 7 8 type Props = SVGProps<SVGSVGElement> & { 9 type: "messages" | "voiceminutes" | "invites";
··· 1 import InvitesIcon from "@/components/icons/invites"; 2 import MessagesIcon from "@/components/icons/messages"; 3 import VoiceIcon from "@/components/icons/voice"; 4 import { cn } from "@/utils/cn"; 5 + import type { SVGProps } from "react"; 6 7 type Props = SVGProps<SVGSVGElement> & { 8 type: "messages" | "voiceminutes" | "invites";
+7 -8
app/leaderboard/[guildId]/layout.tsx
··· 1 - import type { Metadata } from "next"; 2 - import Image from "next/image"; 3 - import { HiAnnotation, HiLink, HiUsers, HiVolumeUp } from "react-icons/hi"; 4 - 5 import { ClientImageWall } from "@/components/client"; 6 import ImageReduceMotion from "@/components/image-reduce-motion"; 7 import { ListTab } from "@/components/list"; ··· 9 import paintPic from "@/public/paint.webp"; 10 import { intl } from "@/utils/numbers"; 11 import { getCanonicalUrl } from "@/utils/urls"; 12 13 import { getDesign, getPagination } from "./api"; 14 import Side from "./side.component"; ··· 18 children: React.ReactNode; 19 } 20 21 - export const revalidate = 3600; 22 23 export const generateMetadata = async ({ params }: Props): Promise<Metadata> => { 24 const { guildId } = await params; ··· 46 type: "profile", 47 images: { 48 url: getCanonicalUrl("leaderboard", guildId, `open-graph.png?ca=${cacheQuery}`), 49 - width: 1200, 50 height: 630, 51 type: "image/png" 52 } ··· 85 classNames={{ img: "!h-36 md:!h-64", blurredImg: "!h-40 md:!h-72 -top-5" }} 86 isBlurred 87 src={design && "bannerUrl" in design && design.bannerUrl ? design.bannerUrl : paintPic.src} 88 - width={3840 / 2} 89 - height={2160 / 2} 90 /> 91 92 <div
··· 1 import { ClientImageWall } from "@/components/client"; 2 import ImageReduceMotion from "@/components/image-reduce-motion"; 3 import { ListTab } from "@/components/list"; ··· 5 import paintPic from "@/public/paint.webp"; 6 import { intl } from "@/utils/numbers"; 7 import { getCanonicalUrl } from "@/utils/urls"; 8 + import type { Metadata } from "next"; 9 + import Image from "next/image"; 10 + import { HiAnnotation, HiLink, HiUsers, HiVolumeUp } from "react-icons/hi"; 11 12 import { getDesign, getPagination } from "./api"; 13 import Side from "./side.component"; ··· 17 children: React.ReactNode; 18 } 19 20 + export const revalidate = 3_600; 21 22 export const generateMetadata = async ({ params }: Props): Promise<Metadata> => { 23 const { guildId } = await params; ··· 45 type: "profile", 46 images: { 47 url: getCanonicalUrl("leaderboard", guildId, `open-graph.png?ca=${cacheQuery}`), 48 + width: 1_200, 49 height: 630, 50 type: "image/png" 51 } ··· 84 classNames={{ img: "!h-36 md:!h-64", blurredImg: "!h-40 md:!h-72 -top-5" }} 85 isBlurred 86 src={design && "bannerUrl" in design && design.bannerUrl ? design.bannerUrl : paintPic.src} 87 + width={3_840 / 2} 88 + height={2_160 / 2} 89 /> 90 91 <div
+1 -1
app/leaderboard/[guildId]/loading.tsx
··· 1 import { Skeleton } from "@/components/ui/skeleton"; 2 3 export default function Loading() { 4 - return new Array(20).fill(null).map((_, i) => ( 5 <div 6 key={"leaderboard-loading-" + i} 7 className="mb-4 rounded-md p-3 flex items-center dark:bg-wamellow bg-wamellow-100 w-full"
··· 1 import { Skeleton } from "@/components/ui/skeleton"; 2 3 export default function Loading() { 4 + return Array.from({ length: 20 }).fill(null).map((_, i) => ( 5 <div 6 key={"leaderboard-loading-" + i} 7 className="mb-4 rounded-md p-3 flex items-center dark:bg-wamellow bg-wamellow-100 w-full"
+9 -10
app/leaderboard/[guildId]/member.component.tsx
··· 1 - import { cookies } from "next/headers"; 2 - import Image from "next/image"; 3 - import Link from "next/link"; 4 - import { HiBadgeCheck } from "react-icons/hi"; 5 - 6 import { ClientBadge, ClientCircularProgress } from "@/components/client"; 7 import DiscordAppBadge from "@/components/discord/app-badge"; 8 import ImageReduceMotion from "@/components/image-reduce-motion"; ··· 11 import getAverageColor from "@/utils/average-color"; 12 import { cn } from "@/utils/cn"; 13 import { intl } from "@/utils/numbers"; 14 15 import Icon from "./icon.component"; 16 ··· 42 43 jar.set( 44 "lbc", 45 - currentCircular !== "server" 46 - ? "server" 47 - : "next" 48 ); 49 } 50 ··· 108 {member.emoji && 109 <div className="w-full hidden sm:block relative mr-6 -ml-48 md:-ml-6 lg:ml-6"> 110 <div className="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-3 lg:grid-cols-6 w-full gap-2 absolute -bottom-9 rotate-1"> 111 - {new Array(12).fill(0).map((_, i) => 112 <Emoji 113 key={"emoji-" + member.id + i} 114 index={i} ··· 148 value={ 149 currentCircular === "next" 150 ? (member.activity[type] * 100) / (members[index - 1]?.activity[type] || 1) 151 - : (member.activity[type] * 100) / parseInt(pagination[type].total.toString()) 152 || 100 153 } 154 showValueLabel={true}
··· 1 import { ClientBadge, ClientCircularProgress } from "@/components/client"; 2 import DiscordAppBadge from "@/components/discord/app-badge"; 3 import ImageReduceMotion from "@/components/image-reduce-motion"; ··· 6 import getAverageColor from "@/utils/average-color"; 7 import { cn } from "@/utils/cn"; 8 import { intl } from "@/utils/numbers"; 9 + import { cookies } from "next/headers"; 10 + import Image from "next/image"; 11 + import Link from "next/link"; 12 + import { HiBadgeCheck } from "react-icons/hi"; 13 14 import Icon from "./icon.component"; 15 ··· 41 42 jar.set( 43 "lbc", 44 + currentCircular === "server" 45 + ? "next" 46 + : "server" 47 ); 48 } 49 ··· 107 {member.emoji && 108 <div className="w-full hidden sm:block relative mr-6 -ml-48 md:-ml-6 lg:ml-6"> 109 <div className="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-3 lg:grid-cols-6 w-full gap-2 absolute -bottom-9 rotate-1"> 110 + {Array.from({ length: 12 }).fill(0).map((_, i) => 111 <Emoji 112 key={"emoji-" + member.id + i} 113 index={i} ··· 147 value={ 148 currentCircular === "next" 149 ? (member.activity[type] * 100) / (members[index - 1]?.activity[type] || 1) 150 + : (member.activity[type] * 100) / Number.parseInt(pagination[type].total.toString(), 10) 151 || 100 152 } 153 showValueLabel={true}
+5 -6
app/leaderboard/[guildId]/open-graph.png/route.tsx
··· 1 /* eslint-disable react/no-unknown-property */ 2 /* eslint-disable @next/next/no-img-element */ 3 4 - import { readFile } from "fs/promises"; 5 - import { ImageResponse } from "next/og"; 6 - import type { NextRequest } from "next/server"; 7 - 8 import { getGuild } from "@/lib/api"; 9 import { intl } from "@/utils/numbers"; 10 import { truncate } from "@/utils/truncate"; 11 import { getCanonicalUrl } from "@/utils/urls"; 12 13 import { getTopMembers } from "../api"; 14 import Icon from "../icon.component"; ··· 17 params: Promise<{ guildId: string; }>; 18 } 19 20 - export const revalidate = 3600; // 1 hour 21 22 export async function GET(request: NextRequest, { params }: Props) { 23 const { guildId } = await params; ··· 88 </div> 89 ), 90 { 91 - width: 1200, 92 height: 630, 93 fonts: [ 94 {
··· 1 /* eslint-disable react/no-unknown-property */ 2 /* eslint-disable @next/next/no-img-element */ 3 4 import { getGuild } from "@/lib/api"; 5 import { intl } from "@/utils/numbers"; 6 import { truncate } from "@/utils/truncate"; 7 import { getCanonicalUrl } from "@/utils/urls"; 8 + import { readFile } from "fs/promises"; 9 + import { ImageResponse } from "next/og"; 10 + import type { NextRequest } from "next/server"; 11 12 import { getTopMembers } from "../api"; 13 import Icon from "../icon.component"; ··· 16 params: Promise<{ guildId: string; }>; 17 } 18 19 + export const revalidate = 3_600; // 1 hour 20 21 export async function GET(request: NextRequest, { params }: Props) { 22 const { guildId } = await params; ··· 87 </div> 88 ), 89 { 90 + width: 1_200, 91 height: 630, 92 fonts: [ 93 {
+4 -5
app/leaderboard/[guildId]/page.tsx
··· 1 import { cookies } from "next/headers"; 2 import { redirect } from "next/navigation"; 3 4 - import { ScreenMessage } from "@/components/screen-message"; 5 - import { getGuild } from "@/lib/api"; 6 - 7 import { getPagination, getTopMembers } from "./api"; 8 import Member from "./member.component"; 9 import Pagination from "./pagination.component"; 10 11 - export const revalidate = 3600; 12 13 interface Props { 14 params: Promise<{ guildId: string; }>; ··· 25 const jar = await cookies(); 26 27 const type = search.type || "messages"; 28 - const page = parseInt(search.page || "1"); 29 30 if (page !== 1 && !jar.get("session")) { 31 redirect(`/login?callback=/leaderboard/${guildId}%3Ftype%3Dmessages%3Fpage=${page}`);
··· 1 + import { ScreenMessage } from "@/components/screen-message"; 2 + import { getGuild } from "@/lib/api"; 3 import { cookies } from "next/headers"; 4 import { redirect } from "next/navigation"; 5 6 import { getPagination, getTopMembers } from "./api"; 7 import Member from "./member.component"; 8 import Pagination from "./pagination.component"; 9 10 + export const revalidate = 3_600; 11 12 interface Props { 13 params: Promise<{ guildId: string; }>; ··· 24 const jar = await cookies(); 25 26 const type = search.type || "messages"; 27 + const page = Number.parseInt(search.page || "1", 10); 28 29 if (page !== 1 && !jar.get("session")) { 30 redirect(`/login?callback=/leaderboard/${guildId}%3Ftype%3Dmessages%3Fpage=${page}`);
+2 -3
app/leaderboard/[guildId]/pagination.component.tsx
··· 1 "use client"; 2 3 import { Pagination as UiPagination } from "@nextui-org/react"; 4 import { useRouter } from "next/navigation"; 5 import { useCookies } from "next-client-cookies"; 6 - 7 - import { LoginButton } from "@/components/login-button"; 8 9 interface Props { 10 searchParams: { ··· 30 showControls 31 total={pages} 32 size="lg" 33 - page={parseInt(searchParams.page || "0")} 34 onChange={(now) => { 35 const params = new URLSearchParams(searchParams); 36 params.delete("page");
··· 1 "use client"; 2 3 + import { LoginButton } from "@/components/login-button"; 4 import { Pagination as UiPagination } from "@nextui-org/react"; 5 import { useRouter } from "next/navigation"; 6 import { useCookies } from "next-client-cookies"; 7 8 interface Props { 9 searchParams: { ··· 29 showControls 30 total={pages} 31 size="lg" 32 + page={Number.parseInt(searchParams.page || "0", 10)} 33 onChange={(now) => { 34 const params = new URLSearchParams(searchParams); 35 params.delete("page");
+11 -12
app/leaderboard/[guildId]/side.component.tsx
··· 1 "use client"; 2 3 - import { Accordion, AccordionItem, Code } from "@nextui-org/react"; 4 - import Link from "next/link"; 5 - import { useRouter } from "next/navigation"; 6 - import { useCookies } from "next-client-cookies"; 7 - import { useState } from "react"; 8 - import { BsDiscord } from "react-icons/bs"; 9 - import { HiAnnotation, HiLink, HiTrash, HiViewGridAdd, HiVolumeUp } from "react-icons/hi"; 10 - 11 import Ad from "@/components/ad"; 12 import Modal from "@/components/modal"; 13 import Notice, { NoticeType } from "@/components/notice"; ··· 16 import type { ApiError, ApiV1GuildsGetResponse, ApiV1GuildsTopmembersPaginationGetResponse } from "@/typings"; 17 import { intl } from "@/utils/numbers"; 18 import { getCanonicalUrl } from "@/utils/urls"; 19 20 export default function Side({ 21 guild, ··· 83 className="w-full justify-start mt-2" 84 > 85 <Link 86 - href={getCanonicalUrl("dashboard", guild.id as string)} 87 > 88 <HiViewGridAdd /> 89 Dashboard ··· 133 <br /> 134 <br /> 135 The percentage { 136 - cookies.get("lbc") !== "server" 137 - ? "indicates the gap in messages needed to surpass the next user" 138 - : "reflects the contribution of server activity from that user" 139 }. 140 </AccordionItem> 141
··· 1 "use client"; 2 3 import Ad from "@/components/ad"; 4 import Modal from "@/components/modal"; 5 import Notice, { NoticeType } from "@/components/notice"; ··· 8 import type { ApiError, ApiV1GuildsGetResponse, ApiV1GuildsTopmembersPaginationGetResponse } from "@/typings"; 9 import { intl } from "@/utils/numbers"; 10 import { getCanonicalUrl } from "@/utils/urls"; 11 + import { Accordion, AccordionItem, Code } from "@nextui-org/react"; 12 + import Link from "next/link"; 13 + import { useRouter } from "next/navigation"; 14 + import { useCookies } from "next-client-cookies"; 15 + import { useState } from "react"; 16 + import { BsDiscord } from "react-icons/bs"; 17 + import { HiAnnotation, HiLink, HiTrash, HiViewGridAdd, HiVolumeUp } from "react-icons/hi"; 18 19 export default function Side({ 20 guild, ··· 82 className="w-full justify-start mt-2" 83 > 84 <Link 85 + href={getCanonicalUrl("dashboard", guild.id)} 86 > 87 <HiViewGridAdd /> 88 Dashboard ··· 132 <br /> 133 <br /> 134 The percentage { 135 + cookies.get("lbc") === "server" 136 + ? "reflects the contribution of server activity from that user" 137 + : "indicates the gap in messages needed to surpass the next user" 138 }. 139 </AccordionItem> 140
+4 -5
app/login/[social]/route.ts
··· 1 import { cookies } from "next/headers"; 2 import { redirect } from "next/navigation"; 3 4 - import { defaultCookieOptions } from "@/lib/cookies"; 5 - 6 import { connect, disconnect, getAuthorizeUrl } from "./api"; 7 8 - const SOCIALS = ["spotify", "bluesky"]; 9 10 export async function GET( 11 request: Request, ··· 13 ) { 14 const { social } = await params; 15 16 - if (!SOCIALS.includes(social)) { 17 return Response.json({ 18 status: 400, 19 message: "Invalid social" ··· 61 res.verifier, 62 { 63 ...defaultCookieOptions, 64 - expires: new Date(Date.now() + 1000 * 600) 65 } 66 ); 67 }
··· 1 + import { defaultCookieOptions } from "@/lib/cookies"; 2 import { cookies } from "next/headers"; 3 import { redirect } from "next/navigation"; 4 5 import { connect, disconnect, getAuthorizeUrl } from "./api"; 6 7 + const SOCIALS = new Set(["spotify", "bluesky"]); 8 9 export async function GET( 10 request: Request, ··· 12 ) { 13 const { social } = await params; 14 15 + if (!SOCIALS.has(social)) { 16 return Response.json({ 17 status: 400, 18 message: "Invalid social" ··· 60 res.verifier, 61 { 62 ...defaultCookieOptions, 63 + expires: new Date(Date.now() + 1_000 * 600) 64 } 65 ); 66 }
+2 -3
app/login/open-graph/page.tsx
··· 1 import type { Metadata } from "next"; 2 import { headers } from "next/headers"; 3 import { redirect } from "next/navigation"; 4 - 5 - import { getCanonicalUrl } from "@/utils/urls"; 6 7 export const generateMetadata = (): Metadata => { 8 const title = "Login with Discord"; ··· 22 type: "website", 23 images: { 24 url, 25 - width: 1200, 26 height: 630, 27 type: "image/png" 28 }
··· 1 + import { getCanonicalUrl } from "@/utils/urls"; 2 import type { Metadata } from "next"; 3 import { headers } from "next/headers"; 4 import { redirect } from "next/navigation"; 5 6 export const generateMetadata = (): Metadata => { 7 const title = "Login with Discord"; ··· 21 type: "website", 22 images: { 23 url, 24 + width: 1_200, 25 height: 630, 26 type: "image/png" 27 }
+2 -3
app/login/route.ts
··· 1 import { PermissionFlagsBits } from "discord-api-types/v10"; 2 import { cookies } from "next/headers"; 3 import { redirect } from "next/navigation"; 4 - 5 - import { defaultCookieOptions } from "@/lib/cookies"; 6 - import { getCanonicalUrl } from "@/utils/urls"; 7 8 import { createSession } from "./api"; 9
··· 1 + import { defaultCookieOptions } from "@/lib/cookies"; 2 + import { getCanonicalUrl } from "@/utils/urls"; 3 import { PermissionFlagsBits } from "discord-api-types/v10"; 4 import { cookies } from "next/headers"; 5 import { redirect } from "next/navigation"; 6 7 import { createSession } from "./api"; 8
+10 -11
app/passport/[guildId]/page.tsx
··· 1 - import type { Metadata } from "next"; 2 - import { cookies } from "next/headers"; 3 - import Image from "next/image"; 4 - import Link from "next/link"; 5 - import { BsDiscord } from "react-icons/bs"; 6 - import { HiChartBar, HiCheck, HiLightningBolt, HiLockClosed, HiStar, HiUsers, HiX } from "react-icons/hi"; 7 - 8 import { ClientButton } from "@/components/client"; 9 import ImageReduceMotion from "@/components/image-reduce-motion"; 10 import { ListFeature } from "@/components/list"; ··· 14 import paintPic from "@/public/paint.webp"; 15 import { intl } from "@/utils/numbers"; 16 import { getCanonicalUrl } from "@/utils/urls"; 17 18 import { getPassport } from "./api"; 19 import { Verify } from "./verify.component"; ··· 165 <div className="mb-4 text-neutral-100 font-semibold text-xl">Modern, Simple, Wamellow 👋</div> 166 <ListFeature 167 items={[ 168 - { icon: <HiLockClosed />, title: "Secure", description: "Wamellow does not store your IP, Geolocation or similar, nothing is kept, no logs.", color: 0xa84b56 }, 169 - { icon: <BsDiscord />, title: "Integration", description: "Unparalleled Discord integration, setting us apart from the rest.", color: 0x4752c4 }, 170 - { icon: <HiStar />, title: "Easy", description: "The most user-friendly and visually appealing verification process.", color: 0x7f43d8 }, 171 - { icon: <HiLightningBolt />, title: "Fast", description: "Welcome new members easily with the fastest verification method available.", color: 0xff9156 } 172 ]} 173 /> 174 </div>
··· 1 import { ClientButton } from "@/components/client"; 2 import ImageReduceMotion from "@/components/image-reduce-motion"; 3 import { ListFeature } from "@/components/list"; ··· 7 import paintPic from "@/public/paint.webp"; 8 import { intl } from "@/utils/numbers"; 9 import { getCanonicalUrl } from "@/utils/urls"; 10 + import type { Metadata } from "next"; 11 + import { cookies } from "next/headers"; 12 + import Image from "next/image"; 13 + import Link from "next/link"; 14 + import { BsDiscord } from "react-icons/bs"; 15 + import { HiChartBar, HiCheck, HiLightningBolt, HiLockClosed, HiStar, HiUsers, HiX } from "react-icons/hi"; 16 17 import { getPassport } from "./api"; 18 import { Verify } from "./verify.component"; ··· 164 <div className="mb-4 text-neutral-100 font-semibold text-xl">Modern, Simple, Wamellow 👋</div> 165 <ListFeature 166 items={[ 167 + { icon: <HiLockClosed />, title: "Secure", description: "Wamellow does not store your IP, Geolocation or similar, nothing is kept, no logs.", color: 0xA8_4B_56 }, 168 + { icon: <BsDiscord />, title: "Integration", description: "Unparalleled Discord integration, setting us apart from the rest.", color: 0x47_52_C4 }, 169 + { icon: <HiStar />, title: "Easy", description: "The most user-friendly and visually appealing verification process.", color: 0x7F_43_D8 }, 170 + { icon: <HiLightningBolt />, title: "Fast", description: "Welcome new members easily with the fastest verification method available.", color: 0xFF_91_56 } 171 ]} 172 /> 173 </div>
+5 -6
app/passport/[guildId]/verify.component.tsx
··· 1 "use client"; 2 3 - import Link from "next/link"; 4 - import { BsDiscord } from "react-icons/bs"; 5 - import { HiExclamation, HiFingerPrint, HiLockClosed } from "react-icons/hi"; 6 - import { TailSpin } from "react-loading-icons"; 7 - 8 import { userStore } from "@/common/user"; 9 import ImageReduceMotion from "@/components/image-reduce-motion"; 10 import { Badge } from "@/components/ui/badge"; ··· 12 import type { ApiV1GuildsGetResponse } from "@/typings"; 13 import { State, useCaptcha } from "@/utils/captcha"; 14 import { cn } from "@/utils/cn"; 15 16 interface Props { 17 guild: ApiV1GuildsGetResponse; ··· 51 ref={button} 52 variant={state === State.Success ? "success" : "secondary"} 53 className={cn(error && "cursor-not-allowed", state === State.Success && "cursor-not-allowed", "font-medium w-full")} 54 - disabled={!!error || state === State.Success} 55 > 56 {state === State.Loading 57 ? <TailSpin stroke="#d4d4d4" strokeWidth={8} className="relative h-3 w-3 overflow-visible" />
··· 1 "use client"; 2 3 import { userStore } from "@/common/user"; 4 import ImageReduceMotion from "@/components/image-reduce-motion"; 5 import { Badge } from "@/components/ui/badge"; ··· 7 import type { ApiV1GuildsGetResponse } from "@/typings"; 8 import { State, useCaptcha } from "@/utils/captcha"; 9 import { cn } from "@/utils/cn"; 10 + import Link from "next/link"; 11 + import { BsDiscord } from "react-icons/bs"; 12 + import { HiExclamation, HiFingerPrint, HiLockClosed } from "react-icons/hi"; 13 + import { TailSpin } from "react-loading-icons"; 14 15 interface Props { 16 guild: ApiV1GuildsGetResponse; ··· 50 ref={button} 51 variant={state === State.Success ? "success" : "secondary"} 52 className={cn(error && "cursor-not-allowed", state === State.Success && "cursor-not-allowed", "font-medium w-full")} 53 + disabled={Boolean(error) || state === State.Success} 54 > 55 {state === State.Loading 56 ? <TailSpin stroke="#d4d4d4" strokeWidth={8} className="relative h-3 w-3 overflow-visible" />
+11 -13
app/profile/billing/page.tsx
··· 1 "use client"; 2 3 - import { Turnstile, type TurnstileInstance } from "@marsidev/react-turnstile"; 4 - import Link from "next/link"; 5 - import { useRef, useState } from "react"; 6 - import { GrAmex } from "react-icons/gr"; 7 - import { HiCreditCard, HiLightningBolt } from "react-icons/hi"; 8 - import { SiDinersclub, SiDiscover, SiJcb, SiMastercard, SiStripe, SiVisa } from "react-icons/si"; 9 - 10 import { DonationSelect } from "@/app/(home)/premium/subscribe.component"; 11 import { userStore } from "@/common/user"; 12 import Box from "@/components/box"; ··· 22 import { Skeleton } from "@/components/ui/skeleton"; 23 import { type ApiEdit, useApi } from "@/lib/api/hook"; 24 import type { ApiV1UsersMeBillingGetResponse, ApiV1UsersMeGuildsGetResponse } from "@/typings"; 25 - 26 27 function isActive(status: ApiV1UsersMeBillingGetResponse["status"]): status is "active" | "trialing" | "past_due" { 28 return status === "active" || status === "trialing" || status === "past_due"; ··· 58 </>); 59 } 60 61 - const periodEndsInDays = Math.floor((((data?.currentPeriodEnd || 0) - Date.now() / 1000) / (60 * 60 * 24))); 62 const periodEndsInStr = `${periodEndsInDays > 1 ? "in " : ""}${periodEndsInDays === 0 ? "Today" : periodEndsInDays === 1 ? "Tomorrow" : periodEndsInDays} ${periodEndsInDays > 1 ? "days" : ""}`; 63 64 return ( ··· 102 ? <Skeleton className="h-12 w-full" /> 103 : (data?.cancelAtPeriodEnd 104 ? <p> 105 - Your subscription will expire on <span className="font-semibold text-neutral-300">{new Date(data!.currentPeriodEnd * 1000).toLocaleDateString()}</span> and you will not be charged again. 106 </p> 107 : <p> 108 - Your subscription will renew on <span className="font-semibold text-neutral-300">{new Date(data!.currentPeriodEnd * 1000).toLocaleDateString()}</span>, for a total of <span className="font-semibold text-neutral-300">EUR {(4 + (data!.donationQuantity || 0)).toFixed(2)}</span>. 109 110 You{"'"}re paying <span className="font-semibold text-neutral-300">EUR {(4).toFixed(2)} Premium</span> and <span className="font-semibold text-neutral-300">EUR {(data!.donationQuantity || 0).toFixed(2)} Donation{data!.donationQuantity ? "s" : ""}</span> 111 {" "} ··· 233 name="Premium Guilds" 234 url="/users/@me/billing/premium-guilds" 235 dataName="guildIds" 236 - items={data 237 - ?.filter((guild) => guild.bot) 238 .map((guild) => ({ 239 icon: ( 240 <ImageReduceMotion
··· 1 "use client"; 2 3 import { DonationSelect } from "@/app/(home)/premium/subscribe.component"; 4 import { userStore } from "@/common/user"; 5 import Box from "@/components/box"; ··· 15 import { Skeleton } from "@/components/ui/skeleton"; 16 import { type ApiEdit, useApi } from "@/lib/api/hook"; 17 import type { ApiV1UsersMeBillingGetResponse, ApiV1UsersMeGuildsGetResponse } from "@/typings"; 18 + import { Turnstile, type TurnstileInstance } from "@marsidev/react-turnstile"; 19 + import Link from "next/link"; 20 + import { useRef, useState } from "react"; 21 + import { GrAmex } from "react-icons/gr"; 22 + import { HiCreditCard, HiLightningBolt } from "react-icons/hi"; 23 + import { SiDinersclub, SiDiscover, SiJcb, SiMastercard, SiStripe, SiVisa } from "react-icons/si"; 24 25 function isActive(status: ApiV1UsersMeBillingGetResponse["status"]): status is "active" | "trialing" | "past_due" { 26 return status === "active" || status === "trialing" || status === "past_due"; ··· 56 </>); 57 } 58 59 + const periodEndsInDays = Math.floor((((data?.currentPeriodEnd || 0) - Date.now() / 1_000) / (60 * 60 * 24))); 60 const periodEndsInStr = `${periodEndsInDays > 1 ? "in " : ""}${periodEndsInDays === 0 ? "Today" : periodEndsInDays === 1 ? "Tomorrow" : periodEndsInDays} ${periodEndsInDays > 1 ? "days" : ""}`; 61 62 return ( ··· 100 ? <Skeleton className="h-12 w-full" /> 101 : (data?.cancelAtPeriodEnd 102 ? <p> 103 + Your subscription will expire on <span className="font-semibold text-neutral-300">{new Date(data.currentPeriodEnd * 1_000).toLocaleDateString()}</span> and you will not be charged again. 104 </p> 105 : <p> 106 + Your subscription will renew on <span className="font-semibold text-neutral-300">{new Date(data!.currentPeriodEnd * 1_000).toLocaleDateString()}</span>, for a total of <span className="font-semibold text-neutral-300">EUR {(4 + (data!.donationQuantity || 0)).toFixed(2)}</span>. 107 108 You{"'"}re paying <span className="font-semibold text-neutral-300">EUR {(4).toFixed(2)} Premium</span> and <span className="font-semibold text-neutral-300">EUR {(data!.donationQuantity || 0).toFixed(2)} Donation{data!.donationQuantity ? "s" : ""}</span> 109 {" "} ··· 231 name="Premium Guilds" 232 url="/users/@me/billing/premium-guilds" 233 dataName="guildIds" 234 + items={(data || []) 235 + .filter((guild) => guild.bot) 236 .map((guild) => ({ 237 icon: ( 238 <ImageReduceMotion
+6 -7
app/profile/connections/page.tsx
··· 1 "use client"; 2 3 - import Image from "next/image"; 4 - import { useRouter } from "next/navigation"; 5 - import { useState } from "react"; 6 - import { BsSpotify } from "react-icons/bs"; 7 - import { HiFingerPrint, HiTrash } from "react-icons/hi"; 8 - import { SiBluesky } from "react-icons/si"; 9 - 10 import DumbTextInput from "@/components/inputs/dumb-text-input"; 11 import Modal from "@/components/modal"; 12 import Notice, { NoticeType } from "@/components/notice"; ··· 15 import { useApi } from "@/lib/api/hook"; 16 import { type ApiV1UsersMeConnectionsGetResponse, ConnectionType } from "@/typings"; 17 import { cn } from "@/utils/cn"; 18 19 const CONNECTION_TYPES = Object 20 .entries(ConnectionType)
··· 1 "use client"; 2 3 import DumbTextInput from "@/components/inputs/dumb-text-input"; 4 import Modal from "@/components/modal"; 5 import Notice, { NoticeType } from "@/components/notice"; ··· 8 import { useApi } from "@/lib/api/hook"; 9 import { type ApiV1UsersMeConnectionsGetResponse, ConnectionType } from "@/typings"; 10 import { cn } from "@/utils/cn"; 11 + import Image from "next/image"; 12 + import { useRouter } from "next/navigation"; 13 + import { useState } from "react"; 14 + import { BsSpotify } from "react-icons/bs"; 15 + import { HiFingerPrint, HiTrash } from "react-icons/hi"; 16 + import { SiBluesky } from "react-icons/si"; 17 18 const CONNECTION_TYPES = Object 19 .entries(ConnectionType)
+14 -15
app/profile/layout.tsx
··· 1 "use client"; 2 3 - import Link from "next/link"; 4 - import { redirect } from "next/navigation"; 5 - import { useCookies } from "next-client-cookies"; 6 - import { Suspense } from "react"; 7 - import CountUp from "react-countup"; 8 - import { HiCreditCard, HiCubeTransparent, HiFire, HiHome, HiPhotograph, HiTranslate } from "react-icons/hi"; 9 - import { useQuery } from "react-query"; 10 - 11 import { userStore } from "@/common/user"; 12 import ImageReduceMotion from "@/components/image-reduce-motion"; 13 import { ListTab } from "@/components/list"; ··· 17 import { Skeleton } from "@/components/ui/skeleton"; 18 import { cacheOptions, getData } from "@/lib/api"; 19 import type { ApiV1UsersMeGetResponse } from "@/typings"; 20 21 export default function RootLayout({ 22 children ··· 36 url, 37 () => getData<ApiV1UsersMeGetResponse>(url), 38 { 39 - enabled: !!user?.id, 40 onSuccess: (d) => userStore.setState({ 41 ...user, 42 extended: "status" in d ? {} : d ··· 76 /> 77 </Skeleton> 78 79 - {!user?.id ? 80 - <div className="flex flex-col mt-2"> 81 - <Skeleton className="rounded-xl w-32 h-5 mb-2" /> 82 - <Skeleton className="rounded-md w-[90px] h-7" /> 83 - </div> 84 - : 85 <div className="flex flex-col gap-1"> 86 <div className="text-2xl dark:text-neutral-200 text-neutral-800 font-medium"> 87 {user.globalName || user.username} ··· 98 {user.extended?.voteCount} VOTE{user.extended?.voteCount === 1 ? "" : "S"} 99 </Badge> 100 </Link> 101 </div> 102 } 103 </div>
··· 1 "use client"; 2 3 import { userStore } from "@/common/user"; 4 import ImageReduceMotion from "@/components/image-reduce-motion"; 5 import { ListTab } from "@/components/list"; ··· 9 import { Skeleton } from "@/components/ui/skeleton"; 10 import { cacheOptions, getData } from "@/lib/api"; 11 import type { ApiV1UsersMeGetResponse } from "@/typings"; 12 + import Link from "next/link"; 13 + import { redirect } from "next/navigation"; 14 + import { useCookies } from "next-client-cookies"; 15 + import { Suspense } from "react"; 16 + import CountUp from "react-countup"; 17 + import { HiCreditCard, HiCubeTransparent, HiFire, HiHome, HiPhotograph, HiTranslate } from "react-icons/hi"; 18 + import { useQuery } from "react-query"; 19 20 export default function RootLayout({ 21 children ··· 35 url, 36 () => getData<ApiV1UsersMeGetResponse>(url), 37 { 38 + enabled: Boolean(user?.id), 39 onSuccess: (d) => userStore.setState({ 40 ...user, 41 extended: "status" in d ? {} : d ··· 75 /> 76 </Skeleton> 77 78 + {user?.id ? 79 <div className="flex flex-col gap-1"> 80 <div className="text-2xl dark:text-neutral-200 text-neutral-800 font-medium"> 81 {user.globalName || user.username} ··· 92 {user.extended?.voteCount} VOTE{user.extended?.voteCount === 1 ? "" : "S"} 93 </Badge> 94 </Link> 95 + </div> 96 + : 97 + <div className="flex flex-col mt-2"> 98 + <Skeleton className="rounded-xl w-32 h-5 mb-2" /> 99 + <Skeleton className="rounded-md w-[90px] h-7" /> 100 </div> 101 } 102 </div>
+7 -8
app/profile/page.tsx
··· 1 "use client"; 2 3 - import { motion } from "framer-motion"; 4 - import Link from "next/link"; 5 - import { useSearchParams } from "next/navigation"; 6 - import { useCookies } from "next-client-cookies"; 7 - import { useMemo, useState } from "react"; 8 - import { HiChartBar, HiRefresh, HiUserAdd, HiViewGridAdd } from "react-icons/hi"; 9 - 10 import ImageReduceMotion from "@/components/image-reduce-motion"; 11 import DumbTextInput from "@/components/inputs/dumb-text-input"; 12 import { ScreenMessage } from "@/components/screen-message"; ··· 14 import { useApi } from "@/lib/api/hook"; 15 import type { ApiV1UsersMeGuildsGetResponse } from "@/typings"; 16 import { cn } from "@/utils/cn"; 17 18 const MAX_GUILDS = 50 as const; 19 ··· 126 {isHuge && ( 127 <ScreenMessage 128 title="There are too many servers.." 129 - description={`To save some performance, use the search to find a guild. Showing ${MAX_GUILDS} out of ~${guilds.length < 1000 ? length : Math.round(length / 1000) * 1000}.`} 130 /> 131 )} 132 </div>);
··· 1 "use client"; 2 3 import ImageReduceMotion from "@/components/image-reduce-motion"; 4 import DumbTextInput from "@/components/inputs/dumb-text-input"; 5 import { ScreenMessage } from "@/components/screen-message"; ··· 7 import { useApi } from "@/lib/api/hook"; 8 import type { ApiV1UsersMeGuildsGetResponse } from "@/typings"; 9 import { cn } from "@/utils/cn"; 10 + import { motion } from "framer-motion"; 11 + import Link from "next/link"; 12 + import { useSearchParams } from "next/navigation"; 13 + import { useCookies } from "next-client-cookies"; 14 + import { useMemo, useState } from "react"; 15 + import { HiChartBar, HiRefresh, HiUserAdd, HiViewGridAdd } from "react-icons/hi"; 16 17 const MAX_GUILDS = 50 as const; 18 ··· 125 {isHuge && ( 126 <ScreenMessage 127 title="There are too many servers.." 128 + description={`To save some performance, use the search to find a guild. Showing ${MAX_GUILDS} out of ~${guilds.length < 1_000 ? length : Math.round(length / 1_000) * 1_000}.`} 129 /> 130 )} 131 </div>);
+6 -7
app/profile/rank/card-style.component.tsx
··· 1 - import type { ApiError } from "next/dist/server/api-utils"; 2 - import Image from "next/image"; 3 - import { type ChangeEvent, useRef, useState } from "react"; 4 - import { HiUpload } from "react-icons/hi"; 5 - 6 import { type User, userStore } from "@/common/user"; 7 import Box from "@/components/box"; 8 import { Shiggy } from "@/components/shiggy"; ··· 11 import { cn } from "@/utils/cn"; 12 import { deepMerge } from "@/utils/deepMerge"; 13 import sleep from "@/utils/sleep"; 14 15 enum State { 16 Idle = 0, ··· 60 return; 61 } 62 63 - await sleep(1000 * 3); 64 setState(State.Success); 65 66 userStore.setState({ ··· 145 </div> 146 147 <div className="absolute blur-sm gap-4 grid grid-cols-6 left-4 lg:grid-cols-6 md:blur-none md:bottom-4 md:left-0 md:opacity-100 md:relative md:scale-100 md:top-0 md:w-1/2 opacity-45 rotate-1 scale-105 top-6 w-full"> 148 - {new Array(18).fill(0).map((_, i) => 149 <Emoji 150 key={"emoji-" + i} 151 index={i}
··· 1 import { type User, userStore } from "@/common/user"; 2 import Box from "@/components/box"; 3 import { Shiggy } from "@/components/shiggy"; ··· 6 import { cn } from "@/utils/cn"; 7 import { deepMerge } from "@/utils/deepMerge"; 8 import sleep from "@/utils/sleep"; 9 + import type { ApiError } from "next/dist/server/api-utils"; 10 + import Image from "next/image"; 11 + import { type ChangeEvent, useRef, useState } from "react"; 12 + import { HiUpload } from "react-icons/hi"; 13 14 enum State { 15 Idle = 0, ··· 59 return; 60 } 61 62 + await sleep(1_000 * 3); 63 setState(State.Success); 64 65 userStore.setState({ ··· 144 </div> 145 146 <div className="absolute blur-sm gap-4 grid grid-cols-6 left-4 lg:grid-cols-6 md:blur-none md:bottom-4 md:left-0 md:opacity-100 md:relative md:scale-100 md:top-0 md:w-1/2 opacity-45 rotate-1 scale-105 top-6 w-full"> 147 + {Array.from({ length: 18 }).fill(0).map((_, i) => 148 <Emoji 149 key={"emoji-" + i} 150 index={i}
+12 -13
app/profile/rank/leaderboard-style.component.tsx
··· 1 - import { useState } from "react"; 2 - 3 import { type User, userStore } from "@/common/user"; 4 import type { ApiError, ApiV1UsersMeGetResponse } from "@/typings"; 5 import { cn } from "@/utils/cn"; 6 import { deepMerge } from "@/utils/deepMerge"; 7 8 export default function LeaderboardStyle() { 9 const user = userStore((s) => s); ··· 58 : "dark:border-violet-400/60 dark:hover:border-violet-400 border-violet-600/60 hover:border-violet-600" 59 )} 60 > 61 - {new Array(10).fill("").map((_, i) => 62 <div key={i} className="flex gap-2"> 63 <div 64 className={cn( ··· 89 <div 90 className={cn( 91 "border-2 duration-200 rounded-md p-4 mt-1 flex flex-col gap-2 group", 92 - !user?.extended?.rank?.useLeaderboardList 93 - ? "dark:border-neutral-700 hover:border-neutral-500 border-neutral-300 " 94 - : "dark:border-violet-400/60 dark:hover:border-violet-400 border-violet-600/60 hover:border-violet-600" 95 )} 96 > 97 - {new Array(8).fill("").map((_, i) => 98 <div key={i} className="flex gap-2"> 99 <div 100 className={cn( 101 "duration-200 h-4 w-4 aspect-square rounded-full", 102 - !user?.extended?.rank?.useLeaderboardList 103 - ? "dark:bg-neutral-700/90 dark:group-hover:bg-neutral-400/60 bg-neutral-300/90 group-hover:bg-neutral-600/60" 104 - : "dark:bg-violet-400/50 dark:group-hover:bg-violet-400/70 bg-violet-600/50 group-hover:bg-violet-600/70" 105 )} 106 /> 107 <div 108 className={cn( 109 "duration-200 h-4 rounded-full", 110 - !user?.extended?.rank?.useLeaderboardList 111 - ? "dark:bg-neutral-700/80 dark:group-hover:bg-neutral-400/50 bg-neutral-300/80 group-hover:bg-neutral-600/50" 112 - : "dark:bg-violet-400/40 dark:group-hover:bg-violet-400/60 bg-violet-600/40 group-hover:bg-violet-600/60" 113 )} 114 style={{ width: `${30 + ((i % 1.7) + (i % 3) + (i % 2)) * 10}%` }} 115 />
··· 1 import { type User, userStore } from "@/common/user"; 2 import type { ApiError, ApiV1UsersMeGetResponse } from "@/typings"; 3 import { cn } from "@/utils/cn"; 4 import { deepMerge } from "@/utils/deepMerge"; 5 + import { useState } from "react"; 6 7 export default function LeaderboardStyle() { 8 const user = userStore((s) => s); ··· 57 : "dark:border-violet-400/60 dark:hover:border-violet-400 border-violet-600/60 hover:border-violet-600" 58 )} 59 > 60 + {Array.from({ length: 10 }).fill("").map((_, i) => 61 <div key={i} className="flex gap-2"> 62 <div 63 className={cn( ··· 88 <div 89 className={cn( 90 "border-2 duration-200 rounded-md p-4 mt-1 flex flex-col gap-2 group", 91 + user?.extended?.rank?.useLeaderboardList 92 + ? "dark:border-violet-400/60 dark:hover:border-violet-400 border-violet-600/60 hover:border-violet-600" 93 + : "dark:border-neutral-700 hover:border-neutral-500 border-neutral-300 " 94 )} 95 > 96 + {Array.from({ length: 8 }).fill("").map((_, i) => 97 <div key={i} className="flex gap-2"> 98 <div 99 className={cn( 100 "duration-200 h-4 w-4 aspect-square rounded-full", 101 + user?.extended?.rank?.useLeaderboardList 102 + ? "dark:bg-violet-400/50 dark:group-hover:bg-violet-400/70 bg-violet-600/50 group-hover:bg-violet-600/70" 103 + : "dark:bg-neutral-700/90 dark:group-hover:bg-neutral-400/60 bg-neutral-300/90 group-hover:bg-neutral-600/60" 104 )} 105 /> 106 <div 107 className={cn( 108 "duration-200 h-4 rounded-full", 109 + user?.extended?.rank?.useLeaderboardList 110 + ? "dark:bg-violet-400/40 dark:group-hover:bg-violet-400/60 bg-violet-600/40 group-hover:bg-violet-600/60" 111 + : "dark:bg-neutral-700/80 dark:group-hover:bg-neutral-400/50 bg-neutral-300/80 group-hover:bg-neutral-600/50" 112 )} 113 style={{ width: `${30 + ((i % 1.7) + (i % 3) + (i % 2)) * 10}%` }} 114 />
+3 -4
app/provider.tsx
··· 1 "use client"; 2 3 import { NextUIProvider } from "@nextui-org/react"; 4 import { usePathname } from "next/navigation"; 5 import { useCookies } from "next-client-cookies"; 6 import { useEffect } from "react"; 7 import { QueryClient, QueryClientProvider } from "react-query"; 8 - 9 - import { guildStore } from "@/common/guilds"; 10 - import { TooltipProvider } from "@/components/ui/tooltip"; 11 - import { cn } from "@/utils/cn"; 12 13 const queryClient = new QueryClient(); 14
··· 1 "use client"; 2 3 + import { guildStore } from "@/common/guilds"; 4 + import { TooltipProvider } from "@/components/ui/tooltip"; 5 + import { cn } from "@/utils/cn"; 6 import { NextUIProvider } from "@nextui-org/react"; 7 import { usePathname } from "next/navigation"; 8 import { useCookies } from "next-client-cookies"; 9 import { useEffect } from "react"; 10 import { QueryClient, QueryClientProvider } from "react-query"; 11 12 const queryClient = new QueryClient(); 13
+114 -176
bun.lock
··· 56 "@types/react-dom": "^19.1.9", 57 "eslint": "^9.36.0", 58 "eslint-config-next": "^15.5.4", 59 - "eslint-plugin-path-alias": "^2.1.0", 60 "eslint-plugin-react": "^7.37.5", 61 "eslint-plugin-react-compiler": "19.1.0-rc.2", 62 "eslint-plugin-react-hooks": "^5.2.0", 63 "eslint-plugin-simple-import-sort": "^12.1.1", 64 - "eslint-plugin-unused-imports": "^4.2.0", 65 "typescript-eslint": "^8.44.1", 66 }, 67 }, ··· 101 102 "@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="], 103 104 - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], 105 106 "@babel/helper-validator-option": ["@babel/helper-validator-option@7.25.9", "", {}, "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw=="], 107 ··· 125 126 "@discordjs/util": ["@discordjs/util@1.1.1", "", {}, "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g=="], 127 128 - "@emnapi/core": ["@emnapi/core@1.3.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.1", "tslib": "^2.4.0" } }, "sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog=="], 129 130 "@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], 131 132 - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw=="], 133 134 "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], 135 ··· 247 248 "@marsidev/react-turnstile": ["@marsidev/react-turnstile@1.3.1", "", { "peerDependencies": { "react": "^17.0.2 || ^18.0.0 || ^19.0", "react-dom": "^17.0.2 || ^18.0.0 || ^19.0" } }, "sha512-h2THG/75k4Y049hgjSGPIcajxXnh+IZAiXVbryQyVmagkboN7pJtBgR16g8akjwUBSfRrg6jw6KvPDjscQflog=="], 249 250 - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.7", "", { "dependencies": { "@emnapi/core": "^1.3.1", "@emnapi/runtime": "^1.3.1", "@tybys/wasm-util": "^0.9.0" } }, "sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw=="], 251 252 "@next/env": ["@next/env@15.5.4", "", {}, "sha512-27SQhYp5QryzIT5uO8hq99C69eLQ7qkzkDPsk3N+GuS2XgOgoYEeOav7Pf8Tn4drECOVDsDg8oj+/DVy8qQL2A=="], 253 ··· 675 676 "@tanstack/virtual-core": ["@tanstack/virtual-core@3.11.2", "", {}, "sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw=="], 677 678 - "@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="], 679 680 "@types/d3-array": ["@types/d3-array@3.2.1", "", {}, "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="], 681 ··· 747 748 "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], 749 750 "@unrs/rspack-resolver-binding-darwin-arm64": ["@unrs/rspack-resolver-binding-darwin-arm64@1.1.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-myn6gHyM77Y6XXGls9Wkfuu+yexGkmhPBDmBUkThrbkXtHq38vsr7o1Dyzruiqtt/okSs0tFF9P77kI6wWF9iQ=="], 751 752 "@unrs/rspack-resolver-binding-darwin-x64": ["@unrs/rspack-resolver-binding-darwin-x64@1.1.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-A/5xK8zb8lJlom+mznrp9YA8lYzHjD2QcUdQ3PkWha8x996fPjSns4ilNYHW+eGXFcEAnfVwf78q9vYf59JJmA=="], ··· 793 794 "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], 795 796 - "arr-diff": ["arr-diff@4.0.0", "", {}, "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA=="], 797 - 798 - "arr-union": ["arr-union@3.1.0", "", {}, "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q=="], 799 - 800 "array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="], 801 802 "array-includes": ["array-includes@3.1.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" } }, "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ=="], 803 - 804 - "array-unique": ["array-unique@0.3.2", "", {}, "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ=="], 805 806 "array.prototype.findlast": ["array.prototype.findlast@1.2.5", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ=="], 807 ··· 814 "array.prototype.tosorted": ["array.prototype.tosorted@1.1.4", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA=="], 815 816 "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="], 817 - 818 - "assign-symbols": ["assign-symbols@1.0.0", "", {}, "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw=="], 819 820 "ast-types-flow": ["ast-types-flow@0.0.8", "", {}, "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ=="], 821 822 "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], 823 824 - "atob": ["atob@2.1.2", "", { "bin": { "atob": "bin/atob.js" } }, "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="], 825 - 826 "autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="], 827 828 "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], ··· 835 836 "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], 837 838 - "base": ["base@0.11.2", "", { "dependencies": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", "component-emitter": "^1.2.1", "define-property": "^1.0.0", "isobject": "^3.0.1", "mixin-deep": "^1.2.0", "pascalcase": "^0.1.1" } }, "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg=="], 839 840 "big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="], 841 ··· 849 850 "browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="], 851 852 - "cache-base": ["cache-base@1.0.1", "", { "dependencies": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", "get-value": "^2.0.6", "has-value": "^1.0.0", "isobject": "^3.0.1", "set-value": "^2.0.0", "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" } }, "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ=="], 853 854 "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], 855 ··· 867 868 "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], 869 870 "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], 871 872 "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], ··· 877 878 "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], 879 880 - "class-utils": ["class-utils@0.3.6", "", { "dependencies": { "arr-union": "^3.1.0", "define-property": "^0.2.5", "isobject": "^3.0.0", "static-extend": "^0.1.1" } }, "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg=="], 881 882 "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], 883 884 "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], 885 886 "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], 887 888 - "collection-visit": ["collection-visit@1.0.0", "", { "dependencies": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" } }, "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw=="], 889 - 890 "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], 891 892 "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], ··· 901 902 "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], 903 904 - "component-emitter": ["component-emitter@1.3.1", "", {}, "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ=="], 905 906 "compute-scroll-into-view": ["compute-scroll-into-view@3.1.1", "", {}, "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw=="], 907 ··· 909 910 "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], 911 912 - "copy-descriptor": ["copy-descriptor@0.1.1", "", {}, "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw=="], 913 914 "countup.js": ["countup.js@2.8.0", "", {}, "sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ=="], 915 ··· 957 958 "decode-named-character-reference": ["decode-named-character-reference@1.1.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w=="], 959 960 - "decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="], 961 - 962 "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], 963 964 "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], ··· 966 "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], 967 968 "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], 969 - 970 - "define-property": ["define-property@2.0.2", "", { "dependencies": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" } }, "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ=="], 971 972 "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], 973 ··· 1023 1024 "eslint-config-next": ["eslint-config-next@15.5.4", "", { "dependencies": { "@next/eslint-plugin-next": "15.5.4", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^5.0.0" }, "peerDependencies": { "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-BzgVVuT3kfJes8i2GHenC1SRJ+W3BTML11lAOYFOOPzrk2xp66jBOAGEFRw+3LkYCln5UzvFsLhojrshb5Zfaw=="], 1025 1026 "eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="], 1027 1028 "eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.9.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^1.3.0", "rspack-resolver": "^1.1.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.12" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-euxa5rTGqHeqVxmOHT25hpk58PxkQ4mNoX6Yun4ooGaCHAxOCojJYNvjmyeOQxj/LyW+3fulH0+xtk+p2kPPTw=="], ··· 1031 1032 "eslint-plugin-import": ["eslint-plugin-import@2.31.0", "", { "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.12.0", "hasown": "^2.0.2", "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", "object.values": "^1.2.0", "semver": "^6.3.1", "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A=="], 1033 1034 "eslint-plugin-jsx-a11y": ["eslint-plugin-jsx-a11y@6.10.2", "", { "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", "axe-core": "^4.10.0", "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", "string.prototype.includes": "^2.0.1" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q=="], 1035 1036 - "eslint-plugin-path-alias": ["eslint-plugin-path-alias@2.1.0", "", { "dependencies": { "find-pkg": "^2.0.0", "get-tsconfig": "^4.7.5", "nanomatch": "^1.2.13" }, "peerDependencies": { "eslint": "^8.0.0" } }, "sha512-suHrHK2MmTDsmQhrZs+hvrNI2PBKAnZ4ir7y3oJLXJsjOFBfOJoQd+URqZC7ICHyNqesoZdcA0BxEG8z5p/mPw=="], 1037 - 1038 "eslint-plugin-react": ["eslint-plugin-react@7.37.5", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA=="], 1039 1040 "eslint-plugin-react-compiler": ["eslint-plugin-react-compiler@19.1.0-rc.2", "", { "dependencies": { "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "@babel/plugin-proposal-private-methods": "^7.18.6", "hermes-parser": "^0.25.1", "zod": "^3.22.4", "zod-validation-error": "^3.0.3" }, "peerDependencies": { "eslint": ">=7" } }, "sha512-oKalwDGcD+RX9mf3NEO4zOoUMeLvjSvcbbEOpquzmzqEEM2MQdp7/FY/Hx9NzmUwFzH1W9SKTz5fihfMldpEYw=="], ··· 1043 1044 "eslint-plugin-simple-import-sort": ["eslint-plugin-simple-import-sort@12.1.1", "", { "peerDependencies": { "eslint": ">=5.0.0" } }, "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA=="], 1045 1046 - "eslint-plugin-unused-imports": ["eslint-plugin-unused-imports@4.2.0", "", { "peerDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", "eslint": "^9.0.0 || ^8.0.0" }, "optionalPeers": ["@typescript-eslint/eslint-plugin"] }, "sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w=="], 1047 1048 "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], 1049 ··· 1063 1064 "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], 1065 1066 - "expand-tilde": ["expand-tilde@2.0.2", "", { "dependencies": { "homedir-polyfill": "^1.0.1" } }, "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw=="], 1067 - 1068 "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], 1069 - 1070 - "extend-shallow": ["extend-shallow@3.0.2", "", { "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" } }, "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q=="], 1071 1072 "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 1073 ··· 1085 1086 "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], 1087 1088 - "find-file-up": ["find-file-up@2.0.1", "", { "dependencies": { "resolve-dir": "^1.0.1" } }, "sha512-qVdaUhYO39zmh28/JLQM5CoYN9byEOKEH4qfa8K1eNV17W0UUMJ9WgbR/hHFH+t5rcl+6RTb5UC7ck/I+uRkpQ=="], 1089 - 1090 - "find-pkg": ["find-pkg@2.0.0", "", { "dependencies": { "find-file-up": "^2.0.1" } }, "sha512-WgZ+nKbELDa6N3i/9nrHeNznm+lY3z4YfhDDWgW+5P0pdmMj26bxaxU11ookgY3NyP9GC7HvZ9etp0jRFqGEeQ=="], 1091 1092 - "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], 1093 1094 "flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="], 1095 ··· 1099 1100 "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], 1101 1102 - "for-in": ["for-in@1.0.2", "", {}, "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ=="], 1103 - 1104 "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], 1105 1106 "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], 1107 - 1108 - "fragment-cache": ["fragment-cache@0.2.1", "", { "dependencies": { "map-cache": "^0.2.2" } }, "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA=="], 1109 1110 "framer-motion": ["framer-motion@12.23.22", "", { "dependencies": { "motion-dom": "^12.23.21", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-ZgGvdxXCw55ZYvhoZChTlG6pUuehecgvEAJz0BHoC5pQKW1EC5xf1Mul1ej5+ai+pVY0pylyFfdl45qnM1/GsA=="], 1111 ··· 1131 1132 "get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="], 1133 1134 - "get-value": ["get-value@2.0.6", "", {}, "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA=="], 1135 - 1136 "glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], 1137 1138 "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], 1139 1140 - "global-modules": ["global-modules@1.0.0", "", { "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", "resolve-dir": "^1.0.0" } }, "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg=="], 1141 - 1142 - "global-prefix": ["global-prefix@1.0.2", "", { "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", "ini": "^1.3.4", "is-windows": "^1.0.1", "which": "^1.2.14" } }, "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg=="], 1143 - 1144 - "globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], 1145 1146 "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], 1147 ··· 1161 1162 "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], 1163 1164 - "has-value": ["has-value@1.0.0", "", { "dependencies": { "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" } }, "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw=="], 1165 - 1166 - "has-values": ["has-values@1.0.0", "", { "dependencies": { "is-number": "^3.0.0", "kind-of": "^4.0.0" } }, "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ=="], 1167 - 1168 "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], 1169 1170 "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], ··· 1186 "hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="], 1187 1188 "highlight.js": ["highlight.js@11.11.1", "", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="], 1189 - 1190 - "homedir-polyfill": ["homedir-polyfill@1.0.3", "", { "dependencies": { "parse-passwd": "^1.0.0" } }, "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA=="], 1191 1192 "html-url-attributes": ["html-url-attributes@3.0.1", "", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="], 1193 ··· 1201 1202 "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], 1203 1204 "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], 1205 1206 "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], 1207 - 1208 - "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], 1209 1210 "inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="], 1211 ··· 1217 1218 "intl-messageformat": ["intl-messageformat@10.7.15", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.3", "@formatjs/fast-memoize": "2.2.6", "@formatjs/icu-messageformat-parser": "2.11.1", "tslib": "2" } }, "sha512-LRyExsEsefQSBjU2p47oAheoKz+EOJxSLDdjOaEjdriajfHsMXOmV/EhMvYSg9bAgCUHasuAC+mcUBe/95PfIg=="], 1219 1220 - "is-accessor-descriptor": ["is-accessor-descriptor@1.0.1", "", { "dependencies": { "hasown": "^2.0.0" } }, "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA=="], 1221 - 1222 "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], 1223 1224 "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], ··· 1235 1236 "is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="], 1237 1238 - "is-buffer": ["is-buffer@1.1.6", "", {}, "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="], 1239 1240 "is-bun-module": ["is-bun-module@1.3.0", "", { "dependencies": { "semver": "^7.6.3" } }, "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA=="], 1241 ··· 1243 1244 "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], 1245 1246 - "is-data-descriptor": ["is-data-descriptor@1.0.1", "", { "dependencies": { "hasown": "^2.0.0" } }, "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw=="], 1247 - 1248 "is-data-view": ["is-data-view@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" } }, "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw=="], 1249 1250 "is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="], 1251 1252 "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], 1253 - 1254 - "is-descriptor": ["is-descriptor@1.0.3", "", { "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" } }, "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw=="], 1255 - 1256 - "is-extendable": ["is-extendable@1.0.1", "", { "dependencies": { "is-plain-object": "^2.0.4" } }, "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA=="], 1257 1258 "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], 1259 ··· 1275 1276 "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], 1277 1278 - "is-plain-object": ["is-plain-object@2.0.4", "", { "dependencies": { "isobject": "^3.0.1" } }, "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og=="], 1279 - 1280 "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="], 1281 1282 "is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="], ··· 1294 "is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="], 1295 1296 "is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="], 1297 - 1298 - "is-windows": ["is-windows@1.0.2", "", {}, "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="], 1299 1300 "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], 1301 1302 "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], 1303 1304 - "isobject": ["isobject@3.0.1", "", {}, "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="], 1305 - 1306 "iterator.prototype": ["iterator.prototype@1.1.5", "", { "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "get-proto": "^1.0.0", "has-symbols": "^1.1.0", "set-function-name": "^2.0.2" } }, "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g=="], 1307 1308 "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], ··· 1330 "jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="], 1331 1332 "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], 1333 - 1334 - "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], 1335 1336 "language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="], 1337 ··· 1356 "lucide-react": ["lucide-react@0.544.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw=="], 1357 1358 "magic-bytes.js": ["magic-bytes.js@1.10.0", "", {}, "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="], 1359 - 1360 - "map-cache": ["map-cache@0.2.2", "", {}, "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="], 1361 - 1362 - "map-visit": ["map-visit@1.0.0", "", { "dependencies": { "object-visit": "^1.0.0" } }, "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w=="], 1363 1364 "match-sorter": ["match-sorter@6.4.0", "", { "dependencies": { "@babel/runtime": "^7.23.8", "remove-accents": "0.5.0" } }, "sha512-d4664ahzdL1QTTvmK1iI0JsrxWeJ6gn33qkYtnPg3mcn+naBLtXSgSPOe+X2vUgtgGwaAk3eiaj7gwKjjMAq+Q=="], 1365 ··· 1435 1436 "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], 1437 1438 - "mixin-deep": ["mixin-deep@1.3.2", "", { "dependencies": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" } }, "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA=="], 1439 - 1440 "motion-dom": ["motion-dom@12.23.21", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-5xDXx/AbhrfgsQmSE7YESMn4Dpo6x5/DTZ4Iyy4xqDvVHWvFVoV+V2Ri2S/ksx+D40wrZ7gPYiMWshkdoqNgNQ=="], 1441 1442 "motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="], ··· 1449 1450 "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], 1451 1452 - "nanomatch": ["nanomatch@1.2.13", "", { "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "fragment-cache": "^0.2.1", "is-windows": "^1.0.2", "kind-of": "^6.0.2", "object.pick": "^1.3.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" } }, "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA=="], 1453 1454 "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], 1455 ··· 1464 "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], 1465 1466 "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], 1467 - 1468 - "object-copy": ["object-copy@0.1.0", "", { "dependencies": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", "kind-of": "^3.0.3" } }, "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ=="], 1469 1470 "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], 1471 ··· 1473 1474 "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], 1475 1476 - "object-visit": ["object-visit@1.0.1", "", { "dependencies": { "isobject": "^3.0.0" } }, "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA=="], 1477 - 1478 "object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="], 1479 1480 "object.entries": ["object.entries@1.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-object-atoms": "^1.1.1" } }, "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw=="], ··· 1482 "object.fromentries": ["object.fromentries@2.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0" } }, "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ=="], 1483 1484 "object.groupby": ["object.groupby@1.0.3", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2" } }, "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ=="], 1485 - 1486 - "object.pick": ["object.pick@1.3.0", "", { "dependencies": { "isobject": "^3.0.1" } }, "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ=="], 1487 1488 "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="], 1489 ··· 1505 1506 "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], 1507 1508 - "parse-passwd": ["parse-passwd@1.0.0", "", {}, "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q=="], 1509 - 1510 "parse5": ["parse5@7.2.1", "", { "dependencies": { "entities": "^4.5.0" } }, "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ=="], 1511 - 1512 - "pascalcase": ["pascalcase@0.1.1", "", {}, "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw=="], 1513 1514 "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], 1515 ··· 1528 "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], 1529 1530 "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], 1531 1532 "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], 1533 ··· 1595 1596 "regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="], 1597 1598 - "regex-not": ["regex-not@1.0.2", "", { "dependencies": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" } }, "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A=="], 1599 1600 "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="], 1601 1602 "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], 1603 ··· 1611 1612 "resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="], 1613 1614 - "resolve-dir": ["resolve-dir@1.0.1", "", { "dependencies": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" } }, "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg=="], 1615 - 1616 "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], 1617 1618 "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], 1619 1620 - "resolve-url": ["resolve-url@0.2.1", "", {}, "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg=="], 1621 - 1622 - "ret": ["ret@0.1.15", "", {}, "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="], 1623 - 1624 "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], 1625 1626 "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], ··· 1633 1634 "safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="], 1635 1636 - "safe-regex": ["safe-regex@1.1.0", "", { "dependencies": { "ret": "~0.1.10" } }, "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg=="], 1637 - 1638 "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], 1639 1640 "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], 1641 1642 "scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.0.10", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-t44QCeDKAPf1mtQH3fYpWz8IM/DyvHLjs8wUvvwMYxk5moOqCzrMSxK6HQVD0QVmVjXFavoFIPRVrMuJPKAvtg=="], 1643 1644 - "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], 1645 1646 "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], 1647 1648 "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="], 1649 1650 "set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="], 1651 - 1652 - "set-value": ["set-value@2.0.1", "", { "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", "is-plain-object": "^2.0.3", "split-string": "^3.0.1" } }, "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw=="], 1653 1654 "sharp": ["sharp@0.34.4", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="], 1655 ··· 1669 1670 "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="], 1671 1672 - "snapdragon": ["snapdragon@0.8.2", "", { "dependencies": { "base": "^0.11.1", "debug": "^2.2.0", "define-property": "^0.2.5", "extend-shallow": "^2.0.1", "map-cache": "^0.2.2", "source-map": "^0.5.6", "source-map-resolve": "^0.5.0", "use": "^3.1.0" } }, "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg=="], 1673 - 1674 - "source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], 1675 - 1676 "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], 1677 1678 - "source-map-resolve": ["source-map-resolve@0.5.3", "", { "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", "urix": "^0.1.0" } }, "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw=="], 1679 - 1680 - "source-map-url": ["source-map-url@0.4.1", "", {}, "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw=="], 1681 - 1682 "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], 1683 1684 - "split-string": ["split-string@3.1.0", "", { "dependencies": { "extend-shallow": "^3.0.0" } }, "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw=="], 1685 - 1686 "stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="], 1687 1688 - "static-extend": ["static-extend@0.1.2", "", { "dependencies": { "define-property": "^0.2.5", "object-copy": "^0.1.0" } }, "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g=="], 1689 1690 "string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], 1691 ··· 1710 "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], 1711 1712 "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], 1713 1714 "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], 1715 ··· 1741 1742 "tinyglobby": ["tinyglobby@0.2.12", "", { "dependencies": { "fdir": "^6.4.3", "picomatch": "^4.0.2" } }, "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww=="], 1743 1744 - "to-object-path": ["to-object-path@0.3.0", "", { "dependencies": { "kind-of": "^3.0.2" } }, "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg=="], 1745 - 1746 - "to-regex": ["to-regex@3.0.2", "", { "dependencies": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "regex-not": "^1.0.2", "safe-regex": "^1.1.0" } }, "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw=="], 1747 - 1748 "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], 1749 1750 "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], ··· 1781 1782 "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], 1783 1784 - "union-value": ["union-value@1.0.1", "", { "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" } }, "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg=="], 1785 - 1786 "unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="], 1787 1788 "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], ··· 1795 1796 "unload": ["unload@2.2.0", "", { "dependencies": { "@babel/runtime": "^7.6.2", "detect-node": "^2.0.4" } }, "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA=="], 1797 1798 - "unset-value": ["unset-value@1.0.0", "", { "dependencies": { "has-value": "^0.3.1", "isobject": "^3.0.0" } }, "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ=="], 1799 1800 "update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], 1801 1802 "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], 1803 1804 - "urix": ["urix@0.1.0", "", {}, "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg=="], 1805 - 1806 - "use": ["use@3.1.1", "", {}, "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="], 1807 - 1808 "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], 1809 1810 "use-composed-ref": ["use-composed-ref@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w=="], ··· 1863 1864 "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], 1865 1866 "@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], 1867 1868 "@discordjs/rest/discord-api-types": ["discord-api-types@0.38.21", "", {}, "sha512-E6KtXUNjZVIYP1GMjmeRdAC1xRql9xtSahRwJYpP74/hJ6Q2i2oTp6ZbFG/FUN0WqtdW2igHDsJyF2u9hV8pHQ=="], 1869 ··· 1871 1872 "@eslint/eslintrc/espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="], 1873 1874 - "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="], 1875 1876 - "@napi-rs/wasm-runtime/@emnapi/runtime": ["@emnapi/runtime@1.3.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw=="], 1877 1878 "@nextui-org/system-rsc/clsx": ["clsx@1.2.1", "", {}, "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="], 1879 ··· 2055 2056 "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 2057 2058 - "@typescript-eslint/typescript-estree/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], 2059 2060 "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 2061 2062 "autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001705", "", {}, "sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg=="], 2063 2064 - "base/define-property": ["define-property@1.0.0", "", { "dependencies": { "is-descriptor": "^1.0.0" } }, "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA=="], 2065 - 2066 "browserslist/caniuse-lite": ["caniuse-lite@1.0.30001705", "", {}, "sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg=="], 2067 2068 "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 2069 2070 - "class-utils/define-property": ["define-property@0.2.5", "", { "dependencies": { "is-descriptor": "^0.1.0" } }, "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA=="], 2071 2072 "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], 2073 ··· 2077 2078 "eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], 2079 2080 - "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 2081 2082 - "glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 2083 2084 - "global-prefix/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "./bin/which" } }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="], 2085 2086 - "has-values/is-number": ["is-number@3.0.0", "", { "dependencies": { "kind-of": "^3.0.2" } }, "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg=="], 2087 2088 - "has-values/kind-of": ["kind-of@4.0.0", "", { "dependencies": { "is-buffer": "^1.1.5" } }, "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw=="], 2089 2090 "hast-util-to-parse5/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="], 2091 ··· 2095 2096 "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], 2097 2098 - "object-copy/define-property": ["define-property@0.2.5", "", { "dependencies": { "is-descriptor": "^0.1.0" } }, "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA=="], 2099 - 2100 - "object-copy/kind-of": ["kind-of@3.2.2", "", { "dependencies": { "is-buffer": "^1.1.5" } }, "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ=="], 2101 - 2102 "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], 2103 2104 "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], ··· 2109 2110 "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 2111 2112 - "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], 2113 - 2114 - "set-value/extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], 2115 - 2116 - "set-value/is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], 2117 - 2118 - "sharp/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], 2119 - 2120 - "snapdragon/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], 2121 - 2122 - "snapdragon/define-property": ["define-property@0.2.5", "", { "dependencies": { "is-descriptor": "^0.1.0" } }, "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA=="], 2123 - 2124 - "snapdragon/extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], 2125 2126 - "static-extend/define-property": ["define-property@0.2.5", "", { "dependencies": { "is-descriptor": "^0.1.0" } }, "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA=="], 2127 2128 "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], 2129 ··· 2139 2140 "tinyglobby/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], 2141 2142 - "to-object-path/kind-of": ["kind-of@3.2.2", "", { "dependencies": { "is-buffer": "^1.1.5" } }, "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ=="], 2143 - 2144 "tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="], 2145 - 2146 - "union-value/is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], 2147 - 2148 - "unset-value/has-value": ["has-value@0.3.1", "", { "dependencies": { "get-value": "^2.0.3", "has-values": "^0.1.4", "isobject": "^2.0.0" } }, "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q=="], 2149 2150 "vaul/@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw=="], 2151 ··· 2249 2250 "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 2251 2252 - "class-utils/define-property/is-descriptor": ["is-descriptor@0.1.7", "", { "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" } }, "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg=="], 2253 2254 - "glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 2255 2256 - "has-values/is-number/kind-of": ["kind-of@3.2.2", "", { "dependencies": { "is-buffer": "^1.1.5" } }, "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ=="], 2257 2258 - "next/postcss/nanoid": ["nanoid@3.3.10", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg=="], 2259 2260 - "object-copy/define-property/is-descriptor": ["is-descriptor@0.1.7", "", { "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" } }, "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg=="], 2261 - 2262 - "snapdragon/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], 2263 2264 - "snapdragon/define-property/is-descriptor": ["is-descriptor@0.1.7", "", { "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" } }, "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg=="], 2265 2266 - "snapdragon/extend-shallow/is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], 2267 2268 - "static-extend/define-property/is-descriptor": ["is-descriptor@0.1.7", "", { "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" } }, "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg=="], 2269 2270 "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], 2271 2272 "tailwindcss/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 2273 - 2274 - "unset-value/has-value/has-values": ["has-values@0.1.4", "", {}, "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ=="], 2275 - 2276 - "unset-value/has-value/isobject": ["isobject@2.1.0", "", { "dependencies": { "isarray": "1.0.0" } }, "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA=="], 2277 2278 "vaul/@radix-ui/react-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.1.1", "", {}, "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA=="], 2279 ··· 2311 2312 "@react-aria/tabs/@react-aria/selection/@react-aria/i18n/@internationalized/date": ["@internationalized/date@3.7.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ=="], 2313 2314 - "unset-value/has-value/isobject/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], 2315 2316 "vaul/@radix-ui/react-dialog/@radix-ui/react-dismissable-layer/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="], 2317
··· 56 "@types/react-dom": "^19.1.9", 57 "eslint": "^9.36.0", 58 "eslint-config-next": "^15.5.4", 59 + "eslint-plugin-import-x": "^4.16.1", 60 "eslint-plugin-react": "^7.37.5", 61 "eslint-plugin-react-compiler": "19.1.0-rc.2", 62 "eslint-plugin-react-hooks": "^5.2.0", 63 "eslint-plugin-simple-import-sort": "^12.1.1", 64 + "eslint-plugin-unicorn": "^61.0.2", 65 "typescript-eslint": "^8.44.1", 66 }, 67 }, ··· 101 102 "@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="], 103 104 + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="], 105 106 "@babel/helper-validator-option": ["@babel/helper-validator-option@7.25.9", "", {}, "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw=="], 107 ··· 125 126 "@discordjs/util": ["@discordjs/util@1.1.1", "", {}, "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g=="], 127 128 + "@emnapi/core": ["@emnapi/core@1.5.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg=="], 129 130 "@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], 131 132 + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], 133 134 "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], 135 ··· 247 248 "@marsidev/react-turnstile": ["@marsidev/react-turnstile@1.3.1", "", { "peerDependencies": { "react": "^17.0.2 || ^18.0.0 || ^19.0", "react-dom": "^17.0.2 || ^18.0.0 || ^19.0" } }, "sha512-h2THG/75k4Y049hgjSGPIcajxXnh+IZAiXVbryQyVmagkboN7pJtBgR16g8akjwUBSfRrg6jw6KvPDjscQflog=="], 249 250 + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], 251 252 "@next/env": ["@next/env@15.5.4", "", {}, "sha512-27SQhYp5QryzIT5uO8hq99C69eLQ7qkzkDPsk3N+GuS2XgOgoYEeOav7Pf8Tn4drECOVDsDg8oj+/DVy8qQL2A=="], 253 ··· 675 676 "@tanstack/virtual-core": ["@tanstack/virtual-core@3.11.2", "", {}, "sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw=="], 677 678 + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], 679 680 "@types/d3-array": ["@types/d3-array@3.2.1", "", {}, "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="], 681 ··· 747 748 "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], 749 750 + "@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="], 751 + 752 + "@unrs/resolver-binding-android-arm64": ["@unrs/resolver-binding-android-arm64@1.11.1", "", { "os": "android", "cpu": "arm64" }, "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g=="], 753 + 754 + "@unrs/resolver-binding-darwin-arm64": ["@unrs/resolver-binding-darwin-arm64@1.11.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g=="], 755 + 756 + "@unrs/resolver-binding-darwin-x64": ["@unrs/resolver-binding-darwin-x64@1.11.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ=="], 757 + 758 + "@unrs/resolver-binding-freebsd-x64": ["@unrs/resolver-binding-freebsd-x64@1.11.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw=="], 759 + 760 + "@unrs/resolver-binding-linux-arm-gnueabihf": ["@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw=="], 761 + 762 + "@unrs/resolver-binding-linux-arm-musleabihf": ["@unrs/resolver-binding-linux-arm-musleabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw=="], 763 + 764 + "@unrs/resolver-binding-linux-arm64-gnu": ["@unrs/resolver-binding-linux-arm64-gnu@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ=="], 765 + 766 + "@unrs/resolver-binding-linux-arm64-musl": ["@unrs/resolver-binding-linux-arm64-musl@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w=="], 767 + 768 + "@unrs/resolver-binding-linux-ppc64-gnu": ["@unrs/resolver-binding-linux-ppc64-gnu@1.11.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA=="], 769 + 770 + "@unrs/resolver-binding-linux-riscv64-gnu": ["@unrs/resolver-binding-linux-riscv64-gnu@1.11.1", "", { "os": "linux", "cpu": "none" }, "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ=="], 771 + 772 + "@unrs/resolver-binding-linux-riscv64-musl": ["@unrs/resolver-binding-linux-riscv64-musl@1.11.1", "", { "os": "linux", "cpu": "none" }, "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew=="], 773 + 774 + "@unrs/resolver-binding-linux-s390x-gnu": ["@unrs/resolver-binding-linux-s390x-gnu@1.11.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg=="], 775 + 776 + "@unrs/resolver-binding-linux-x64-gnu": ["@unrs/resolver-binding-linux-x64-gnu@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w=="], 777 + 778 + "@unrs/resolver-binding-linux-x64-musl": ["@unrs/resolver-binding-linux-x64-musl@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA=="], 779 + 780 + "@unrs/resolver-binding-wasm32-wasi": ["@unrs/resolver-binding-wasm32-wasi@1.11.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.11" }, "cpu": "none" }, "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ=="], 781 + 782 + "@unrs/resolver-binding-win32-arm64-msvc": ["@unrs/resolver-binding-win32-arm64-msvc@1.11.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw=="], 783 + 784 + "@unrs/resolver-binding-win32-ia32-msvc": ["@unrs/resolver-binding-win32-ia32-msvc@1.11.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ=="], 785 + 786 + "@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="], 787 + 788 "@unrs/rspack-resolver-binding-darwin-arm64": ["@unrs/rspack-resolver-binding-darwin-arm64@1.1.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-myn6gHyM77Y6XXGls9Wkfuu+yexGkmhPBDmBUkThrbkXtHq38vsr7o1Dyzruiqtt/okSs0tFF9P77kI6wWF9iQ=="], 789 790 "@unrs/rspack-resolver-binding-darwin-x64": ["@unrs/rspack-resolver-binding-darwin-x64@1.1.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-A/5xK8zb8lJlom+mznrp9YA8lYzHjD2QcUdQ3PkWha8x996fPjSns4ilNYHW+eGXFcEAnfVwf78q9vYf59JJmA=="], ··· 831 832 "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], 833 834 "array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="], 835 836 "array-includes": ["array-includes@3.1.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" } }, "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ=="], 837 838 "array.prototype.findlast": ["array.prototype.findlast@1.2.5", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ=="], 839 ··· 846 "array.prototype.tosorted": ["array.prototype.tosorted@1.1.4", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA=="], 847 848 "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="], 849 850 "ast-types-flow": ["ast-types-flow@0.0.8", "", {}, "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ=="], 851 852 "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], 853 854 "autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="], 855 856 "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], ··· 863 864 "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], 865 866 + "baseline-browser-mapping": ["baseline-browser-mapping@2.8.9", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-hY/u2lxLrbecMEWSB0IpGzGyDyeoMFQhCvZd2jGFSE5I17Fh01sYUBPCJtkWERw7zrac9+cIghxm/ytJa2X8iA=="], 867 868 "big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="], 869 ··· 877 878 "browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="], 879 880 + "builtin-modules": ["builtin-modules@5.0.0", "", {}, "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg=="], 881 882 "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], 883 ··· 895 896 "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], 897 898 + "change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="], 899 + 900 "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], 901 902 "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], ··· 907 908 "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], 909 910 + "ci-info": ["ci-info@4.3.0", "", {}, "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ=="], 911 912 "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], 913 + 914 + "clean-regexp": ["clean-regexp@1.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw=="], 915 916 "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], 917 918 "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], 919 920 "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], 921 922 "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], ··· 931 932 "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], 933 934 + "comment-parser": ["comment-parser@1.4.1", "", {}, "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg=="], 935 936 "compute-scroll-into-view": ["compute-scroll-into-view@3.1.1", "", {}, "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw=="], 937 ··· 939 940 "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], 941 942 + "core-js-compat": ["core-js-compat@3.45.1", "", { "dependencies": { "browserslist": "^4.25.3" } }, "sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA=="], 943 944 "countup.js": ["countup.js@2.8.0", "", {}, "sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ=="], 945 ··· 987 988 "decode-named-character-reference": ["decode-named-character-reference@1.1.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w=="], 989 990 "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], 991 992 "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], ··· 994 "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], 995 996 "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], 997 998 "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], 999 ··· 1049 1050 "eslint-config-next": ["eslint-config-next@15.5.4", "", { "dependencies": { "@next/eslint-plugin-next": "15.5.4", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^5.0.0" }, "peerDependencies": { "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-BzgVVuT3kfJes8i2GHenC1SRJ+W3BTML11lAOYFOOPzrk2xp66jBOAGEFRw+3LkYCln5UzvFsLhojrshb5Zfaw=="], 1051 1052 + "eslint-import-context": ["eslint-import-context@0.1.9", "", { "dependencies": { "get-tsconfig": "^4.10.1", "stable-hash-x": "^0.2.0" }, "peerDependencies": { "unrs-resolver": "^1.0.0" }, "optionalPeers": ["unrs-resolver"] }, "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg=="], 1053 + 1054 "eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="], 1055 1056 "eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.9.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^1.3.0", "rspack-resolver": "^1.1.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.12" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-euxa5rTGqHeqVxmOHT25hpk58PxkQ4mNoX6Yun4ooGaCHAxOCojJYNvjmyeOQxj/LyW+3fulH0+xtk+p2kPPTw=="], ··· 1059 1060 "eslint-plugin-import": ["eslint-plugin-import@2.31.0", "", { "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.12.0", "hasown": "^2.0.2", "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", "object.values": "^1.2.0", "semver": "^6.3.1", "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A=="], 1061 1062 + "eslint-plugin-import-x": ["eslint-plugin-import-x@4.16.1", "", { "dependencies": { "@typescript-eslint/types": "^8.35.0", "comment-parser": "^1.4.1", "debug": "^4.4.1", "eslint-import-context": "^0.1.9", "is-glob": "^4.0.3", "minimatch": "^9.0.3 || ^10.0.1", "semver": "^7.7.2", "stable-hash-x": "^0.2.0", "unrs-resolver": "^1.9.2" }, "peerDependencies": { "@typescript-eslint/utils": "^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "eslint-import-resolver-node": "*" }, "optionalPeers": ["@typescript-eslint/utils", "eslint-import-resolver-node"] }, "sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ=="], 1063 + 1064 "eslint-plugin-jsx-a11y": ["eslint-plugin-jsx-a11y@6.10.2", "", { "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", "axe-core": "^4.10.0", "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", "string.prototype.includes": "^2.0.1" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q=="], 1065 1066 "eslint-plugin-react": ["eslint-plugin-react@7.37.5", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA=="], 1067 1068 "eslint-plugin-react-compiler": ["eslint-plugin-react-compiler@19.1.0-rc.2", "", { "dependencies": { "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "@babel/plugin-proposal-private-methods": "^7.18.6", "hermes-parser": "^0.25.1", "zod": "^3.22.4", "zod-validation-error": "^3.0.3" }, "peerDependencies": { "eslint": ">=7" } }, "sha512-oKalwDGcD+RX9mf3NEO4zOoUMeLvjSvcbbEOpquzmzqEEM2MQdp7/FY/Hx9NzmUwFzH1W9SKTz5fihfMldpEYw=="], ··· 1071 1072 "eslint-plugin-simple-import-sort": ["eslint-plugin-simple-import-sort@12.1.1", "", { "peerDependencies": { "eslint": ">=5.0.0" } }, "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA=="], 1073 1074 + "eslint-plugin-unicorn": ["eslint-plugin-unicorn@61.0.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "@eslint-community/eslint-utils": "^4.7.0", "@eslint/plugin-kit": "^0.3.3", "change-case": "^5.4.4", "ci-info": "^4.3.0", "clean-regexp": "^1.0.0", "core-js-compat": "^3.44.0", "esquery": "^1.6.0", "find-up-simple": "^1.0.1", "globals": "^16.3.0", "indent-string": "^5.0.0", "is-builtin-module": "^5.0.0", "jsesc": "^3.1.0", "pluralize": "^8.0.0", "regexp-tree": "^0.1.27", "regjsparser": "^0.12.0", "semver": "^7.7.2", "strip-indent": "^4.0.0" }, "peerDependencies": { "eslint": ">=9.29.0" } }, "sha512-zLihukvneYT7f74GNbVJXfWIiNQmkc/a9vYBTE4qPkQZswolWNdu+Wsp9sIXno1JOzdn6OUwLPd19ekXVkahRA=="], 1075 1076 "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], 1077 ··· 1091 1092 "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], 1093 1094 "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], 1095 1096 "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 1097 ··· 1109 1110 "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], 1111 1112 + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], 1113 1114 + "find-up-simple": ["find-up-simple@1.0.1", "", {}, "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ=="], 1115 1116 "flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="], 1117 ··· 1121 1122 "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], 1123 1124 "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], 1125 1126 "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], 1127 1128 "framer-motion": ["framer-motion@12.23.22", "", { "dependencies": { "motion-dom": "^12.23.21", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-ZgGvdxXCw55ZYvhoZChTlG6pUuehecgvEAJz0BHoC5pQKW1EC5xf1Mul1ej5+ai+pVY0pylyFfdl45qnM1/GsA=="], 1129 ··· 1149 1150 "get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="], 1151 1152 "glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], 1153 1154 "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], 1155 1156 + "globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="], 1157 1158 "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], 1159 ··· 1173 1174 "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], 1175 1176 "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], 1177 1178 "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], ··· 1194 "hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="], 1195 1196 "highlight.js": ["highlight.js@11.11.1", "", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="], 1197 1198 "html-url-attributes": ["html-url-attributes@3.0.1", "", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="], 1199 ··· 1207 1208 "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], 1209 1210 + "indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], 1211 + 1212 "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], 1213 1214 "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], 1215 1216 "inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="], 1217 ··· 1223 1224 "intl-messageformat": ["intl-messageformat@10.7.15", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.3", "@formatjs/fast-memoize": "2.2.6", "@formatjs/icu-messageformat-parser": "2.11.1", "tslib": "2" } }, "sha512-LRyExsEsefQSBjU2p47oAheoKz+EOJxSLDdjOaEjdriajfHsMXOmV/EhMvYSg9bAgCUHasuAC+mcUBe/95PfIg=="], 1225 1226 "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], 1227 1228 "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], ··· 1239 1240 "is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="], 1241 1242 + "is-builtin-module": ["is-builtin-module@5.0.0", "", { "dependencies": { "builtin-modules": "^5.0.0" } }, "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA=="], 1243 1244 "is-bun-module": ["is-bun-module@1.3.0", "", { "dependencies": { "semver": "^7.6.3" } }, "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA=="], 1245 ··· 1247 1248 "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], 1249 1250 "is-data-view": ["is-data-view@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" } }, "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw=="], 1251 1252 "is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="], 1253 1254 "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], 1255 1256 "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], 1257 ··· 1273 1274 "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], 1275 1276 "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="], 1277 1278 "is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="], ··· 1290 "is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="], 1291 1292 "is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="], 1293 1294 "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], 1295 1296 "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], 1297 1298 "iterator.prototype": ["iterator.prototype@1.1.5", "", { "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "get-proto": "^1.0.0", "has-symbols": "^1.1.0", "set-function-name": "^2.0.2" } }, "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g=="], 1299 1300 "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], ··· 1322 "jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="], 1323 1324 "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], 1325 1326 "language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="], 1327 ··· 1346 "lucide-react": ["lucide-react@0.544.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw=="], 1347 1348 "magic-bytes.js": ["magic-bytes.js@1.10.0", "", {}, "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="], 1349 1350 "match-sorter": ["match-sorter@6.4.0", "", { "dependencies": { "@babel/runtime": "^7.23.8", "remove-accents": "0.5.0" } }, "sha512-d4664ahzdL1QTTvmK1iI0JsrxWeJ6gn33qkYtnPg3mcn+naBLtXSgSPOe+X2vUgtgGwaAk3eiaj7gwKjjMAq+Q=="], 1351 ··· 1421 1422 "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], 1423 1424 "motion-dom": ["motion-dom@12.23.21", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-5xDXx/AbhrfgsQmSE7YESMn4Dpo6x5/DTZ4Iyy4xqDvVHWvFVoV+V2Ri2S/ksx+D40wrZ7gPYiMWshkdoqNgNQ=="], 1425 1426 "motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="], ··· 1433 1434 "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], 1435 1436 + "napi-postinstall": ["napi-postinstall@0.3.3", "", { "bin": { "napi-postinstall": "lib/cli.js" } }, "sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow=="], 1437 1438 "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], 1439 ··· 1448 "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], 1449 1450 "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], 1451 1452 "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], 1453 ··· 1455 1456 "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], 1457 1458 "object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="], 1459 1460 "object.entries": ["object.entries@1.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-object-atoms": "^1.1.1" } }, "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw=="], ··· 1462 "object.fromentries": ["object.fromentries@2.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0" } }, "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ=="], 1463 1464 "object.groupby": ["object.groupby@1.0.3", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2" } }, "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ=="], 1465 1466 "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="], 1467 ··· 1483 1484 "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], 1485 1486 "parse5": ["parse5@7.2.1", "", { "dependencies": { "entities": "^4.5.0" } }, "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ=="], 1487 1488 "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], 1489 ··· 1502 "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], 1503 1504 "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], 1505 + 1506 + "pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="], 1507 1508 "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="], 1509 ··· 1571 1572 "regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="], 1573 1574 + "regexp-tree": ["regexp-tree@0.1.27", "", { "bin": { "regexp-tree": "bin/regexp-tree" } }, "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA=="], 1575 1576 "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="], 1577 + 1578 + "regjsparser": ["regjsparser@0.12.0", "", { "dependencies": { "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ=="], 1579 1580 "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], 1581 ··· 1589 1590 "resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="], 1591 1592 "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], 1593 1594 "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], 1595 1596 "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], 1597 1598 "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], ··· 1605 1606 "safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="], 1607 1608 "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], 1609 1610 "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], 1611 1612 "scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.0.10", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-t44QCeDKAPf1mtQH3fYpWz8IM/DyvHLjs8wUvvwMYxk5moOqCzrMSxK6HQVD0QVmVjXFavoFIPRVrMuJPKAvtg=="], 1613 1614 + "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], 1615 1616 "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], 1617 1618 "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="], 1619 1620 "set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="], 1621 1622 "sharp": ["sharp@0.34.4", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="], 1623 ··· 1637 1638 "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="], 1639 1640 "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], 1641 1642 "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], 1643 1644 "stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="], 1645 1646 + "stable-hash-x": ["stable-hash-x@0.2.0", "", {}, "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ=="], 1647 1648 "string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], 1649 ··· 1668 "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], 1669 1670 "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], 1671 + 1672 + "strip-indent": ["strip-indent@4.1.0", "", {}, "sha512-OA95x+JPmL7kc7zCu+e+TeYxEiaIyndRx0OrBcK2QPPH09oAndr2ALvymxWA+Lx1PYYvFUm4O63pRkdJAaW96w=="], 1673 1674 "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], 1675 ··· 1701 1702 "tinyglobby": ["tinyglobby@0.2.12", "", { "dependencies": { "fdir": "^6.4.3", "picomatch": "^4.0.2" } }, "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww=="], 1703 1704 "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], 1705 1706 "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], ··· 1737 1738 "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], 1739 1740 "unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="], 1741 1742 "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], ··· 1749 1750 "unload": ["unload@2.2.0", "", { "dependencies": { "@babel/runtime": "^7.6.2", "detect-node": "^2.0.4" } }, "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA=="], 1751 1752 + "unrs-resolver": ["unrs-resolver@1.11.1", "", { "dependencies": { "napi-postinstall": "^0.3.0" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.11.1", "@unrs/resolver-binding-android-arm64": "1.11.1", "@unrs/resolver-binding-darwin-arm64": "1.11.1", "@unrs/resolver-binding-darwin-x64": "1.11.1", "@unrs/resolver-binding-freebsd-x64": "1.11.1", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-musl": "1.11.1", "@unrs/resolver-binding-wasm32-wasi": "1.11.1", "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg=="], 1753 1754 "update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], 1755 1756 "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], 1757 1758 "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], 1759 1760 "use-composed-ref": ["use-composed-ref@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w=="], ··· 1813 1814 "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], 1815 1816 + "@babel/code-frame/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], 1817 + 1818 + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], 1819 + 1820 + "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], 1821 + 1822 + "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], 1823 + 1824 + "@babel/helper-module-transforms/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], 1825 + 1826 "@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], 1827 + 1828 + "@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], 1829 1830 "@discordjs/rest/discord-api-types": ["discord-api-types@0.38.21", "", {}, "sha512-E6KtXUNjZVIYP1GMjmeRdAC1xRql9xtSahRwJYpP74/hJ6Q2i2oTp6ZbFG/FUN0WqtdW2igHDsJyF2u9hV8pHQ=="], 1831 ··· 1833 1834 "@eslint/eslintrc/espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="], 1835 1836 + "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], 1837 1838 + "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="], 1839 1840 "@nextui-org/system-rsc/clsx": ["clsx@1.2.1", "", {}, "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="], 1841 ··· 2017 2018 "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 2019 2020 + "@unrs/rspack-resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.7", "", { "dependencies": { "@emnapi/core": "^1.3.1", "@emnapi/runtime": "^1.3.1", "@tybys/wasm-util": "^0.9.0" } }, "sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw=="], 2021 2022 "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 2023 2024 "autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001705", "", {}, "sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg=="], 2025 2026 "browserslist/caniuse-lite": ["caniuse-lite@1.0.30001705", "", {}, "sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg=="], 2027 2028 "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 2029 2030 + "clean-regexp/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], 2031 + 2032 + "core-js-compat/browserslist": ["browserslist@4.26.2", "", { "dependencies": { "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001741", "electron-to-chromium": "^1.5.218", "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A=="], 2033 + 2034 + "eslint-import-context/get-tsconfig": ["get-tsconfig@4.10.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ=="], 2035 2036 "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], 2037 ··· 2041 2042 "eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], 2043 2044 + "eslint-plugin-import/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], 2045 2046 + "eslint-plugin-import-x/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], 2047 2048 + "eslint-plugin-import-x/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 2049 2050 + "eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], 2051 2052 + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 2053 + 2054 + "glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 2055 2056 "hast-util-to-parse5/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="], 2057 ··· 2061 2062 "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], 2063 2064 "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], 2065 2066 "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], ··· 2071 2072 "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 2073 2074 + "regjsparser/jsesc": ["jsesc@3.0.2", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g=="], 2075 2076 + "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], 2077 2078 "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], 2079 ··· 2089 2090 "tinyglobby/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], 2091 2092 "tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="], 2093 2094 "vaul/@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw=="], 2095 ··· 2193 2194 "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 2195 2196 + "@unrs/rspack-resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime/@emnapi/core": ["@emnapi/core@1.3.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.1", "tslib": "^2.4.0" } }, "sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog=="], 2197 2198 + "@unrs/rspack-resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime/@emnapi/runtime": ["@emnapi/runtime@1.3.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw=="], 2199 2200 + "@unrs/rspack-resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="], 2201 2202 + "core-js-compat/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.227", "", {}, "sha512-ITxuoPfJu3lsNWUi2lBM2PaBPYgH3uqmxut5vmBxgYvyI4AlJ6P3Cai1O76mOrkJCBzq0IxWg/NtqOrpu/0gKA=="], 2203 2204 + "core-js-compat/browserslist/node-releases": ["node-releases@2.0.21", "", {}, "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw=="], 2205 2206 + "eslint-plugin-import-x/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 2207 2208 + "glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 2209 2210 + "next/postcss/nanoid": ["nanoid@3.3.10", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg=="], 2211 2212 "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], 2213 2214 "tailwindcss/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 2215 2216 "vaul/@radix-ui/react-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.1.1", "", {}, "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA=="], 2217 ··· 2249 2250 "@react-aria/tabs/@react-aria/selection/@react-aria/i18n/@internationalized/date": ["@internationalized/date@3.7.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ=="], 2251 2252 + "@unrs/rspack-resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw=="], 2253 2254 "vaul/@radix-ui/react-dialog/@radix-ui/react-dismissable-layer/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="], 2255
+1 -2
common/guilds.ts
··· 1 import { create } from "zustand"; 2 - 3 - import type { ApiV1GuildsChannelsGetResponse, ApiV1GuildsEmojisGetResponse, ApiV1GuildsGetResponse, ApiV1GuildsRolesGetResponse } from "@/typings"; 4 5 export interface Guild extends ApiV1GuildsGetResponse { 6 channels?: ApiV1GuildsChannelsGetResponse[];
··· 1 + import type { ApiV1GuildsChannelsGetResponse, ApiV1GuildsEmojisGetResponse, ApiV1GuildsGetResponse, ApiV1GuildsRolesGetResponse } from "@/typings"; 2 import { create } from "zustand"; 3 4 export interface Guild extends ApiV1GuildsGetResponse { 5 channels?: ApiV1GuildsChannelsGetResponse[];
+1 -2
common/user.ts
··· 1 import { create } from "zustand"; 2 - 3 - import type { ApiV1UsersMeGetResponse } from "@/typings"; 4 5 export interface User { 6 HELLO_AND_WELCOME_TO_THE_DEV_TOOLS__PLEASE_GO_AWAY?: true;
··· 1 + import type { ApiV1UsersMeGetResponse } from "@/typings"; 2 import { create } from "zustand"; 3 4 export interface User { 5 HELLO_AND_WELCOME_TO_THE_DEV_TOOLS__PLEASE_GO_AWAY?: true;
+1 -2
components/ad.tsx
··· 1 "use client"; 2 3 import { Poppins } from "next/font/google"; 4 import Link from "next/link"; 5 import type { FunctionComponent } from "react"; 6 import { HiArrowNarrowRight } from "react-icons/hi"; 7 - 8 - import { cn } from "@/utils/cn"; 9 10 import { Button } from "./ui/button"; 11
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import { Poppins } from "next/font/google"; 5 import Link from "next/link"; 6 import type { FunctionComponent } from "react"; 7 import { HiArrowNarrowRight } from "react-icons/hi"; 8 9 import { Button } from "./ui/button"; 10
+1 -2
components/box.tsx
··· 1 import React, { type HTMLProps } from "react"; 2 - 3 - import { cn } from "@/utils/cn"; 4 5 type Props = HTMLProps<HTMLDivElement> & { 6 children: React.ReactNode;
··· 1 + import { cn } from "@/utils/cn"; 2 import React, { type HTMLProps } from "react"; 3 4 type Props = HTMLProps<HTMLDivElement> & { 5 children: React.ReactNode;
+3 -3
components/button-fetch.tsx
··· 36 setError(null); 37 38 const res = await fetch(`${process.env.NEXT_PUBLIC_API}${url}`, { 39 - method: method, 40 credentials: "include", 41 headers: { 42 "Content-Type": "application/json" ··· 46 47 if (res.status === 429) { 48 setState(State.Ratelimited); 49 - setTimeout(() => setState(State.Idle), 6 * 1000); 50 } 51 52 if (res.ok) { 53 setState(State.Success); 54 - setTimeout(() => setState(State.Idle), 6 * 1000); 55 return; 56 } 57
··· 36 setError(null); 37 38 const res = await fetch(`${process.env.NEXT_PUBLIC_API}${url}`, { 39 + method, 40 credentials: "include", 41 headers: { 42 "Content-Type": "application/json" ··· 46 47 if (res.status === 429) { 48 setState(State.Ratelimited); 49 + setTimeout(() => setState(State.Idle), 6 * 1_000); 50 } 51 52 if (res.ok) { 53 setState(State.Success); 54 + setTimeout(() => setState(State.Idle), 6 * 1_000); 55 return; 56 } 57
+1 -2
components/comment.tsx
··· 1 import { Patrick_Hand } from "next/font/google"; 2 import Image, { type StaticImageData } from "next/image"; 3 import { HiChevronRight } from "react-icons/hi"; 4 - 5 - import { cn } from "@/utils/cn"; 6 7 const handwritten = Patrick_Hand({ subsets: ["latin"], weight: "400" }); 8
··· 1 + import { cn } from "@/utils/cn"; 2 import { Patrick_Hand } from "next/font/google"; 3 import Image, { type StaticImageData } from "next/image"; 4 import { HiChevronRight } from "react-icons/hi"; 5 6 const handwritten = Patrick_Hand({ subsets: ["latin"], weight: "400" }); 7
+1 -1
components/copy-to-clipboard.tsx
··· 25 setSaved(true); 26 27 if (timeoutRef.current) clearInterval(timeoutRef.current); 28 - timeoutRef.current = setTimeout(() => setSaved(false), 1000 * 2); 29 } 30 31 return (
··· 25 setSaved(true); 26 27 if (timeoutRef.current) clearInterval(timeoutRef.current); 28 + timeoutRef.current = setTimeout(() => setSaved(false), 1_000 * 2); 29 } 30 31 return (
+1 -1
components/counter.tsx
··· 51 const ref = useRef<NodeJS.Timeout | null>(null); 52 53 useEffect(() => { 54 - ref.current = setInterval(() => setWidth(window.innerWidth), 1000); 55 return () => { 56 if (ref.current) clearInterval(ref.current); 57 };
··· 51 const ref = useRef<NodeJS.Timeout | null>(null); 52 53 useEffect(() => { 54 + ref.current = setInterval(() => setWidth(window.innerWidth), 1_000); 55 return () => { 56 if (ref.current) clearInterval(ref.current); 57 };
+2 -3
components/dashboard/lists/hook.ts
··· 1 import { useParams, usePathname, useRouter, useSearchParams } from "next/navigation"; 2 import { useCallback } from "react"; 3 import { useQuery, useQueryClient } from "react-query"; 4 - 5 - import { cacheOptions, getData } from "@/lib/api"; 6 7 interface UseDataQueryOptions { 8 url: string; ··· 20 url, 21 () => getData<T[]>(url), 22 { 23 - enabled: !!params.guildId, 24 ...cacheOptions 25 } 26 );
··· 1 + import { cacheOptions, getData } from "@/lib/api"; 2 import { useParams, usePathname, useRouter, useSearchParams } from "next/navigation"; 3 import { useCallback } from "react"; 4 import { useQuery, useQueryClient } from "react-query"; 5 6 interface UseDataQueryOptions { 7 url: string; ··· 19 url, 20 () => getData<T[]>(url), 21 { 22 + enabled: Boolean(params.guildId), 23 ...cacheOptions 24 } 25 );
+2 -3
components/dashboard/lists/navigation.tsx
··· 1 "use client"; 2 3 import Link from "next/link"; 4 import { HiArrowLeft, HiExternalLink } from "react-icons/hi"; 5 - 6 - import { guildStore } from "@/common/guilds"; 7 - import { Button } from "@/components/ui/button"; 8 9 interface Props { 10 href: `/${string}`;
··· 1 "use client"; 2 3 + import { guildStore } from "@/common/guilds"; 4 + import { Button } from "@/components/ui/button"; 5 import Link from "next/link"; 6 import { HiArrowLeft, HiExternalLink } from "react-icons/hi"; 7 8 interface Props { 9 href: `/${string}`;
+2 -3
components/dashboard/lists/selector.tsx
··· 1 "use client"; 2 3 - import Link from "next/link"; 4 - import { HiExternalLink, HiPencil } from "react-icons/hi"; 5 - 6 import { type Guild, guildStore } from "@/common/guilds"; 7 import { Button } from "@/components/ui/button"; 8 import { cn } from "@/utils/cn"; 9 10 interface TBase { 11 id: string;
··· 1 "use client"; 2 3 import { type Guild, guildStore } from "@/common/guilds"; 4 import { Button } from "@/components/ui/button"; 5 import { cn } from "@/utils/cn"; 6 + import Link from "next/link"; 7 + import { HiExternalLink, HiPencil } from "react-icons/hi"; 8 9 interface TBase { 10 id: string;
+1 -2
components/discord/app-badge.tsx
··· 1 import type { HTMLProps } from "react"; 2 import { HiCheck } from "react-icons/hi"; 3 - 4 - import { cn } from "@/utils/cn"; 5 6 export default function DiscordAppBadge({ 7 className,
··· 1 + import { cn } from "@/utils/cn"; 2 import type { HTMLProps } from "react"; 3 import { HiCheck } from "react-icons/hi"; 4 5 export default function DiscordAppBadge({ 6 className,
+1 -2
components/discord/channel.tsx
··· 1 import React from "react"; 2 import { HiHashtag, HiVolumeUp } from "react-icons/hi"; 3 - 4 - import { cn } from "@/utils/cn"; 5 6 interface Props { 7 type: "text" | "voice";
··· 1 + import { cn } from "@/utils/cn"; 2 import React from "react"; 3 import { HiHashtag, HiVolumeUp } from "react-icons/hi"; 4 5 interface Props { 6 type: "text" | "voice";
+1 -3
components/discord/markdown.tsx
··· 1 import "./markdown.css"; 2 - 3 - import * as md from "@odiffey/discord-markdown"; 4 - 5 import { cn } from "@/utils/cn"; 6 7 export function DiscordMarkdown({ 8 text,
··· 1 import "./markdown.css"; 2 import { cn } from "@/utils/cn"; 3 + import * as md from "@odiffey/discord-markdown"; 4 5 export function DiscordMarkdown({ 6 text,
+1 -2
components/discord/message-embed.tsx
··· 1 /* eslint-disable @next/next/no-img-element */ 2 import React from "react"; 3 - 4 - import { cn } from "@/utils/cn"; 5 6 import { DiscordMarkdown } from "./markdown"; 7
··· 1 /* eslint-disable @next/next/no-img-element */ 2 + import { cn } from "@/utils/cn"; 3 import React from "react"; 4 5 import { DiscordMarkdown } from "./markdown"; 6
+4 -5
components/discord/message.tsx
··· 1 "use client"; 2 3 import React from "react"; 4 5 - import { cn } from "@/utils/cn"; 6 - 7 import { UserAvatar } from "../ui/avatar"; 8 - import DiscordAppBadge from "./app-badge"; 9 10 interface Props { 11 children: React.ReactNode; ··· 82 } 83 <time 84 className="mt-[2px] text-xs opacity-50 truncate" 85 - dateTime={new Date(1019060317).toISOString()} 86 > 87 - {formatTime(new Date(1019060317))} 88 </time> 89 </div> 90
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import React from "react"; 5 6 + import DiscordAppBadge from "./app-badge"; 7 import { UserAvatar } from "../ui/avatar"; 8 9 interface Props { 10 children: React.ReactNode; ··· 81 } 82 <time 83 className="mt-[2px] text-xs opacity-50 truncate" 84 + dateTime={new Date(1_019_060_317).toISOString()} 85 > 86 + {formatTime(new Date(1_019_060_317))} 87 </time> 88 </div> 89
+1 -1
components/discord/user.tsx
··· 1 import { cn } from "@/utils/cn"; 2 3 - import { UserAvatar } from "../ui/avatar"; 4 import DiscordAppBadge from "./app-badge"; 5 6 interface Props { 7 username: string;
··· 1 import { cn } from "@/utils/cn"; 2 3 import DiscordAppBadge from "./app-badge"; 4 + import { UserAvatar } from "../ui/avatar"; 5 6 interface Props { 7 username: string;
+5 -6
components/embed-creator.tsx
··· 1 import React, { useState } from "react"; 2 import { BiMoon, BiSun } from "react-icons/bi"; 3 import { FaFloppyDisk } from "react-icons/fa6"; 4 import { HiChevronDown, HiChevronUp } from "react-icons/hi"; 5 - 6 - import type { GuildEmbed } from "@/typings"; 7 - import { cn } from "@/utils/cn"; 8 9 import { DiscordMarkdown } from "./discord/markdown"; 10 import DiscordMessage from "./discord/message"; ··· 39 }; 40 41 disabled?: boolean; 42 - onSave?: (state: { content?: string | null; embed?: GuildEmbed; }) => void; 43 } 44 45 export default function MessageCreatorEmbed({ ··· 188 189 <div className="lg:w-3/6 m-1"> 190 191 - <DumbTextInput placeholder="Content" value={content} setValue={setContent} max={2000} disabled={disabled} /> 192 <DumbTextInput placeholder="Embed Title" value={embed} setValue={setEmbed} max={256} dataName="title" disabled={disabled} /> 193 - <DumbTextInput placeholder="Embed Description" value={embed} setValue={setEmbed} max={4096} dataName="description" disabled={disabled} /> 194 <div className="flex gap-2"> 195 <DumbColorInput placeholder="Embed Color" value={embed} setValue={setEmbed} dataName="color" disabled={disabled} /> 196 <DumbTextInput placeholder="Embed Thumbnail" value={embed} setValue={setEmbed} max={256} dataName="thumbnail" disabled={disabled} />
··· 1 + import type { GuildEmbed } from "@/typings"; 2 + import { cn } from "@/utils/cn"; 3 import React, { useState } from "react"; 4 import { BiMoon, BiSun } from "react-icons/bi"; 5 import { FaFloppyDisk } from "react-icons/fa6"; 6 import { HiChevronDown, HiChevronUp } from "react-icons/hi"; 7 8 import { DiscordMarkdown } from "./discord/markdown"; 9 import DiscordMessage from "./discord/message"; ··· 38 }; 39 40 disabled?: boolean; 41 + onSave?: (state: { content: string; embed: GuildEmbed; }) => void; 42 } 43 44 export default function MessageCreatorEmbed({ ··· 187 188 <div className="lg:w-3/6 m-1"> 189 190 + <DumbTextInput placeholder="Content" value={content} setValue={setContent} max={2_000} disabled={disabled} /> 191 <DumbTextInput placeholder="Embed Title" value={embed} setValue={setEmbed} max={256} dataName="title" disabled={disabled} /> 192 + <DumbTextInput placeholder="Embed Description" value={embed} setValue={setEmbed} max={4_096} dataName="description" disabled={disabled} /> 193 <div className="flex gap-2"> 194 <DumbColorInput placeholder="Embed Color" value={embed} setValue={setEmbed} dataName="color" disabled={disabled} /> 195 <DumbTextInput placeholder="Embed Thumbnail" value={embed} setValue={setEmbed} max={256} dataName="thumbnail" disabled={disabled} />
+6 -7
components/footer.tsx
··· 1 import Image from "next/image"; 2 import Link from "next/link"; 3 import type { HTMLProps } from "react"; ··· 7 import { HiBookOpen, HiCloud, HiCube, HiGlobe, HiHand, HiLibrary, HiUserAdd } from "react-icons/hi"; 8 import { SiDiscord, SiKofi } from "react-icons/si"; 9 10 - import TopggIcon from "@/components/icons/topgg"; 11 - import { getUser } from "@/lib/discord/user"; 12 - import BlahajPic from "@/public/blahaj.webp"; 13 - import { cn } from "@/utils/cn"; 14 - 15 import { Badge } from "./ui/badge"; 16 17 export async function Footer(props: HTMLProps<HTMLDivElement>) { ··· 38 <span className="flex gap-1 items-center"> 39 <BiCopyright /> 40 <span> 41 - <Link href="/" className="hover:underline">Wamellow {new Date(1635609600000).getFullYear()} - {new Date().getFullYear()}</Link>, 42 not affiliated with Discord Inc. 43 </span> 44 </span> ··· 80 alt="Blahaj" 81 src={BlahajPic} 82 height={Math.round(775 / 2)} 83 - width={1500 / 2} 84 /> 85 </Link> 86 </div>
··· 1 + import TopggIcon from "@/components/icons/topgg"; 2 + import { getUser } from "@/lib/discord/user"; 3 + import BlahajPic from "@/public/blahaj.webp"; 4 + import { cn } from "@/utils/cn"; 5 import Image from "next/image"; 6 import Link from "next/link"; 7 import type { HTMLProps } from "react"; ··· 11 import { HiBookOpen, HiCloud, HiCube, HiGlobe, HiHand, HiLibrary, HiUserAdd } from "react-icons/hi"; 12 import { SiDiscord, SiKofi } from "react-icons/si"; 13 14 import { Badge } from "./ui/badge"; 15 16 export async function Footer(props: HTMLProps<HTMLDivElement>) { ··· 37 <span className="flex gap-1 items-center"> 38 <BiCopyright /> 39 <span> 40 + <Link href="/" className="hover:underline">Wamellow {new Date(1_635_609_600_000).getFullYear()} - {new Date().getFullYear()}</Link>, 41 not affiliated with Discord Inc. 42 </span> 43 </span> ··· 79 alt="Blahaj" 80 src={BlahajPic} 81 height={Math.round(775 / 2)} 82 + width={1_500 / 2} 83 /> 84 </Link> 85 </div>
+21 -16
components/header.tsx
··· 1 "use client"; 2 3 import { AnimatePresence, motion, MotionConfig } from "framer-motion"; 4 import Link from "next/link"; 5 import { useRouter } from "next/navigation"; 6 import { useCookies } from "next-client-cookies"; 7 import { useCallback, useEffect, useMemo, useState } from "react"; 8 import { HiAdjustments, HiBeaker, HiChartPie, HiChevronDown, HiEyeOff, HiFire, HiIdentification, HiLogout, HiTrendingUp, HiViewGridAdd } from "react-icons/hi"; 9 - 10 - import { userStore } from "@/common/user"; 11 - import { webStore } from "@/common/webstore"; 12 - import { LoginButton } from "@/components/login-button"; 13 - import { authorize } from "@/utils/authorize-user"; 14 - import { cn } from "@/utils/cn"; 15 16 import ImageReduceMotion from "./image-reduce-motion"; 17 import { Button } from "./ui/button"; ··· 68 icon: <HiEyeOff />, 69 value: reduceMotions, 70 onChange: () => { 71 - if (!reduceMotions) cookies.set("reduceMotions", "true", { expires: 365 }); 72 - else cookies.remove("reduceMotions"); 73 router.refresh(); 74 } 75 }, ··· 101 icon: <HiBeaker />, 102 value: devTools, 103 onChange: () => { 104 - if (!devTools) cookies.set("devTools", "true", { expires: 365 }); 105 - else cookies.remove("devTools"); 106 router.refresh(); 107 } 108 } ··· 120 )} 121 onClick={() => setMenu(!menu)} 122 > 123 - {!user?.id ? 124 - <> 125 - <Skeleton className="rounded-full mr-2 size-[30p]" /> 126 - <Skeleton className="rounded-xl w-20 h-4" /> 127 - </> 128 - : 129 <> 130 <ImageReduceMotion 131 alt="your avatar" ··· 136 137 <p className="mr-1 relative bottom-[1px] truncate block text-primary-foreground font-medium tracking-tight">{user.globalName || user.username}</p> 138 <HiChevronDown /> 139 </> 140 } 141 </button>
··· 1 "use client"; 2 3 + import { userStore } from "@/common/user"; 4 + import { webStore } from "@/common/webstore"; 5 + import { LoginButton } from "@/components/login-button"; 6 + import { authorize } from "@/utils/authorize-user"; 7 + import { cn } from "@/utils/cn"; 8 import { AnimatePresence, motion, MotionConfig } from "framer-motion"; 9 import Link from "next/link"; 10 import { useRouter } from "next/navigation"; 11 import { useCookies } from "next-client-cookies"; 12 import { useCallback, useEffect, useMemo, useState } from "react"; 13 import { HiAdjustments, HiBeaker, HiChartPie, HiChevronDown, HiEyeOff, HiFire, HiIdentification, HiLogout, HiTrendingUp, HiViewGridAdd } from "react-icons/hi"; 14 15 import ImageReduceMotion from "./image-reduce-motion"; 16 import { Button } from "./ui/button"; ··· 67 icon: <HiEyeOff />, 68 value: reduceMotions, 69 onChange: () => { 70 + if (reduceMotions) { 71 + cookies.remove("reduceMotions"); 72 + } else { 73 + cookies.set("reduceMotions", "true", { expires: 365 }); 74 + } 75 router.refresh(); 76 } 77 }, ··· 103 icon: <HiBeaker />, 104 value: devTools, 105 onChange: () => { 106 + if (devTools) { 107 + cookies.remove("devTools"); 108 + } else { 109 + cookies.set("devTools", "true", { expires: 365 }); 110 + } 111 router.refresh(); 112 } 113 } ··· 125 )} 126 onClick={() => setMenu(!menu)} 127 > 128 + {user?.id ? 129 <> 130 <ImageReduceMotion 131 alt="your avatar" ··· 136 137 <p className="mr-1 relative bottom-[1px] truncate block text-primary-foreground font-medium tracking-tight">{user.globalName || user.username}</p> 138 <HiChevronDown /> 139 + </> 140 + : 141 + <> 142 + <Skeleton className="rounded-full mr-2 size-[30p]" /> 143 + <Skeleton className="rounded-xl w-20 h-4" /> 144 </> 145 } 146 </button>
+1 -2
components/image-grid.tsx
··· 1 import Image from "next/image"; 2 import Link from "next/link"; 3 - 4 - import { toFixedArrayLength } from "@/utils/fixed-array-length"; 5 6 import ImageReduceMotion from "./image-reduce-motion"; 7
··· 1 + import { toFixedArrayLength } from "@/utils/fixed-array-length"; 2 import Image from "next/image"; 3 import Link from "next/link"; 4 5 import ImageReduceMotion from "./image-reduce-motion"; 6
-1
components/image-reduce-motion.tsx
··· 2 import Image from "next/image"; 3 import { useCookies } from "next-client-cookies"; 4 5 - 6 interface Props { 7 url: string | null | undefined; 8 size: number;
··· 2 import Image from "next/image"; 3 import { useCookies } from "next-client-cookies"; 4 5 interface Props { 6 url: string | null | undefined; 7 size: number;
+7 -9
components/inputs/color-input.tsx
··· 1 import { useEffect, useState } from "react"; 2 import { TailSpin } from "react-loading-icons"; 3 4 - import type { ApiError } from "@/typings"; 5 - 6 - import { useStateDebounced } from "../../utils/useDebounce"; 7 import DumbColorInput from "./dumb-color-input"; 8 9 enum State { 10 Idle = 0, ··· 26 onSave?: (value: string | number) => void; 27 } 28 29 - 30 export default function ColorInput({ 31 name, 32 url, ··· 41 const [state, setState] = useState<State>(State.Idle); 42 const [error, setError] = useState<string | null>(null); 43 44 - const [valuedebounced, setValuedebounced] = useStateDebounced<string | number>("", 1000); 45 const [value, setValue] = useState<string | number>(""); 46 const [defaultStatealue, setdefaultStatealue] = useState<string | number>(""); 47 ··· 61 headers: { 62 "Content-Type": "application/json" 63 }, 64 - body: JSON.stringify({ [dataName]: value || 0x000000 }) 65 }) 66 .then(async (res) => { 67 const response = await res.json(); ··· 69 70 switch (res.status) { 71 case 200: { 72 - setValue(value || 0x000000); 73 - onSave?.(value || 0x000000); 74 - setdefaultStatealue(value || 0x000000); 75 76 setState(State.Success); 77 setTimeout(() => setState(State.Idle), 1_000 * 8);
··· 1 + import type { ApiError } from "@/typings"; 2 import { useEffect, useState } from "react"; 3 import { TailSpin } from "react-loading-icons"; 4 5 import DumbColorInput from "./dumb-color-input"; 6 + import { useStateDebounced } from "../../utils/useDebounce"; 7 8 enum State { 9 Idle = 0, ··· 25 onSave?: (value: string | number) => void; 26 } 27 28 export default function ColorInput({ 29 name, 30 url, ··· 39 const [state, setState] = useState<State>(State.Idle); 40 const [error, setError] = useState<string | null>(null); 41 42 + const [valuedebounced, setValuedebounced] = useStateDebounced<string | number>("", 1_000); 43 const [value, setValue] = useState<string | number>(""); 44 const [defaultStatealue, setdefaultStatealue] = useState<string | number>(""); 45 ··· 59 headers: { 60 "Content-Type": "application/json" 61 }, 62 + body: JSON.stringify({ [dataName]: value || 0x00_00_00 }) 63 }) 64 .then(async (res) => { 65 const response = await res.json(); ··· 67 68 switch (res.status) { 69 case 200: { 70 + setValue(value || 0x00_00_00); 71 + onSave?.(value || 0x00_00_00); 72 + setdefaultStatealue(value || 0x00_00_00); 73 74 setState(State.Success); 75 setTimeout(() => setState(State.Idle), 1_000 * 8);
+7 -6
components/inputs/dumb-color-input.tsx
··· 1 import { AnimatePresence, motion } from "framer-motion"; 2 import React, { useEffect, useState } from "react"; 3 import { AiOutlineEdit } from "react-icons/ai"; 4 - 5 - import { cn } from "@/utils/cn"; 6 7 interface Props { 8 name?: string; 9 placeholder?: string; 10 11 // eslint-disable-next-line @typescript-eslint/no-explicit-any 12 - value: any; setValue: React.Dispatch<React.SetStateAction<any>>; 13 14 disabled?: boolean; 15 description?: string; ··· 38 // this cuz there can be multiple color inputs on the same page, so it will bug, so we need to identify them 39 const [inputId, setInputId] = useState<string>(""); 40 useEffect(() => { 41 - setInputId(Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)); 42 }, []); 43 44 const [isHovered, setIsHovered] = useState<boolean>(false); ··· 57 placeholder={placeholder} 58 onChange={(e) => { 59 if (dataName) { 60 - setValue(JSON.stringify(Object.assign(JSON.parse(value), { [dataName]: parseInt(e.target.value.slice(1), 16) }))); 61 } else { 62 - setValue(parseInt(e.target.value.slice(1), 16)); 63 } 64 }} 65 value={(dataName ? JSON.parse(value)[dataName] : value) ? `#${(dataName ? JSON.parse(value)[dataName] : value)?.toString(16)}` : "#ffffff"}
··· 1 + import { cn } from "@/utils/cn"; 2 import { AnimatePresence, motion } from "framer-motion"; 3 import React, { useEffect, useState } from "react"; 4 import { AiOutlineEdit } from "react-icons/ai"; 5 6 interface Props { 7 name?: string; 8 placeholder?: string; 9 10 // eslint-disable-next-line @typescript-eslint/no-explicit-any 11 + value: any; 12 + // eslint-disable-next-line @typescript-eslint/no-explicit-any 13 + setValue: React.Dispatch<React.SetStateAction<any>>; 14 15 disabled?: boolean; 16 description?: string; ··· 39 // this cuz there can be multiple color inputs on the same page, so it will bug, so we need to identify them 40 const [inputId, setInputId] = useState<string>(""); 41 useEffect(() => { 42 + setInputId(Math.random().toString(36).slice(2, 15) + Math.random().toString(36).slice(2, 15)); 43 }, []); 44 45 const [isHovered, setIsHovered] = useState<boolean>(false); ··· 58 placeholder={placeholder} 59 onChange={(e) => { 60 if (dataName) { 61 + setValue(JSON.stringify(Object.assign(JSON.parse(value), { [dataName]: Number.parseInt(e.target.value.slice(1), 16) }))); 62 } else { 63 + setValue(Number.parseInt(e.target.value.slice(1), 16)); 64 } 65 }} 66 value={(dataName ? JSON.parse(value)[dataName] : value) ? `#${(dataName ? JSON.parse(value)[dataName] : value)?.toString(16)}` : "#ffffff"}
+5 -4
components/inputs/dumb-text-input.tsx
··· 1 import React, { useEffect, useState } from "react"; 2 - 3 - import { cn } from "@/utils/cn"; 4 5 interface Props { 6 name?: string; 7 placeholder?: string; 8 9 // eslint-disable-next-line @typescript-eslint/no-explicit-any 10 - value: any; setValue: React.Dispatch<React.SetStateAction<any>>; 11 12 disabled?: boolean; 13 description?: string; ··· 71 type="color" 72 value={`#${(dataName ? JSON.parse(value)[dataName] : value)?.toString(16)}`} 73 onChange={(e) => { 74 - const color = parseInt(e.target.value.replace(/#/, ""), 16); 75 76 if (dataName) { 77 setValue(JSON.stringify(Object.assign(JSON.parse(value), { [dataName]: color || null })));
··· 1 + import { cn } from "@/utils/cn"; 2 import React, { useEffect, useState } from "react"; 3 4 interface Props { 5 name?: string; 6 placeholder?: string; 7 8 // eslint-disable-next-line @typescript-eslint/no-explicit-any 9 + value: any; 10 + // eslint-disable-next-line @typescript-eslint/no-explicit-any 11 + setValue: React.Dispatch<React.SetStateAction<any>>; 12 13 disabled?: boolean; 14 description?: string; ··· 72 type="color" 73 value={`#${(dataName ? JSON.parse(value)[dataName] : value)?.toString(16)}`} 74 onChange={(e) => { 75 + const color = Number.parseInt(e.target.value.replace(/#/, ""), 16); 76 77 if (dataName) { 78 setValue(JSON.stringify(Object.assign(JSON.parse(value), { [dataName]: color || null })));
+2 -3
components/inputs/image-url-input.tsx
··· 1 import { useEffect, useState } from "react"; 2 import { TailSpin } from "react-loading-icons"; 3 - 4 - import type { ApiError } from "@/typings"; 5 - import { cn } from "@/utils/cn"; 6 7 import DumbTextInput from "./dumb-text-input"; 8
··· 1 + import type { ApiError } from "@/typings"; 2 + import { cn } from "@/utils/cn"; 3 import { useEffect, useState } from "react"; 4 import { TailSpin } from "react-loading-icons"; 5 6 import DumbTextInput from "./dumb-text-input"; 7
+6 -7
components/inputs/multi-select-menu.tsx
··· 1 import { useEffect, useState } from "react"; 2 import { HiCheck, HiChevronDown, HiExclamationCircle, HiX } from "react-icons/hi"; 3 import { TailSpin } from "react-loading-icons"; 4 - 5 - import type { ApiError } from "@/typings"; 6 - import { cn } from "@/utils/cn"; 7 8 import { ClickOutside } from "../click-outside"; 9 ··· 63 }, [defaultState, items]); 64 65 useEffect(() => { 66 - if (values.find((v) => !!v.error) || JSON.stringify(values.map((v) => v.value)) === JSON.stringify(defaultvalue)) { 67 setState(State.Idle); 68 return; 69 } ··· 129 className={cn( 130 "mt-1 min-h-12 w-full bg-wamellow rounded-lg flex items-center px-3 duration-100 wamellow-modal", 131 open && "outline outline-violet-400 outline-2", 132 - (values.find((v) => !!v.error) || error) && !open && "outline outline-red-500 outline-1", 133 state === State.Success && !open && "outline outline-green-500 outline-1", 134 (state === State.Loading || disabled) && "cursor-not-allowed opacity-50" 135 )} ··· 168 ))} 169 </div> 170 <div className="ml-auto flex items-center gap-2"> 171 - {values.find((v) => !!v.error) && 172 <div className="text-sm flex items-center gap-1 text-red-500"> 173 <HiExclamationCircle /> {values.find((v) => v.error)?.error} 174 </div> ··· 196 onClick={() => { 197 setState(State.Idle); 198 setValues((v) => { 199 - if (v.length >= max || v.find((i) => i.value === item.value)) return v.filter((i) => i.value !== item.value); 200 return [...v, item]; 201 }); 202 }}
··· 1 + import type { ApiError } from "@/typings"; 2 + import { cn } from "@/utils/cn"; 3 import { useEffect, useState } from "react"; 4 import { HiCheck, HiChevronDown, HiExclamationCircle, HiX } from "react-icons/hi"; 5 import { TailSpin } from "react-loading-icons"; 6 7 import { ClickOutside } from "../click-outside"; 8 ··· 62 }, [defaultState, items]); 63 64 useEffect(() => { 65 + if (values.some((v) => Boolean(v.error)) || JSON.stringify(values.map((v) => v.value)) === JSON.stringify(defaultvalue)) { 66 setState(State.Idle); 67 return; 68 } ··· 128 className={cn( 129 "mt-1 min-h-12 w-full bg-wamellow rounded-lg flex items-center px-3 duration-100 wamellow-modal", 130 open && "outline outline-violet-400 outline-2", 131 + (values.some((v) => Boolean(v.error)) || error) && !open && "outline outline-red-500 outline-1", 132 state === State.Success && !open && "outline outline-green-500 outline-1", 133 (state === State.Loading || disabled) && "cursor-not-allowed opacity-50" 134 )} ··· 167 ))} 168 </div> 169 <div className="ml-auto flex items-center gap-2"> 170 + {values.some((v) => Boolean(v.error)) && 171 <div className="text-sm flex items-center gap-1 text-red-500"> 172 <HiExclamationCircle /> {values.find((v) => v.error)?.error} 173 </div> ··· 195 onClick={() => { 196 setState(State.Idle); 197 setValues((v) => { 198 + if (v.length >= max || v.some((i) => i.value === item.value)) return v.filter((i) => i.value !== item.value); 199 return [...v, item]; 200 }); 201 }}
+4 -5
components/inputs/number-input.tsx
··· 1 import { Button } from "@nextui-org/react"; 2 import { useEffect, useRef, useState } from "react"; 3 import { HiMinus, HiPlus } from "react-icons/hi"; 4 import { TailSpin } from "react-loading-icons"; 5 - 6 - import { webStore } from "@/common/webstore"; 7 - import type { ApiError } from "@/typings"; 8 - import { cn } from "@/utils/cn"; 9 10 enum State { 11 Idle = 0, ··· 206 (state === State.Loading || disabled) ? "cursor-not-allowed" : "cursor-text" 207 )} 208 onChange={(e) => { 209 - if (/^[0-9]+$/.test(e.target.value) || !e.target.value) setValue(e.target.value ? parseInt(e.target.value) : undefined); 210 }} 211 value={value} 212 disabled={state === State.Loading || disabled}
··· 1 + import { webStore } from "@/common/webstore"; 2 + import type { ApiError } from "@/typings"; 3 + import { cn } from "@/utils/cn"; 4 import { Button } from "@nextui-org/react"; 5 import { useEffect, useRef, useState } from "react"; 6 import { HiMinus, HiPlus } from "react-icons/hi"; 7 import { TailSpin } from "react-loading-icons"; 8 9 enum State { 10 Idle = 0, ··· 205 (state === State.Loading || disabled) ? "cursor-not-allowed" : "cursor-text" 206 )} 207 onChange={(e) => { 208 + if (/^\d+$/.test(e.target.value) || !e.target.value) setValue(e.target.value ? Number.parseInt(e.target.value, 10) : undefined); 209 }} 210 value={value} 211 disabled={state === State.Loading || disabled}
+2 -3
components/inputs/select-menu.tsx
··· 1 import { useEffect, useState } from "react"; 2 import { HiCheck, HiChevronDown, HiExclamationCircle, HiX } from "react-icons/hi"; 3 import { TailSpin } from "react-loading-icons"; 4 - 5 - import type { ApiError } from "@/typings"; 6 - import { cn } from "@/utils/cn"; 7 8 import { ClickOutside } from "../click-outside"; 9
··· 1 + import type { ApiError } from "@/typings"; 2 + import { cn } from "@/utils/cn"; 3 import { useEffect, useState } from "react"; 4 import { HiCheck, HiChevronDown, HiExclamationCircle, HiX } from "react-icons/hi"; 5 import { TailSpin } from "react-loading-icons"; 6 7 import { ClickOutside } from "../click-outside"; 8
+2 -4
components/inputs/switch.tsx
··· 1 import Link from "next/link"; 2 import { TailSpin } from "react-loading-icons"; 3 - 4 - import { cn } from "@/utils/cn"; 5 - import { type InputProps, InputState, useInput } from "@/utils/input"; 6 7 import { Badge } from "../ui/badge"; 8 import { Checkbox } from "../ui/checkbox"; ··· 87 /> 88 } 89 </div> 90 - 91 92 <div className="absolute top-6 mt-0.5"> 93 {description &&
··· 1 + import { cn } from "@/utils/cn"; 2 + import { type InputProps, InputState, useInput } from "@/utils/input"; 3 import Link from "next/link"; 4 import { TailSpin } from "react-loading-icons"; 5 6 import { Badge } from "../ui/badge"; 7 import { Checkbox } from "../ui/checkbox"; ··· 86 /> 87 } 88 </div> 89 90 <div className="absolute top-6 mt-0.5"> 91 {description &&
+19 -19
components/inputs/text-input.tsx
··· 1 "use client"; 2 3 import { useEffect, useState } from "react"; 4 import { TailSpin } from "react-loading-icons"; 5 6 - import type { ApiError } from "@/typings"; 7 - import { cn } from "@/utils/cn"; 8 - 9 - import { useStateDebounced } from "../../utils/useDebounce"; 10 import DumbTextInput from "./dumb-text-input"; 11 12 enum State { 13 Idle = 0, ··· 15 Success = 2 16 } 17 18 - interface Props { 19 className?: string; 20 21 name?: string; ··· 23 dataName?: string; 24 disabled?: boolean; 25 description?: string; 26 - defaultState: string | number; 27 - resetState?: string | number; 28 29 - type?: string; 30 max?: number; 31 placeholder?: string; 32 33 - onSave?: (value: string | number | null) => void; 34 } 35 36 - export default function TextInput({ 37 className, 38 name, 39 url, ··· 42 description, 43 defaultState, 44 resetState, 45 - type, 46 max, 47 placeholder, 48 onSave 49 - }: Props) { 50 const [state, setState] = useState<State>(State.Idle); 51 const [error, setError] = useState<string | null>(null); 52 53 - const [valuedebounced, setValueDebounced] = useStateDebounced<string | number>("", 1000); 54 - const [value, setValue] = useState<string | number>(""); 55 - const [defaultStateValue, setdefaultStateValue] = useState<string | number>(""); 56 57 useEffect(() => { 58 if (!defaultStateValue) setdefaultStateValue(defaultState); ··· 93 94 switch (res.status) { 95 case 200: { 96 - setValue(value || def || ""); 97 - onSave?.(value || def); 98 - setdefaultStateValue(value || def || ""); 99 100 setState(State.Success); 101 setTimeout(() => setState(State.Idle), 1_000 * 8); ··· 151 type={type} 152 description={description} 153 /> 154 - 155 156 <div className="flex absolute right-0 bottom-0"> 157 {error &&
··· 1 "use client"; 2 3 + import type { ApiError } from "@/typings"; 4 + import { cn } from "@/utils/cn"; 5 import { useEffect, useState } from "react"; 6 import { TailSpin } from "react-loading-icons"; 7 8 import DumbTextInput from "./dumb-text-input"; 9 + import { useStateDebounced } from "../../utils/useDebounce"; 10 + 11 + type Type<T extends "text" | "color"> = T extends "text" ? string : number; 12 13 enum State { 14 Idle = 0, ··· 16 Success = 2 17 } 18 19 + interface Props<T extends "text" | "color"> { 20 className?: string; 21 22 name?: string; ··· 24 dataName?: string; 25 disabled?: boolean; 26 description?: string; 27 + defaultState: Type<T>; 28 + resetState?: Type<T>; 29 30 + type?: T; 31 max?: number; 32 placeholder?: string; 33 34 + onSave?: (value: Type<T> | null) => void; 35 } 36 37 + export default function TextInput<T extends "text" | "color" = "text">({ 38 className, 39 name, 40 url, ··· 43 description, 44 defaultState, 45 resetState, 46 + type = "text" as T, 47 max, 48 placeholder, 49 onSave 50 + }: Props<T>) { 51 const [state, setState] = useState<State>(State.Idle); 52 const [error, setError] = useState<string | null>(null); 53 54 + const [valuedebounced, setValueDebounced] = useStateDebounced<T extends "text" ? string : number>((type === "text" ? "" : 0) as Type<T>, 1_000); 55 + const [value, setValue] = useState<T extends "text" ? string : number>((type === "text" ? "" : 0) as Type<T>); 56 + const [defaultStateValue, setdefaultStateValue] = useState<T extends "text" ? string : number>((type === "text" ? "" : 0) as Type<T>); 57 58 useEffect(() => { 59 if (!defaultStateValue) setdefaultStateValue(defaultState); ··· 94 95 switch (res.status) { 96 case 200: { 97 + setValue(value || def || (type === "text" ? "" : 0) as Type<T>); 98 + onSave?.(value || def || (type === "text" ? "" : 0) as Type<T>); 99 + setdefaultStateValue(value || def || (type === "text" ? "" : 0) as Type<T>); 100 101 setState(State.Success); 102 setTimeout(() => setState(State.Idle), 1_000 * 8); ··· 152 type={type} 153 description={description} 154 /> 155 156 <div className="flex absolute right-0 bottom-0"> 157 {error &&
+1 -2
components/list.tsx
··· 1 "use client"; 2 3 import { Tab, Tabs } from "@nextui-org/react"; 4 import { usePathname, useRouter, useSearchParams } from "next/navigation"; 5 import React, { useEffect, useRef, useState } from "react"; 6 import { HiChevronLeft, HiChevronRight } from "react-icons/hi"; 7 - 8 - import decimalToRgb from "@/utils/decimalToRgb"; 9 10 interface ListProps { 11 tabs: {
··· 1 "use client"; 2 3 + import decimalToRgb from "@/utils/decimalToRgb"; 4 import { Tab, Tabs } from "@nextui-org/react"; 5 import { usePathname, useRouter, useSearchParams } from "next/navigation"; 6 import React, { useEffect, useRef, useState } from "react"; 7 import { HiChevronLeft, HiChevronRight } from "react-icons/hi"; 8 9 interface ListProps { 10 tabs: {
+1 -2
components/loading-circle.tsx
··· 1 import { LoaderCircleIcon } from "lucide-react"; 2 - 3 - import { cn } from "@/utils/cn"; 4 5 export function LoadingCircle({ className = "" }: { className?: string; }) { 6 return (
··· 1 + import { cn } from "@/utils/cn"; 2 import { LoaderCircleIcon } from "lucide-react"; 3 4 export function LoadingCircle({ className = "" }: { className?: string; }) { 5 return (
+4 -5
components/login-button.tsx
··· 1 "use client"; 2 3 import { Lexend } from "next/font/google"; 4 import Link from "next/link"; 5 import { BsDiscord } from "react-icons/bs"; 6 import { HiExclamation } from "react-icons/hi"; 7 - 8 - import { cn } from "@/utils/cn"; 9 10 import { Button } from "./ui/button"; 11 ··· 41 prefetch={false} 42 > 43 <Icon state={state} /> 44 - {!state ? 45 <span className={cn(lexend.className, "font-semibold")}> 46 {message || 47 <> ··· 50 </> 51 } 52 </span> 53 - : 54 - <span>Authorization failed</span> 55 } 56 </Link> 57 </Button>
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import { Lexend } from "next/font/google"; 5 import Link from "next/link"; 6 import { BsDiscord } from "react-icons/bs"; 7 import { HiExclamation } from "react-icons/hi"; 8 9 import { Button } from "./ui/button"; 10 ··· 40 prefetch={false} 41 > 42 <Icon state={state} /> 43 + {state ? 44 + <span>Authorization failed</span> 45 + : 46 <span className={cn(lexend.className, "font-semibold")}> 47 {message || 48 <> ··· 51 </> 52 } 53 </span> 54 } 55 </Link> 56 </Button>
+18 -21
components/markdown/index.tsx
··· 1 /* eslint-disable @typescript-eslint/no-unused-vars */ 2 3 import { Code } from "@nextui-org/react"; 4 import Link from "next/link"; 5 import type { ReactNode } from "react"; ··· 7 import ReactMarkdown from "react-markdown"; 8 import rehypeRaw from "rehype-raw"; 9 10 - import { getUser } from "@/lib/discord/user"; 11 - import { cn } from "@/utils/cn"; 12 - import { filterDuplicates } from "@/utils/filter-duplicates"; 13 - import { getBaseUrl } from "@/utils/urls"; 14 - 15 - import Notice, { NoticeType } from "../notice"; 16 - import { Separator } from "../ui/separator"; 17 import Channel from "./channel"; 18 import Emoji from "./emoji"; 19 import Timestamp from "./timestamp"; 20 import User from "./user"; 21 22 const ALLOWED_IFRAMES = [ 23 "https://www.youtube.com/embed/", ··· 37 async function parseDiscordMarkdown(content: string) { 38 const users = await Promise.all( 39 filterDuplicates(content.match(/<@!?\d{15,21}>/g) || []) 40 - .map((match) => match.replace(/<|!|>|@/g, "")) 41 .map((userId) => getUser(userId)) 42 ); 43 ··· 49 return renderToString(<Emoji emojiId={emojiId} />); 50 }) 51 .replace(/<(@!?)\d{15,21}>/g, (match) => { 52 - const userId = match.replace(/<|!|>|@/g, ""); 53 const username = users.find((user) => user?.id === userId)?.username || "user"; 54 55 return renderToString(<User username={username} />); ··· 66 67 return renderToString( 68 <Timestamp 69 - unix={parseInt(timestamp)} 70 format={format.slice(1, -1)} 71 /> 72 ); 73 }); 74 } 75 76 - function createHId(text: ReactNode) { 77 - return text 78 - ?.toString() 79 - .toLowerCase() 80 - .replace("[object object],[object object],", "") 81 - .replace(EMOJI_REGEX, "") 82 - .trim() 83 - .replace(/ +/g, "-"); 84 - } 85 - 86 return ( 87 <ReactMarkdown 88 rehypePlugins={[rehypeRaw]} ··· 121 del: (props) => <span className="line-through" {...props} />, 122 ins: (props) => <span className="underline" {...props} />, 123 124 - // eslint-disable-next-line unused-imports/no-unused-vars 125 code: ({ ref, color, ...props }) => { 126 return <Code color="secondary" {...props} />; 127 }, ··· 194 {await parseDiscordMarkdown(markdown)} 195 </ReactMarkdown> 196 ); 197 198 }
··· 1 /* eslint-disable @typescript-eslint/no-unused-vars */ 2 3 + import { getUser } from "@/lib/discord/user"; 4 + import { cn } from "@/utils/cn"; 5 + import { filterDuplicates } from "@/utils/filter-duplicates"; 6 + import { getBaseUrl } from "@/utils/urls"; 7 import { Code } from "@nextui-org/react"; 8 import Link from "next/link"; 9 import type { ReactNode } from "react"; ··· 11 import ReactMarkdown from "react-markdown"; 12 import rehypeRaw from "rehype-raw"; 13 14 import Channel from "./channel"; 15 import Emoji from "./emoji"; 16 import Timestamp from "./timestamp"; 17 import User from "./user"; 18 + import Notice, { NoticeType } from "../notice"; 19 + import { Separator } from "../ui/separator"; 20 21 const ALLOWED_IFRAMES = [ 22 "https://www.youtube.com/embed/", ··· 36 async function parseDiscordMarkdown(content: string) { 37 const users = await Promise.all( 38 filterDuplicates(content.match(/<@!?\d{15,21}>/g) || []) 39 + .map((match) => match.replace(/[!<>@]/g, "")) 40 .map((userId) => getUser(userId)) 41 ); 42 ··· 48 return renderToString(<Emoji emojiId={emojiId} />); 49 }) 50 .replace(/<(@!?)\d{15,21}>/g, (match) => { 51 + const userId = match.replace(/[!<>@]/g, ""); 52 const username = users.find((user) => user?.id === userId)?.username || "user"; 53 54 return renderToString(<User username={username} />); ··· 65 66 return renderToString( 67 <Timestamp 68 + unix={Number.parseInt(timestamp, 10)} 69 format={format.slice(1, -1)} 70 /> 71 ); 72 }); 73 } 74 75 return ( 76 <ReactMarkdown 77 rehypePlugins={[rehypeRaw]} ··· 110 del: (props) => <span className="line-through" {...props} />, 111 ins: (props) => <span className="underline" {...props} />, 112 113 code: ({ ref, color, ...props }) => { 114 return <Code color="secondary" {...props} />; 115 }, ··· 182 {await parseDiscordMarkdown(markdown)} 183 </ReactMarkdown> 184 ); 185 + } 186 187 + function createHId(text: ReactNode) { 188 + return text 189 + ?.toString() 190 + .toLowerCase() 191 + .replace("[object object],[object object],", "") 192 + .replace(EMOJI_REGEX, "") 193 + .trim() 194 + .replace(/ +/g, "-"); 195 }
+1 -1
components/markdown/timestamp.tsx
··· 7 unix: number; 8 format: string; 9 }) { 10 - const date = new Date(unix * 1000); 11 const str = getDateString(date, format); 12 13 return (
··· 7 unix: number; 8 format: string; 9 }) { 10 + const date = new Date(unix * 1_000); 11 const str = getDateString(date, format); 12 13 return (
+10 -5
components/modal.tsx
··· 1 "use client"; 2 3 import Link from "next/link"; 4 import { useEffect, useState } from "react"; 5 import { HiFire } from "react-icons/hi"; 6 - 7 - import type { ApiError } from "@/typings"; 8 - import { cn } from "@/utils/cn"; 9 10 import Notice, { NoticeType } from "./notice"; 11 import { Badge } from "./ui/badge"; ··· 64 65 async function submit() { 66 if (state === State.Loading) return; 67 - if (!onSubmit) return onClose(); 68 69 setError(null); 70 setState(State.Loading); 71 const data = onSubmit?.(); 72 73 - if (!data) return onClose(); 74 75 if (data instanceof Error) { 76 setError(data?.message || "something went wrong..");
··· 1 "use client"; 2 3 + import type { ApiError } from "@/typings"; 4 + import { cn } from "@/utils/cn"; 5 import Link from "next/link"; 6 import { useEffect, useState } from "react"; 7 import { HiFire } from "react-icons/hi"; 8 9 import Notice, { NoticeType } from "./notice"; 10 import { Badge } from "./ui/badge"; ··· 63 64 async function submit() { 65 if (state === State.Loading) return; 66 + if (!onSubmit) { 67 + onClose(); 68 + return; 69 + } 70 71 setError(null); 72 setState(State.Loading); 73 const data = onSubmit?.(); 74 75 + if (!data) { 76 + onClose(); 77 + return; 78 + } 79 80 if (data instanceof Error) { 81 setError(data?.message || "something went wrong..");
+2 -3
components/screen-message.tsx
··· 1 import Image from "next/image"; 2 import Link from "next/link"; 3 import { BsDiscord } from "react-icons/bs"; 4 import { HiHome } from "react-icons/hi"; 5 - 6 - import SadWumpusPic from "@/public/sad-wumpus.gif"; 7 - import { cn } from "@/utils/cn"; 8 9 import { Button } from "./ui/button"; 10
··· 1 + import SadWumpusPic from "@/public/sad-wumpus.gif"; 2 + import { cn } from "@/utils/cn"; 3 import Image from "next/image"; 4 import Link from "next/link"; 5 import { BsDiscord } from "react-icons/bs"; 6 import { HiHome } from "react-icons/hi"; 7 8 import { Button } from "./ui/button"; 9
+2 -2
components/time.tsx
··· 15 return `Today at ${dateFormatter.format(date)}`; 16 } else if (date.toDateString() === yesterday.toDateString()) { 17 return `Yesterday at ${dateFormatter.format(date)}`; 18 - } else { 19 - return date.toLocaleDateString(userLanguage); 20 } 21 }
··· 15 return `Today at ${dateFormatter.format(date)}`; 16 } else if (date.toDateString() === yesterday.toDateString()) { 17 return `Yesterday at ${dateFormatter.format(date)}`; 18 } 19 + return date.toLocaleDateString(userLanguage); 20 + 21 }
+1 -2
components/ui/alert.tsx
··· 1 import { cva, type VariantProps } from "class-variance-authority"; 2 import * as React from "react"; 3 - 4 - import { cn } from "@/utils/cn"; 5 6 const alertVariants = cva( 7 "relative w-full rounded-lg p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-2px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-[17px] [&>svg]:text-foreground",
··· 1 + import { cn } from "@/utils/cn"; 2 import { cva, type VariantProps } from "class-variance-authority"; 3 import * as React from "react"; 4 5 const alertVariants = cva( 6 "relative w-full rounded-lg p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-2px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-[17px] [&>svg]:text-foreground",
+1 -2
components/ui/avatar.tsx
··· 1 "use client"; 2 3 import * as AvatarPrimitive from "@radix-ui/react-avatar"; 4 import * as React from "react"; 5 - 6 - import { cn } from "@/utils/cn"; 7 8 const Avatar = React.forwardRef< 9 React.ElementRef<typeof AvatarPrimitive.Root>,
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import * as AvatarPrimitive from "@radix-ui/react-avatar"; 5 import * as React from "react"; 6 7 const Avatar = React.forwardRef< 8 React.ElementRef<typeof AvatarPrimitive.Root>,
+1 -2
components/ui/badge.tsx
··· 1 import { cva, type VariantProps } from "class-variance-authority"; 2 import * as React from "react"; 3 - 4 - import { cn } from "@/utils/cn"; 5 6 const badgeVariants = cva( 7 "w-fit inline-flex items-center border font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 [&>svg]:relative [&>svg]:right-1",
··· 1 + import { cn } from "@/utils/cn"; 2 import { cva, type VariantProps } from "class-variance-authority"; 3 import * as React from "react"; 4 5 const badgeVariants = cva( 6 "w-fit inline-flex items-center border font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 [&>svg]:relative [&>svg]:right-1",
+1 -2
components/ui/button.tsx
··· 1 import { Slot } from "@radix-ui/react-slot"; 2 import { cva, type VariantProps } from "class-variance-authority"; 3 import Link from "next/link"; 4 import * as React from "react"; 5 - 6 - import { cn } from "@/utils/cn"; 7 8 import { LoadingCircle } from "../loading-circle"; 9
··· 1 + import { cn } from "@/utils/cn"; 2 import { Slot } from "@radix-ui/react-slot"; 3 import { cva, type VariantProps } from "class-variance-authority"; 4 import Link from "next/link"; 5 import * as React from "react"; 6 7 import { LoadingCircle } from "../loading-circle"; 8
+1 -2
components/ui/checkbox.tsx
··· 1 "use client"; 2 3 import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; 4 import { Check } from "lucide-react"; 5 import * as React from "react"; 6 - 7 - import { cn } from "@/utils/cn"; 8 9 const Checkbox = React.forwardRef< 10 React.ElementRef<typeof CheckboxPrimitive.Root>,
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; 5 import { Check } from "lucide-react"; 6 import * as React from "react"; 7 8 const Checkbox = React.forwardRef< 9 React.ElementRef<typeof CheckboxPrimitive.Root>,
+1 -2
components/ui/dialog.tsx
··· 1 "use client"; 2 3 import * as DialogPrimitive from "@radix-ui/react-dialog"; 4 import { X } from "lucide-react"; 5 import * as React from "react"; 6 - 7 - import { cn } from "@/utils/cn"; 8 9 const Dialog = DialogPrimitive.Root; 10
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import * as DialogPrimitive from "@radix-ui/react-dialog"; 5 import { X } from "lucide-react"; 6 import * as React from "react"; 7 8 const Dialog = DialogPrimitive.Root; 9
+2 -3
components/ui/input-base.tsx
··· 1 "use client"; 2 3 import { composeEventHandlers } from "@radix-ui/primitive"; 4 import { useComposedRefs } from "@radix-ui/react-compose-refs"; 5 import { Primitive } from "@radix-ui/react-primitive"; 6 import { Slot } from "@radix-ui/react-slot"; 7 import * as React from "react"; 8 - 9 - import { Button } from "@/components/ui/button"; 10 - import { cn } from "@/utils/cn"; 11 12 export type InputBaseContextProps = Pick< 13 InputBaseProps,
··· 1 "use client"; 2 3 + import { Button } from "@/components/ui/button"; 4 + import { cn } from "@/utils/cn"; 5 import { composeEventHandlers } from "@radix-ui/primitive"; 6 import { useComposedRefs } from "@radix-ui/react-compose-refs"; 7 import { Primitive } from "@radix-ui/react-primitive"; 8 import { Slot } from "@radix-ui/react-slot"; 9 import * as React from "react"; 10 11 export type InputBaseContextProps = Pick< 12 InputBaseProps,
+1 -2
components/ui/popover.tsx
··· 1 "use client"; 2 3 import * as PopoverPrimitive from "@radix-ui/react-popover"; 4 import * as React from "react"; 5 - 6 - import { cn } from "@/utils/cn"; 7 8 const Popover = PopoverPrimitive.Root; 9
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import * as PopoverPrimitive from "@radix-ui/react-popover"; 5 import * as React from "react"; 6 7 const Popover = PopoverPrimitive.Root; 8
+1 -2
components/ui/separator.tsx
··· 1 "use client"; 2 3 import * as SeparatorPrimitive from "@radix-ui/react-separator"; 4 import * as React from "react"; 5 - 6 - import { cn } from "@/utils/cn"; 7 8 interface SeparatorProps extends React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root> { 9 loading?: boolean;
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import * as SeparatorPrimitive from "@radix-ui/react-separator"; 5 import * as React from "react"; 6 7 interface SeparatorProps extends React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root> { 8 loading?: boolean;
+1 -2
components/ui/switch.tsx
··· 1 "use client"; 2 3 import * as SwitchPrimitives from "@radix-ui/react-switch"; 4 import * as React from "react"; 5 - 6 - import { cn } from "@/utils/cn"; 7 8 const Switch = React.forwardRef< 9 React.ElementRef<typeof SwitchPrimitives.Root>,
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import * as SwitchPrimitives from "@radix-ui/react-switch"; 5 import * as React from "react"; 6 7 const Switch = React.forwardRef< 8 React.ElementRef<typeof SwitchPrimitives.Root>,
+1 -2
components/ui/tooltip.tsx
··· 1 "use client"; 2 3 import * as TooltipPrimitive from "@radix-ui/react-tooltip"; 4 import * as React from "react"; 5 - 6 - import { cn } from "@/utils/cn"; 7 8 const TooltipProvider = TooltipPrimitive.Provider; 9
··· 1 "use client"; 2 3 + import { cn } from "@/utils/cn"; 4 import * as TooltipPrimitive from "@radix-ui/react-tooltip"; 5 import * as React from "react"; 6 7 const TooltipProvider = TooltipPrimitive.Provider; 8
+144 -17
eslint.config.mjs
··· 1 import next from "@next/eslint-plugin-next"; 2 import stylistic from "@stylistic/eslint-plugin"; 3 - import pathAlias from "eslint-plugin-path-alias"; 4 import react from "eslint-plugin-react"; 5 import reactCompiler from "eslint-plugin-react-compiler"; 6 import reactHooks from "eslint-plugin-react-hooks"; 7 import simpleImportSort from "eslint-plugin-simple-import-sort"; 8 - import unusedImports from "eslint-plugin-unused-imports"; 9 import tseslint from "typescript-eslint"; 10 11 export default tseslint.config( ··· 26 "react-hooks": reactHooks, 27 "@next/next": next, 28 "react-compiler": reactCompiler, 29 - "path-alias": pathAlias, 30 "simple-import-sort": simpleImportSort, 31 - "unused-imports": unusedImports, 32 - "@stylistic": stylistic, 33 }, 34 rules: { 35 ...react.configs.recommended.rules, ··· 65 "@stylistic/no-extra-semi": "error", 66 "@stylistic/no-floating-decimal": "error", 67 "@stylistic/no-multi-spaces": "error", 68 - "@stylistic/no-multiple-empty-lines": ["error", { max: 2, maxBOF: 0, maxEOF: 0 }], 69 "@stylistic/no-trailing-spaces": "error", 70 "@stylistic/no-whitespace-before-property": "error", 71 "@stylistic/object-curly-newline": "error", ··· 88 "@stylistic/type-annotation-spacing": "error", 89 "@stylistic/type-generic-spacing": "error", 90 "@stylistic/type-named-tuple-spacing": "error", 91 "@typescript-eslint/no-explicit-any": "error", 92 "@typescript-eslint/adjacent-overload-signatures": "error", 93 "@typescript-eslint/array-type": "error", ··· 112 // order: "alphabetically-case-insensitive" 113 // } 114 // }], 115 "@typescript-eslint/method-signature-style": "error", 116 "@typescript-eslint/naming-convention": ["error", { selector: "typeLike", format: ["PascalCase"] }], 117 "@typescript-eslint/no-duplicate-enum-values": "error", ··· 142 "@typescript-eslint/no-unused-expressions": "error", 143 "@typescript-eslint/require-await": "error", 144 "@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error", 145 - 146 - // Import Sorting Rules 147 - "simple-import-sort/imports": "error", 148 "simple-import-sort/exports": "error", 149 - 150 - // Unused Imports Rules 151 - "unused-imports/no-unused-imports": "error", 152 - "unused-imports/no-unused-vars": [ 153 - "warn", 154 - { vars: "all", varsIgnorePattern: "^_", args: "after-used", argsIgnorePattern: "^_" }, 155 - ], 156 }, 157 settings: { 158 react: { ··· 161 } 162 }, 163 { 164 - ignores: ["node_modules", ".next", "**/gt4.ts", "next-env.d.ts", "typings.ts"] 165 } 166 )
··· 1 import next from "@next/eslint-plugin-next"; 2 import stylistic from "@stylistic/eslint-plugin"; 3 + import eslintPluginImport from "eslint-plugin-import-x"; 4 import react from "eslint-plugin-react"; 5 import reactCompiler from "eslint-plugin-react-compiler"; 6 import reactHooks from "eslint-plugin-react-hooks"; 7 import simpleImportSort from "eslint-plugin-simple-import-sort"; 8 + import eslintPluginUnicorn from "eslint-plugin-unicorn"; 9 import tseslint from "typescript-eslint"; 10 11 export default tseslint.config( ··· 26 "react-hooks": reactHooks, 27 "@next/next": next, 28 "react-compiler": reactCompiler, 29 + 30 + "@stylistic": stylistic, 31 + "@typescript-eslint": tseslint.plugin, 32 + import: eslintPluginImport, 33 "simple-import-sort": simpleImportSort, 34 + unicorn: eslintPluginUnicorn 35 }, 36 rules: { 37 ...react.configs.recommended.rules, ··· 67 "@stylistic/no-extra-semi": "error", 68 "@stylistic/no-floating-decimal": "error", 69 "@stylistic/no-multi-spaces": "error", 70 + "@stylistic/no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }], 71 "@stylistic/no-trailing-spaces": "error", 72 "@stylistic/no-whitespace-before-property": "error", 73 "@stylistic/object-curly-newline": "error", ··· 90 "@stylistic/type-annotation-spacing": "error", 91 "@stylistic/type-generic-spacing": "error", 92 "@stylistic/type-named-tuple-spacing": "error", 93 + "@stylistic/max-statements-per-line": ["error", { max: 1 }], 94 + "@stylistic/multiline-comment-style": ["error", "separate-lines"], 95 + "@stylistic/no-mixed-spaces-and-tabs": "error", 96 + "@stylistic/no-tabs": "error", 97 + "@stylistic/object-property-newline": ["error", { allowAllPropertiesOnSameLine: true }], 98 + "@stylistic/one-var-declaration-per-line": "error", 99 + "@stylistic/wrap-iife": ["error", "inside"], 100 + // "@typescript-eslint/no-floating-promises": "error", 101 "@typescript-eslint/no-explicit-any": "error", 102 "@typescript-eslint/adjacent-overload-signatures": "error", 103 "@typescript-eslint/array-type": "error", ··· 122 // order: "alphabetically-case-insensitive" 123 // } 124 // }], 125 + "@typescript-eslint/consistent-type-imports": "error", 126 "@typescript-eslint/method-signature-style": "error", 127 "@typescript-eslint/naming-convention": ["error", { selector: "typeLike", format: ["PascalCase"] }], 128 "@typescript-eslint/no-duplicate-enum-values": "error", ··· 153 "@typescript-eslint/no-unused-expressions": "error", 154 "@typescript-eslint/require-await": "error", 155 "@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error", 156 + "@typescript-eslint/array-type": "error", 157 + "@typescript-eslint/prefer-as-const": "error", 158 + "@typescript-eslint/prefer-find": "error", 159 + "@typescript-eslint/prefer-for-of": "error", 160 + "@typescript-eslint/prefer-includes": "error", 161 + "@typescript-eslint/prefer-reduce-type-parameter": "error", 162 + "@typescript-eslint/prefer-return-this-type": "error", 163 + "@typescript-eslint/prefer-string-starts-ends-with": "error", 164 + "@typescript-eslint/prefer-ts-expect-error": "error", 165 + "@typescript-eslint/restrict-plus-operands": "error", 166 + "@typescript-eslint/no-confusing-void-expression": ["error", { ignoreArrowShorthand: true }], 167 + "@typescript-eslint/no-meaningless-void-operator": "error", 168 + "@typescript-eslint/no-mixed-enums": "error", 169 + "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error", 170 + "@typescript-eslint/no-unnecessary-type-assertion": "error", 171 + "@typescript-eslint/unbound-method": "error", 172 + "import/extensions": "off", // changed 173 + "import/first": "error", 174 + "import/newline-after-import": ["error", { considerComments: true }], 175 + "import/no-absolute-path": "error", 176 + "import/no-duplicates": "error", 177 + "import/no-empty-named-blocks": "error", 178 + "import/no-extraneous-dependencies": "error", 179 + "import/no-relative-packages": "error", 180 + "import/no-unused-modules": "error", 181 + "import/no-self-import": "error", 182 + "import/no-useless-path-segments": "error", 183 + "import/no-cycle": ["error", { maxDepth: Infinity }], 184 "simple-import-sort/exports": "error", 185 + "simple-import-sort/imports": ["error", { groups: [["^\\u0000", "^[^~./]"], ["^~"], ["^\\./", "^\\.\\./"]] }], 186 + "unicorn/escape-case": "error", 187 + // "unicorn/filename-case": ["error", { cases: { pascalCase: true, snakeCase: true, kebabCase: true } }], 188 + "unicorn/no-hex-escape": "error", 189 + "unicorn/no-zero-fractions": "error", 190 + "unicorn/number-literal-case": "error", 191 + "unicorn/numeric-separators-style": ["error", { number: { minimumDigits: 0 } }], 192 + "unicorn/prefer-export-from": "error", 193 + "unicorn/better-regex": "error", 194 + "unicorn/catch-error-name": "error", 195 + "unicorn/consistent-function-scoping": ["error", { checkArrowFunctions: false }], 196 + "unicorn/empty-brace-spaces": "error", 197 + "unicorn/error-message": "error", 198 + "unicorn/new-for-builtins": "error", 199 + "unicorn/no-array-callback-reference": "error", 200 + "unicorn/no-array-for-each": "error", 201 + "unicorn/no-array-push-push": "error", 202 + "unicorn/no-console-spaces": "error", 203 + "unicorn/no-for-loop": "error", 204 + "unicorn/no-instanceof-array": "error", 205 + "unicorn/no-negated-condition": "error", 206 + "unicorn/no-new-array": "error", 207 + "unicorn/no-new-buffer": "error", 208 + "unicorn/no-object-as-default-parameter": "error", 209 + "unicorn/no-static-only-class": "error", 210 + "unicorn/no-thenable": "error", 211 + "unicorn/no-this-assignment": "error", 212 + "unicorn/no-unnecessary-await": "error", 213 + "unicorn/no-unreadable-array-destructuring": "error", 214 + "unicorn/no-unreadable-iife": "error", 215 + "unicorn/no-useless-length-check": "error", 216 + "unicorn/no-useless-promise-resolve-reject": "error", 217 + "unicorn/no-useless-spread": "error", 218 + "unicorn/no-useless-switch-case": "error", 219 + "unicorn/prefer-array-find": "error", 220 + "unicorn/prefer-array-flat": "error", 221 + "unicorn/prefer-array-flat-map": "error", 222 + "unicorn/prefer-array-index-of": "error", 223 + "unicorn/prefer-array-some": "error", 224 + "unicorn/prefer-at": "error", 225 + "unicorn/prefer-date-now": "error", 226 + "unicorn/prefer-default-parameters": "error", 227 + "unicorn/prefer-includes": "error", 228 + "unicorn/prefer-logical-operator-over-ternary": "error", 229 + "unicorn/prefer-modern-math-apis": "error", 230 + "unicorn/prefer-negative-index": "error", 231 + "unicorn/prefer-number-properties": "error", 232 + "unicorn/prefer-object-from-entries": "error", 233 + "unicorn/prefer-optional-catch-binding": "error", 234 + "unicorn/prefer-prototype-methods": "error", 235 + "unicorn/prefer-regexp-test": "error", 236 + "unicorn/prefer-set-has": "error", 237 + "unicorn/prefer-spread": "error", 238 + "unicorn/prefer-string-slice": "error", 239 + "unicorn/prefer-string-starts-ends-with": "error", 240 + "unicorn/prefer-string-trim-start-end": "error", 241 + "unicorn/prefer-switch": "error", 242 + "unicorn/prefer-type-error": "error", 243 + "unicorn/require-number-to-fixed-digits-argument": "error", 244 + "unicorn/throw-new-error": "error", 245 + "no-dupe-else-if": "error", 246 + "no-template-curly-in-string": "error", 247 + "no-unexpected-multiline": "error", 248 + "no-unreachable": "error", 249 + "no-unreachable-loop": "error", 250 + "default-case-last": "error", 251 + "dot-notation": "error", 252 + eqeqeq: "error", 253 + // "new-cap": "error", 254 + // "no-console": "error", 255 + "no-empty": "error", 256 + // "no-nested-ternary": "error", 257 + "no-unneeded-ternary": "error", 258 + "no-var": "error", 259 + "for-direction": "error", 260 + "no-constant-condition": "error", 261 + "no-constructor-return": "error", 262 + "no-duplicate-case": "error", 263 + "no-else-return": "error", 264 + "no-implicit-coercion": "error", 265 + "no-lonely-if": "error", 266 + "no-return-assign": "error", 267 + "no-self-compare": "error", 268 + "no-throw-literal": "error", 269 + "no-undef-init": "error", 270 + "no-unused-expressions": "off", 271 + "no-useless-concat": "error", 272 + "no-useless-return": "error", 273 + "object-shorthand": "error", 274 + "one-var": ["error", "never"], 275 + "prefer-arrow-callback": "error", 276 + "prefer-const": "error", 277 + "prefer-destructuring": ["error", { object: true, array: false }], 278 + "prefer-object-spread": "error", 279 + "prefer-rest-params": "error", 280 + "prefer-spread": "error", 281 + radix: "error", 282 + yoda: "error" 283 }, 284 settings: { 285 react: { ··· 288 } 289 }, 290 { 291 + ignores: ["node_modules", ".next", "**/gt4.ts", "next-env.d.ts"] 292 } 293 )
+1 -1
lib/analytics.ts
··· 19 }; 20 21 const res = await fetch(`${process.env.PLAUSIBLE_API}/v1/stats/breakdown?${objectToQueryString(params)}`, { 22 - headers: { Authorization: "Bearer " + process.env.PLAUSIBLE_API_KEY as string }, 23 next: { revalidate: 60 } 24 }); 25
··· 19 }; 20 21 const res = await fetch(`${process.env.PLAUSIBLE_API}/v1/stats/breakdown?${objectToQueryString(params)}`, { 22 + headers: { Authorization: "Bearer " + process.env.PLAUSIBLE_API_KEY }, 23 next: { revalidate: 60 } 24 }); 25
+1 -2
lib/api/hook.ts
··· 1 import { useCallback } from "react"; 2 import { useQuery, useQueryClient } from "react-query"; 3 - 4 - import { cacheOptions, getData } from "@/lib/api"; 5 6 export type ApiEdit<T> = <K extends keyof T>(key: K, value: T[K]) => void; 7
··· 1 + import { cacheOptions, getData } from "@/lib/api"; 2 import { useCallback } from "react"; 3 import { useQuery, useQueryClient } from "react-query"; 4 5 export type ApiEdit<T> = <K extends keyof T>(key: K, value: T[K]) => void; 6
+1 -1
lib/api/index.ts
··· 5 } 6 7 export const cacheOptions = { 8 - cacheTime: 1000 * 60 * 60, 9 refetchOnWindowFocus: false, 10 refetchOnMount: false 11 };
··· 5 } 6 7 export const cacheOptions = { 8 + cacheTime: 1_000 * 60 * 60, 9 refetchOnWindowFocus: false, 10 refetchOnMount: false 11 };
+1 -1
lib/cookies.ts
··· 8 sameSite: "lax", 9 domain: "." + (domain.startsWith("dev.") ? domain.replace(/^dev\./, "") : domain), 10 get expires() { 11 - return new Date(Date.now() + 1000 * 60 * 60 * 24 * 28); 12 } 13 } as const;
··· 8 sameSite: "lax", 9 domain: "." + (domain.startsWith("dev.") ? domain.replace(/^dev\./, "") : domain), 10 get expires() { 11 + return new Date(Date.now() + 1_000 * 60 * 60 * 24 * 28); 12 } 13 } as const;
+1 -1
lib/gt4.ts
··· 27 userInfo?: string; 28 } 29 30 - export function GT4Init() { 31 "use strict"; 32 if (typeof window === "undefined") { 33 throw new Error("Geetest requires browser environment");
··· 27 userInfo?: string; 28 } 29 30 + export function gt4init() { 31 "use strict"; 32 if (typeof window === "undefined") { 33 throw new Error("Geetest requires browser environment");
+2 -2
package.json
··· 65 "@types/react-dom": "^19.1.9", 66 "eslint": "^9.36.0", 67 "eslint-config-next": "^15.5.4", 68 - "eslint-plugin-path-alias": "^2.1.0", 69 "eslint-plugin-react": "^7.37.5", 70 "eslint-plugin-react-compiler": "19.1.0-rc.2", 71 "eslint-plugin-react-hooks": "^5.2.0", 72 "eslint-plugin-simple-import-sort": "^12.1.1", 73 - "eslint-plugin-unused-imports": "^4.2.0", 74 "typescript-eslint": "^8.44.1" 75 } 76 }
··· 65 "@types/react-dom": "^19.1.9", 66 "eslint": "^9.36.0", 67 "eslint-config-next": "^15.5.4", 68 + "eslint-plugin-import-x": "^4.16.1", 69 "eslint-plugin-react": "^7.37.5", 70 "eslint-plugin-react-compiler": "19.1.0-rc.2", 71 "eslint-plugin-react-hooks": "^5.2.0", 72 "eslint-plugin-simple-import-sort": "^12.1.1", 73 + "eslint-plugin-unicorn": "^61.0.2", 74 "typescript-eslint": "^8.44.1" 75 } 76 }
+1 -1
public/docs/notifications.md
··· 69 The flags used for string matching are `gi`, only the YouTube and Twitch titles, Bluesky post bodies, and Reddit flairs are checked. 70 71 ### 🕵️‍♀️ Styles (whitelabel / webhook) 72 - Notification styles allow you to customise (or whitelabel) the username and avatar of the author (i.e. the sender of the message) separately for each notification. Wamellow will automatically manage the webhooks for you. 73 <br /> 74 <br /> 75
··· 69 The flags used for string matching are `gi`, only the YouTube and Twitch titles, Bluesky post bodies, and Reddit flairs are checked. 70 71 ### 🕵️‍♀️ Styles (whitelabel / webhook) 72 + Notification styles allow you to customize (or whitelabel) the username and avatar of the author (i.e. the sender of the message) separately for each notification. Wamellow will automatically manage the webhooks for you. 73 <br /> 74 <br /> 75
+67 -38
tsconfig.json
··· 1 { 2 - "compilerOptions": { 3 - "target": "es6", 4 - "lib": [ 5 - "dom", 6 - "dom.iterable", 7 - "esnext" 8 - ], 9 - "allowJs": true, 10 - "skipLibCheck": true, 11 - "strict": true, 12 - "forceConsistentCasingInFileNames": true, 13 - "noEmit": true, 14 - "esModuleInterop": true, 15 - "module": "esnext", 16 - "moduleResolution": "node", 17 - "resolveJsonModule": true, 18 - "isolatedModules": true, 19 - "jsx": "preserve", 20 - "incremental": true, 21 - "plugins": [ 22 - { 23 - "name": "next" 24 - } 25 ], 26 - "paths": { 27 - "@/*": [ 28 - "./*" 29 - ] 30 - } 31 - }, 32 - "include": [ 33 - "next-env.d.ts", 34 - "**/*.ts", 35 - "**/*.tsx", 36 - ".next/types/**/*.ts" 37 - ], 38 - "exclude": [ 39 - "node_modules" 40 - ] 41 }
··· 1 { 2 + "compilerOptions": { 3 + /* Basic Options */ 4 + "incremental": true, 5 + "module": "ESNext", 6 + "target": "ES2024", 7 + "lib": [ 8 + "dom", 9 + "dom.iterable", 10 + "esnext" 11 + ], 12 + 13 + /* Strict Type-Checking Options */ 14 + "strict": true, 15 + "noImplicitAny": true, 16 + "strictNullChecks": true, 17 + "strictFunctionTypes": true, 18 + "strictBindCallApply": true, 19 + "strictPropertyInitialization": true, 20 + "noImplicitThis": true, 21 + "alwaysStrict": true, 22 + 23 + /* Additional Checks */ 24 + "noUnusedLocals": true, 25 + "noUnusedParameters": true, 26 + "noImplicitReturns": false, 27 + "noFallthroughCasesInSwitch": true, 28 + 29 + /* Module Resolution Options */ 30 + "moduleResolution": "node", 31 + "esModuleInterop": true, 32 + "baseUrl": ".", 33 + 34 + "declaration": true, 35 + "skipLibCheck": true, 36 + "resolveJsonModule": true, 37 + "noUncheckedIndexedAccess": false, 38 + 39 + /* Experimental Options */ 40 + "experimentalDecorators": false, 41 + 42 + /* Advanced Options */ 43 + "forceConsistentCasingInFileNames": true, 44 + 45 + /* Other Options */ 46 + "allowJs": true, 47 + "noEmit": true, 48 + "isolatedModules": true, 49 + "jsx": "preserve", 50 + "plugins": [ 51 + { 52 + "name": "next" 53 + } 54 + ], 55 + "paths": { 56 + "@/*": [ 57 + "./*" 58 + ] 59 + } 60 + }, 61 + "include": [ 62 + "next-env.d.ts", 63 + "**/*.ts", 64 + "**/*.tsx", 65 + ".next/types/**/*.ts" 66 ], 67 + "exclude": [ 68 + "node_modules" 69 + ] 70 }
+78 -77
typings.ts
··· 1 - import { ChannelType } from "discord-api-types/v10"; 2 - import { actor } from "./utils/tts"; 3 4 export interface ApiError { 5 status: number; ··· 24 } 25 26 export enum GuildFlags { 27 - Premium = 1 << 0, 28 } 29 30 export interface ApiV1GuildsGetResponse { ··· 55 username: string | null; 56 avatar: string | null; 57 banner: string | null; 58 - } 59 } 60 61 export interface ApiV1GuildsStylePatchResponse { ··· 72 avatar: string | null; 73 bot: true; 74 emoji: string | null; 75 - activity: ApiV1UsersMeGetResponse["activity"] & { formattedVoicetime: string }; 76 } 77 78 export interface ApiV1GuildsTopmembersPaginationGetResponse { ··· 128 footer: { 129 text: string | null; 130 icon_url: string | null; 131 - } 132 } 133 134 export interface ApiV1GuildsModulesWelcomeGetResponse { ··· 137 138 message: { 139 content?: string; 140 - embed?: GuildEmbed 141 }; 142 143 roleIds: string[]; ··· 155 }; 156 157 reactions: { 158 - welcomeMessageEmojis: string[], 159 - firstMessageEmojis: string[], 160 }; 161 162 card: { ··· 183 184 message: { 185 content?: string; 186 - embed?: GuildEmbed 187 }; 188 189 deleteAfter?: number; ··· 243 rank: "**" | "__" | "*" | "`" | null; 244 number: "**" | "__" | "*" | "`" | null; 245 user: "**" | "__" | "*" | "`" | null; 246 - } 247 248 range: "daily" | "weekly" | "monthly" | "alltime"; 249 display: "mention" | "username" | "nickname" | "id"; ··· 270 271 export interface ApiV1GuildsModulesPassportGetResponse { 272 enabled: boolean; 273 - channelId?: string; 274 /** 275 * We're currently on free tier 276 */ ··· 281 * 2 - Assign role 282 */ 283 punishment: 0 | 1 | 2; 284 - punishmentRoleId?: string; 285 286 - successRoleId?: string; 287 - unverifiedRoleId?: string; 288 289 sendFailedDm: boolean; 290 - alsoFailIf: ("disposableEmailAddress")[] 291 } 292 293 export enum UserFlags { ··· 308 barColor?: number; 309 useLeaderboardList?: boolean; 310 subText?: { 311 - type: 0 | 1 | 2 | 3 // 0: off, 1: date, 2: relative, 3: custom 312 content?: string; 313 }; 314 }; ··· 336 337 export interface ApiV1UsersMeBillingGetResponse { 338 subscriptionId: string; 339 - status: 'active' 340 - | 'canceled' 341 - | 'incomplete' 342 - | 'incomplete_expired' 343 - | 'past_due' 344 - | 'paused' 345 - | 'trialing' 346 - | 'unpaid'; 347 priceId: string; 348 created: number; 349 currentPeriodEnd: number; ··· 355 last4: string | null; 356 } | string | null; 357 portalUrl: string; 358 - guildIds: string[] 359 } 360 361 export interface ApiV1GuildsModulesTagsGetResponse { ··· 410 pagination: { 411 total: number; 412 pages: number; 413 - } 414 } 415 416 export interface ApiV1UploadGetResponse extends Upload { ··· 529 export interface NekosticResponse { 530 event: string; 531 name: string; 532 - uses: number 533 users: number; 534 snapshot: string; 535 } 536 537 export enum PermissionFlagsBits { 538 - CreateInstantInvite = 0x0000000000000001, 539 - KickMembers = 0x0000000000000002, 540 - BanMembers = 0x0000000000000004, 541 - Administrator = 0x0000000000000008, 542 - ManageChannels = 0x0000000000000010, 543 - ManageGuild = 0x0000000000000020, 544 - AddReactions = 0x0000000000000040, 545 - ViewAuditLog = 0x0000000000000080, 546 - PrioritySpeaker = 0x0000000000000100, 547 - Stream = 0x0000000000000200, 548 - ViewChannel = 0x0000000000000400, 549 - SendMessages = 0x0000000000000800, 550 - SendTtsMessages = 0x0000000000001000, 551 - ManageMessages = 0x0000000000002000, 552 - EmbedLinks = 0x0000000000004000, 553 - AttachFiles = 0x0000000000008000, 554 - ReadMessageHistory = 0x0000000000010000, 555 - MentionEveryone = 0x0000000000020000, 556 - UseExternalEmojis = 0x0000000000040000, 557 - ViewGuildInsights = 0x0000000000080000, 558 - Connect = 0x0000000000100000, 559 - Speak = 0x0000000000200000, 560 - MuteMembers = 0x0000000000400000, 561 - DeafenMembers = 0x0000000000800000, 562 - MoveMembers = 0x0000000001000000, 563 - UseVad = 0x0000000002000000, 564 - ChangeNickname = 0x0000000004000000, 565 - ManageNicknames = 0x0000000008000000, 566 - ManageRoles = 0x0000000010000000, 567 - ManageWebhooks = 0x0000000020000000, 568 - ManageGuildExpressions = 0x0000000040000000, 569 - UseApplicationCommands = 0x0000000080000000, 570 - RequestToSpeak = 0x0000000100000000, 571 - ManageEvents = 0x0000000200000000, 572 - ManageThreads = 0x0000000400000000, 573 - CreatePublicThreads = 0x0000000800000000, 574 - CreatePrivateThreads = 0x0000001000000000, 575 - UseExternalStickers = 0x0000002000000000, 576 - SendMessagesInThreads = 0x0000004000000000, 577 - UseEmbeddedActivities = 0x0000008000000000, 578 - ModerateMembers = 0x0000010000000000, 579 - ViewCreatorMonetizationAnalytics = 0x0000020000000000, 580 - UseSoundboard = 0x0000040000000000, 581 - CreateGuildExpressions = 0x0000080000000000, 582 - CreateEvents = 0x0000100000000000, 583 - UseExternalSounds = 0x0000200000000000, 584 - SendVoiceMessages = 0x0000400000000000, 585 - SendPolls = 0x0002000000000000, 586 - UseExternalApps = 0x0004000000000000, 587 }
··· 1 + import type { ChannelType } from "discord-api-types/v10"; 2 + 3 + import type { actor } from "./utils/tts"; 4 5 export interface ApiError { 6 status: number; ··· 25 } 26 27 export enum GuildFlags { 28 + Premium = 1 << 0 29 } 30 31 export interface ApiV1GuildsGetResponse { ··· 56 username: string | null; 57 avatar: string | null; 58 banner: string | null; 59 + }; 60 } 61 62 export interface ApiV1GuildsStylePatchResponse { ··· 73 avatar: string | null; 74 bot: true; 75 emoji: string | null; 76 + activity: ApiV1UsersMeGetResponse["activity"] & { formattedVoicetime: string; }; 77 } 78 79 export interface ApiV1GuildsTopmembersPaginationGetResponse { ··· 129 footer: { 130 text: string | null; 131 icon_url: string | null; 132 + }; 133 } 134 135 export interface ApiV1GuildsModulesWelcomeGetResponse { ··· 138 139 message: { 140 content?: string; 141 + embed?: GuildEmbed; 142 }; 143 144 roleIds: string[]; ··· 156 }; 157 158 reactions: { 159 + welcomeMessageEmojis: string[]; 160 + firstMessageEmojis: string[]; 161 }; 162 163 card: { ··· 184 185 message: { 186 content?: string; 187 + embed?: GuildEmbed; 188 }; 189 190 deleteAfter?: number; ··· 244 rank: "**" | "__" | "*" | "`" | null; 245 number: "**" | "__" | "*" | "`" | null; 246 user: "**" | "__" | "*" | "`" | null; 247 + }; 248 249 range: "daily" | "weekly" | "monthly" | "alltime"; 250 display: "mention" | "username" | "nickname" | "id"; ··· 271 272 export interface ApiV1GuildsModulesPassportGetResponse { 273 enabled: boolean; 274 + channelId: string | null; 275 /** 276 * We're currently on free tier 277 */ ··· 282 * 2 - Assign role 283 */ 284 punishment: 0 | 1 | 2; 285 + punishmentRoleId: string | null; 286 287 + successRoleId: string | null; 288 + unverifiedRoleId: string | null; 289 290 sendFailedDm: boolean; 291 + alsoFailIf: ("disposableEmailAddress")[]; 292 } 293 294 export enum UserFlags { ··· 309 barColor?: number; 310 useLeaderboardList?: boolean; 311 subText?: { 312 + type: 0 | 1 | 2 | 3; // 0: off, 1: date, 2: relative, 3: custom 313 content?: string; 314 }; 315 }; ··· 337 338 export interface ApiV1UsersMeBillingGetResponse { 339 subscriptionId: string; 340 + status: "active" 341 + | "canceled" 342 + | "incomplete" 343 + | "incomplete_expired" 344 + | "past_due" 345 + | "paused" 346 + | "trialing" 347 + | "unpaid"; 348 priceId: string; 349 created: number; 350 currentPeriodEnd: number; ··· 356 last4: string | null; 357 } | string | null; 358 portalUrl: string; 359 + guildIds: string[]; 360 } 361 362 export interface ApiV1GuildsModulesTagsGetResponse { ··· 411 pagination: { 412 total: number; 413 pages: number; 414 + }; 415 } 416 417 export interface ApiV1UploadGetResponse extends Upload { ··· 530 export interface NekosticResponse { 531 event: string; 532 name: string; 533 + uses: number; 534 users: number; 535 snapshot: string; 536 } 537 538 export enum PermissionFlagsBits { 539 + CreateInstantInvite = 0x00_00_00_00_00_00_00_01, 540 + KickMembers = 0x00_00_00_00_00_00_00_02, 541 + BanMembers = 0x00_00_00_00_00_00_00_04, 542 + Administrator = 0x00_00_00_00_00_00_00_08, 543 + ManageChannels = 0x00_00_00_00_00_00_00_10, 544 + ManageGuild = 0x00_00_00_00_00_00_00_20, 545 + AddReactions = 0x00_00_00_00_00_00_00_40, 546 + ViewAuditLog = 0x00_00_00_00_00_00_00_80, 547 + PrioritySpeaker = 0x00_00_00_00_00_00_01_00, 548 + Stream = 0x00_00_00_00_00_00_02_00, 549 + ViewChannel = 0x00_00_00_00_00_00_04_00, 550 + SendMessages = 0x00_00_00_00_00_00_08_00, 551 + SendTtsMessages = 0x00_00_00_00_00_00_10_00, 552 + ManageMessages = 0x00_00_00_00_00_00_20_00, 553 + EmbedLinks = 0x00_00_00_00_00_00_40_00, 554 + AttachFiles = 0x00_00_00_00_00_00_80_00, 555 + ReadMessageHistory = 0x00_00_00_00_00_01_00_00, 556 + MentionEveryone = 0x00_00_00_00_00_02_00_00, 557 + UseExternalEmojis = 0x00_00_00_00_00_04_00_00, 558 + ViewGuildInsights = 0x00_00_00_00_00_08_00_00, 559 + Connect = 0x00_00_00_00_00_10_00_00, 560 + Speak = 0x00_00_00_00_00_20_00_00, 561 + MuteMembers = 0x00_00_00_00_00_40_00_00, 562 + DeafenMembers = 0x00_00_00_00_00_80_00_00, 563 + MoveMembers = 0x00_00_00_00_01_00_00_00, 564 + UseVad = 0x00_00_00_00_02_00_00_00, 565 + ChangeNickname = 0x00_00_00_00_04_00_00_00, 566 + ManageNicknames = 0x00_00_00_00_08_00_00_00, 567 + ManageRoles = 0x00_00_00_00_10_00_00_00, 568 + ManageWebhooks = 0x00_00_00_00_20_00_00_00, 569 + ManageGuildExpressions = 0x00_00_00_00_40_00_00_00, 570 + UseApplicationCommands = 0x00_00_00_00_80_00_00_00, 571 + RequestToSpeak = 0x00_00_00_01_00_00_00_00, 572 + ManageEvents = 0x00_00_00_02_00_00_00_00, 573 + ManageThreads = 0x00_00_00_04_00_00_00_00, 574 + CreatePublicThreads = 0x00_00_00_08_00_00_00_00, 575 + CreatePrivateThreads = 0x00_00_00_10_00_00_00_00, 576 + UseExternalStickers = 0x00_00_00_20_00_00_00_00, 577 + SendMessagesInThreads = 0x00_00_00_40_00_00_00_00, 578 + UseEmbeddedActivities = 0x00_00_00_80_00_00_00_00, 579 + ModerateMembers = 0x00_00_01_00_00_00_00_00, 580 + ViewCreatorMonetizationAnalytics = 0x00_00_02_00_00_00_00_00, 581 + UseSoundboard = 0x00_00_04_00_00_00_00_00, 582 + CreateGuildExpressions = 0x00_00_08_00_00_00_00_00, 583 + CreateEvents = 0x00_00_10_00_00_00_00_00, 584 + UseExternalSounds = 0x00_00_20_00_00_00_00_00, 585 + SendVoiceMessages = 0x00_00_40_00_00_00_00_00, 586 + SendPolls = 0x00_02_00_00_00_00_00_00, 587 + UseExternalApps = 0x00_04_00_00_00_00_00_00 588 }
+1 -2
utils/authorize-user.ts
··· 1 - import type React from "react"; 2 - 3 import type { User } from "@/common/user"; 4 import type { ApiError } from "@/typings"; 5 6 enum State { 7 Idle = 0,
··· 1 import type { User } from "@/common/user"; 2 import type { ApiError } from "@/typings"; 3 + import type React from "react"; 4 5 enum State { 6 Idle = 0,
+2 -3
utils/captcha.ts
··· 1 import { useEffect, useRef, useState } from "react"; 2 - 3 - import { GT4Init } from "@/lib/gt4"; 4 5 export enum State { 6 Idle = 0, ··· 16 17 useEffect(() => { 18 if (!userId) return; 19 - const { init } = GT4Init(); 20 21 init( 22 {
··· 1 + import { gt4init } from "@/lib/gt4"; 2 import { useEffect, useRef, useState } from "react"; 3 4 export enum State { 5 Idle = 0, ··· 15 16 useEffect(() => { 17 if (!userId) return; 18 + const { init } = gt4init(); 19 20 init( 21 {
+2 -3
utils/create-selectable-items.tsx
··· 1 import { ChannelType } from "discord-api-types/v10"; 2 import Image from "next/image"; 3 import { HiAtSymbol, HiHashtag, HiMenuAlt2, HiNewspaper, HiVolumeUp } from "react-icons/hi"; 4 - 5 - import { type ApiV1GuildsChannelsGetResponse, type ApiV1GuildsEmojisGetResponse, type ApiV1GuildsRolesGetResponse, PermissionFlagsBits } from "@/typings"; 6 7 type Item = ApiV1GuildsChannelsGetResponse | ApiV1GuildsRolesGetResponse; 8 type PermissionNames = keyof typeof PermissionFlagsBits | "RoleHirachy"; ··· 12 13 return required 14 .filter((perm) => perm !== "RoleHirachy") 15 - .map((perm) => (permissions & PermissionFlagsBits[perm as keyof typeof PermissionFlagsBits]) === 0 ? perm : false) 16 .filter(Boolean); 17 } 18
··· 1 + import { type ApiV1GuildsChannelsGetResponse, type ApiV1GuildsEmojisGetResponse, type ApiV1GuildsRolesGetResponse, PermissionFlagsBits } from "@/typings"; 2 import { ChannelType } from "discord-api-types/v10"; 3 import Image from "next/image"; 4 import { HiAtSymbol, HiHashtag, HiMenuAlt2, HiNewspaper, HiVolumeUp } from "react-icons/hi"; 5 6 type Item = ApiV1GuildsChannelsGetResponse | ApiV1GuildsRolesGetResponse; 7 type PermissionNames = keyof typeof PermissionFlagsBits | "RoleHirachy"; ··· 11 12 return required 13 .filter((perm) => perm !== "RoleHirachy") 14 + .map((perm) => (permissions & PermissionFlagsBits[perm]) === 0 ? perm : false) 15 .filter(Boolean); 16 } 17
+3 -3
utils/decimalToRgb.ts
··· 1 export default function decimalToRgb(int: number) { 2 return { 3 - b: int & 0xff, 4 - g: (int >> 8) & 0xff, 5 - r: (int >> 16) & 0xff 6 }; 7 }
··· 1 export default function decimalToRgb(int: number) { 2 return { 3 + b: int & 0xFF, 4 + g: (int >> 8) & 0xFF, 5 + r: (int >> 16) & 0xFF 6 }; 7 }
+1 -3
utils/input.ts
··· 1 import type { HTMLProps } from "react"; 2 import { useCallback, useRef, useState } from "react"; 3 - 4 - import type { ApiError } from "@/typings"; 5 - 6 7 export enum InputState { 8 Idle = 0,
··· 1 + import type { ApiError } from "@/typings"; 2 import type { HTMLProps } from "react"; 3 import { useCallback, useRef, useState } from "react"; 4 5 export enum InputState { 6 Idle = 0,
+3 -3
utils/time.ts
··· 44 const now = new Date(); 45 const diff = now.getTime() - date.getTime(); 46 47 - const seconds = Math.floor(diff / 1000); 48 const minutes = Math.floor(seconds / 60); 49 const hours = Math.floor(minutes / 60); 50 const days = Math.floor(hours / 24); ··· 61 return days === 1 ? "a day ago" : `${days} days ago`; 62 } else if (months < 12) { 63 return months === 1 ? "a month ago" : `${months} months ago`; 64 - } else { 65 - return years === 1 ? "a year ago" : `${years} years ago`; 66 } 67 }
··· 44 const now = new Date(); 45 const diff = now.getTime() - date.getTime(); 46 47 + const seconds = Math.floor(diff / 1_000); 48 const minutes = Math.floor(seconds / 60); 49 const hours = Math.floor(minutes / 60); 50 const days = Math.floor(hours / 24); ··· 61 return days === 1 ? "a day ago" : `${days} days ago`; 62 } else if (months < 12) { 63 return months === 1 ? "a month ago" : `${months} months ago`; 64 } 65 + return years === 1 ? "a year ago" : `${years} years ago`; 66 + 67 }
+1 -1
utils/truncate.ts
··· 1 export const truncate = (str: string, length: number) => { 2 - return str.length > length ? str.substring(0, length) + "…" : str; 3 };
··· 1 export const truncate = (str: string, length: number) => { 2 + return str.length > length ? str.slice(0, Math.max(0, length)) + "…" : str; 3 };
+1 -1
utils/useDebounce.ts
··· 1 import { useMemo, useState } from "react"; 2 3 const debounce = <T>(fn: (...args: T[]) => void, delay: number) => { 4 - let timeout: NodeJS.Timeout | undefined = undefined; 5 return (...args: T[]) => { 6 if (timeout !== undefined) { 7 clearTimeout(timeout);
··· 1 import { useMemo, useState } from "react"; 2 3 const debounce = <T>(fn: (...args: T[]) => void, delay: number) => { 4 + let timeout: NodeJS.Timeout | undefined; 5 return (...args: T[]) => { 6 if (timeout !== undefined) { 7 clearTimeout(timeout);