From 7c250116a1a1833a9d653accff17e380d3a1a2b1 Mon Sep 17 00:00:00 2001 From: manNomi Date: Mon, 1 Jun 2026 00:09:17 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9B=B9=20React=20Compiler=20?= =?UTF-8?q?=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/REACT_COMPILER.md | 42 ++ apps/web/next.config.mjs | 9 +- apps/web/package.json | 6 +- .../_ui/PopularUniversitySection/index.tsx | 34 +- apps/web/src/app/(home)/page.tsx | 10 +- .../[boardCode]/[postId]/modify/page.tsx | 8 +- .../community/[boardCode]/[postId]/page.tsx | 10 +- .../app/community/[boardCode]/create/page.tsx | 4 +- .../src/app/community/[boardCode]/page.tsx | 8 +- apps/web/src/app/layout.tsx | 8 +- apps/web/src/app/login/page.tsx | 9 +- apps/web/src/app/mentor/[id]/page.tsx | 7 +- .../web/src/app/mentor/chat/[chatId]/page.tsx | 7 +- .../app/university/[homeUniversity]/page.tsx | 11 +- .../app/university/application/apply/page.tsx | 8 +- apps/web/src/app/university/score/page.tsx | 4 +- .../score/submit/gpa/_lib/schema.ts | 3 +- .../app/university/score/submit/gpa/page.tsx | 4 +- .../score/submit/language-test/_lib/schema.ts | 3 +- .../score/submit/language-test/page.tsx | 4 +- apps/web/src/app/university/search/page.tsx | 4 +- .../components/layout/GlobalLayout/index.tsx | 7 +- apps/web/src/components/ui/ChannelBadge.tsx | 2 + apps/web/src/utils/isServerStateLogin.ts | 4 +- apps/web/tsconfig.json | 1 + pnpm-lock.yaml | 524 ++++++++++++++++-- 26 files changed, 578 insertions(+), 163 deletions(-) create mode 100644 apps/web/REACT_COMPILER.md diff --git a/apps/web/REACT_COMPILER.md b/apps/web/REACT_COMPILER.md new file mode 100644 index 00000000..e55e1a21 --- /dev/null +++ b/apps/web/REACT_COMPILER.md @@ -0,0 +1,42 @@ +# React Compiler rollout + +## Current setup + +- React Compiler is wired through `experimental.reactCompiler` in `next.config.mjs`. +- The web app runs on Next.js 15 because the compiler config is handled by Next, not a custom Babel pipeline. +- React is still 18, so `react-compiler-runtime` is a runtime dependency and the compiler target is `"18"`. +- The current lockfile resolves React and React DOM to `18.3.1`. The `^18` range does not admit React 19, so React 19 should remain a separate migration. +- The compiler runs in `compilationMode: "annotation"` so only components or hooks with `"use memo"` are compiled. +- `ChannelBadge` is the first annotated component. It is intentionally small and presentational to keep the first rollout low risk. + +## Rollout notes + +- A custom Babel config is intentionally not used because it disables SWC and conflicts with `next/font` in this Next.js app. +- Keep `babel-plugin-react-compiler` and `react-compiler-runtime` on the same version when upgrading either package. +- This branch keeps the existing `next dev` script. If the web app later switches dev mode to Turbopack, re-run the compiler-output check there before widening annotation coverage. +- Build time should be watched before widening compiler coverage. +- Do not switch to full compilation until the app has a React Compiler lint/audit path. The current repo uses Biome instead of ESLint, so `eslint-plugin-react-hooks` `recommended-latest` is a follow-up decision rather than part of this first slice. +- For any component that behaves incorrectly after annotation, remove `"use memo"` or add `"use no memo"` while investigating. +- Current Next/Sentry warnings are unrelated to the compiler rollout, but should be reviewed before broadly modernizing the web app runtime. + +## Next.js 15 compatibility audit + +The Next.js 15 migration removed `next/dynamic(..., { ssr: false })` from Server Components because that option is no longer accepted there. Each direct import was audited before keeping the change: + +| Import target | Boundary / SSR safety | +| --- | --- | +| `AppleScriptLoader` | `"use client"` and renders `next/script` only. | +| `KakaoScriptLoader` | `"use client"` with `typeof window !== "undefined"` before Kakao initialization. | +| `LoginContent` | `"use client"`. | +| `NewsSection` | `"use client"`; `window.IntersectionObserver` is used inside `useEffect`. | +| `ApplyPageContent` | `"use client"`. | +| `ScoreScreen` | `"use client"`. | +| `SearchClientContent` | `"use client"`. | +| `AIInspectorFab` | `"use client"`; `window.location.href` is read inside a click handler. | +| `ClientModal` | `"use client"`. | +| `PopularUniversityCard` | No browser-only API usage; safe as a server-renderable component. | + +## Verification + +- Run `pnpm --filter @solid-connect/web build` and confirm the compiled server/client output references `react-compiler-runtime`. +- Run `pnpm --filter @solid-connect/web ci:check` before merging. diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs index cf9c4041..5314198c 100644 --- a/apps/web/next.config.mjs +++ b/apps/web/next.config.mjs @@ -9,7 +9,6 @@ const withBundleAnalyzer = bundleAnalyzer({ /** @type {import('next').NextConfig} */ const nextConfig = { - swcMinify: true, transpilePackages: ["@solid-connect/ai-inspector"], images: { unoptimized: true, @@ -17,16 +16,16 @@ const nextConfig = { formats: ["image/avif", "image/webp"], deviceSizes: [360, 640, 768, 1024, 1280], }, - // 폰트 최적화 설정 - optimizeFonts: true, // 압축 활성화 compress: true, // 정적 리소스 최적화 experimental: { + reactCompiler: { + compilationMode: "annotation", + target: "18", + }, optimizeCss: true, gzipSize: true, - // Sentry instrumentation 활성화 (Web Vitals 수집에 필요) - instrumentationHook: true, optimizePackageImports: [ "lucide-react", "@radix-ui/react-select", diff --git a/apps/web/package.json b/apps/web/package.json index 051704f8..1fde3db6 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "@hookform/resolvers": "^5.2.2", - "@next/third-parties": "^14.2.4", + "@next/third-parties": "^15.5.18", "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-label": "^2.1.2", "@radix-ui/react-progress": "^1.1.2", @@ -37,9 +37,10 @@ "linkify-react": "^4.3.2", "linkifyjs": "^4.3.2", "lucide-react": "^0.479.0", - "next": "^14.2.35", + "next": "^15.5.18", "next-render-analyzer": "^0.1.2", "react": "^18", + "react-compiler-runtime": "1.0.0", "react-dom": "^18", "react-hook-form": "^7.60.0", "react-hot-toast": "^2.6.0", @@ -56,6 +57,7 @@ "@types/react": "19.2.10", "@types/react-dom": "19.2.3", "autoprefixer": "^10.4.20", + "babel-plugin-react-compiler": "1.0.0", "critters": "^0.0.23", "postcss": "^8.4.45", "tailwindcss": "^3.4.10", diff --git a/apps/web/src/app/(home)/_ui/PopularUniversitySection/index.tsx b/apps/web/src/app/(home)/_ui/PopularUniversitySection/index.tsx index 29304d00..c7b40073 100644 --- a/apps/web/src/app/(home)/_ui/PopularUniversitySection/index.tsx +++ b/apps/web/src/app/(home)/_ui/PopularUniversitySection/index.tsx @@ -1,18 +1,6 @@ -import dynamic from "next/dynamic"; -import { Suspense } from "react"; import type { ListUniversity } from "@/types/university"; import PopularUniversityCard from "./_ui/PopularUniversityCard"; -// PopularUniversityCard를 동적 임포트 -const PopularUniversityCardDynamic = dynamic(() => import("./_ui/PopularUniversityCard"), { - ssr: false, - loading: () => ( -
-
-
- ), -}); - type PopularUniversitySectionProps = { universities: ListUniversity[]; }; @@ -38,22 +26,14 @@ const PopularUniversitySection = ({ universities }: PopularUniversitySectionProp {/* 나머지는 동적 렌더링으로 위임 */} {belowFold.map((university) => ( - -
-
- } - > - -
+ university={university} + priority={false} + loading="lazy" + fetchPriority="low" + quality={50} // 지연 로딩 이미지는 50으로 최대 압축 + /> ))}
diff --git a/apps/web/src/app/(home)/page.tsx b/apps/web/src/app/(home)/page.tsx index 38f02a8c..d26b24c0 100644 --- a/apps/web/src/app/(home)/page.tsx +++ b/apps/web/src/app/(home)/page.tsx @@ -1,19 +1,13 @@ import type { Metadata } from "next"; -import nextDynamic from "next/dynamic"; import { getHomeNewsList } from "@/apis/news/server/getNewsList"; import { getCategorizedUniversities, getRecommendedUniversity } from "@/apis/universities/server"; import { type ListUniversity, RegionEnumExtend } from "@/types/university"; import FindLastYearScoreBar from "./_ui/FindLastYearScoreBar"; import HomeEntrySection from "./_ui/HomeEntrySection"; -import NewsSectionSkeleton from "./_ui/NewsSection/skeleton"; +import NewsSection from "./_ui/NewsSection"; import PopularUniversitySection from "./_ui/PopularUniversitySection"; import UniversityList from "./_ui/UniversityList"; -const NewsSectionDynamic = nextDynamic(() => import("./_ui/NewsSection"), { - ssr: false, - loading: () => , -}); - const baseUrl = process.env.NEXT_PUBLIC_WEB_URL || "https://solid-connection.com"; const ogImageUrl = `${baseUrl}/opengraph-image.png`; const homeMetaTitle = "교환학생 사이트 | 솔리드 커넥션 – 교환학생 커뮤니티, 플랫폼"; @@ -106,7 +100,7 @@ const HomePage = async () => { - + ); diff --git a/apps/web/src/app/community/[boardCode]/[postId]/modify/page.tsx b/apps/web/src/app/community/[boardCode]/[postId]/modify/page.tsx index 83ebf24f..ca1b315f 100644 --- a/apps/web/src/app/community/[boardCode]/[postId]/modify/page.tsx +++ b/apps/web/src/app/community/[boardCode]/[postId]/modify/page.tsx @@ -5,18 +5,18 @@ import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; import PostModifyContent from "./PostModifyContent"; interface PostModifyPageProps { - params: { + params: Promise<{ boardCode: string; postId: string; - }; + }>; } export const metadata: Metadata = { title: "글 수정", }; -const PostModifyPage = ({ params }: PostModifyPageProps) => { - const { boardCode, postId } = params; +const PostModifyPage = async ({ params }: PostModifyPageProps) => { + const { boardCode, postId } = await params; return ( <> diff --git a/apps/web/src/app/community/[boardCode]/[postId]/page.tsx b/apps/web/src/app/community/[boardCode]/[postId]/page.tsx index 2780d50b..cd382117 100644 --- a/apps/web/src/app/community/[boardCode]/[postId]/page.tsx +++ b/apps/web/src/app/community/[boardCode]/[postId]/page.tsx @@ -3,19 +3,19 @@ import type { Metadata } from "next"; import PostPageContent from "./PostPageContent"; interface PostPageProps { - params: { + params: Promise<{ boardCode: string; postId: string; - }; + }>; } export const metadata: Metadata = { title: "게시글", }; -const PostPage = ({ params }: PostPageProps) => { - const { boardCode } = params; - const postId = Number(params.postId); +const PostPage = async ({ params }: PostPageProps) => { + const { boardCode, postId: postIdParam } = await params; + const postId = Number(postIdParam); return (
diff --git a/apps/web/src/app/community/[boardCode]/create/page.tsx b/apps/web/src/app/community/[boardCode]/create/page.tsx index 0f5aca6f..a95ec635 100644 --- a/apps/web/src/app/community/[boardCode]/create/page.tsx +++ b/apps/web/src/app/community/[boardCode]/create/page.tsx @@ -4,8 +4,8 @@ export const metadata = { title: "글쓰기", }; -const PostCreatePage = ({ params }: { params: { boardCode: string } }) => { - const { boardCode } = params; +const PostCreatePage = async ({ params }: { params: Promise<{ boardCode: string }> }) => { + const { boardCode } = await params; return (
diff --git a/apps/web/src/app/community/[boardCode]/page.tsx b/apps/web/src/app/community/[boardCode]/page.tsx index 1b60046f..a61b97dc 100644 --- a/apps/web/src/app/community/[boardCode]/page.tsx +++ b/apps/web/src/app/community/[boardCode]/page.tsx @@ -7,13 +7,13 @@ export const metadata: Metadata = { }; interface CommunityPageProps { - params: { + params: Promise<{ boardCode: string; - }; + }>; } -const CommunityPage = ({ params }: CommunityPageProps) => { - const { boardCode } = params; +const CommunityPage = async ({ params }: CommunityPageProps) => { + const { boardCode } = await params; return (
diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 5ba1a256..08208cf0 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -1,13 +1,12 @@ import type { Metadata, Viewport } from "next"; -import dynamic from "next/dynamic"; import localFont from "next/font/local"; import type { ReactNode } from "react"; import { Toaster } from "react-hot-toast"; import GlobalLayout from "@/components/layout/GlobalLayout"; import ReissueProvider from "@/components/layout/ReissueProvider"; - import QueryProvider from "@/lib/react-query/QueryProvider"; +import AppleScriptLoader from "@/lib/ScriptLoader/AppleScriptLoader"; import "@/styles/globals.css"; import { GoogleAnalytics } from "@next/third-parties/google"; import { SpeedInsights } from "@vercel/speed-insights/next"; @@ -39,11 +38,6 @@ const pretendard = localFont({ ], }); -const AppleScriptLoader = dynamic(() => import("@/lib/ScriptLoader/AppleScriptLoader"), { - ssr: false, - loading: () => null, -}); - declare global { interface Window { Kakao: { diff --git a/apps/web/src/app/login/page.tsx b/apps/web/src/app/login/page.tsx index 787674f8..4346dbfd 100644 --- a/apps/web/src/app/login/page.tsx +++ b/apps/web/src/app/login/page.tsx @@ -1,11 +1,6 @@ import type { Metadata } from "next"; -import dynamic from "next/dynamic"; - -const KakaoScriptLoader = dynamic(() => import("@/lib/ScriptLoader/KakaoScriptLoader"), { - ssr: false, - loading: () => null, -}); -const LoginContent = dynamic(() => import("./LoginContent"), { ssr: false }); +import KakaoScriptLoader from "@/lib/ScriptLoader/KakaoScriptLoader"; +import LoginContent from "./LoginContent"; export const metadata: Metadata = { title: "로그인", diff --git a/apps/web/src/app/mentor/[id]/page.tsx b/apps/web/src/app/mentor/[id]/page.tsx index ffda2381..0b34a435 100644 --- a/apps/web/src/app/mentor/[id]/page.tsx +++ b/apps/web/src/app/mentor/[id]/page.tsx @@ -9,11 +9,12 @@ export const metadata: Metadata = { }; interface MentorDetailPageProps { - params: { id: string }; + params: Promise<{ id: string }>; } -const MentorDetailPage = ({ params }: MentorDetailPageProps) => { - const mentorId = Number(params.id); +const MentorDetailPage = async ({ params }: MentorDetailPageProps) => { + const { id } = await params; + const mentorId = Number(id); return (
diff --git a/apps/web/src/app/mentor/chat/[chatId]/page.tsx b/apps/web/src/app/mentor/chat/[chatId]/page.tsx index d1b833ad..f2596a4c 100644 --- a/apps/web/src/app/mentor/chat/[chatId]/page.tsx +++ b/apps/web/src/app/mentor/chat/[chatId]/page.tsx @@ -11,11 +11,12 @@ export const metadata: Metadata = { }; interface ChatDetailPageProps { - params: { chatId: string }; + params: Promise<{ chatId: string }>; } -const ChatDetailPage = ({ params }: ChatDetailPageProps) => { - const chatId = Number(params.chatId); +const ChatDetailPage = async ({ params }: ChatDetailPageProps) => { + const { chatId: chatIdParam } = await params; + const chatId = Number(chatIdParam); if (Number.isNaN(chatId)) notFound(); return ( diff --git a/apps/web/src/app/university/[homeUniversity]/page.tsx b/apps/web/src/app/university/[homeUniversity]/page.tsx index 422c1be0..a8985d77 100644 --- a/apps/web/src/app/university/[homeUniversity]/page.tsx +++ b/apps/web/src/app/university/[homeUniversity]/page.tsx @@ -24,7 +24,7 @@ export async function generateStaticParams() { type PageProps = { params: Promise<{ homeUniversity: string }>; - searchParams?: Record; + searchParams?: Promise>; }; type SearchParamValue = string | string[] | undefined; @@ -80,10 +80,11 @@ export async function generateMetadata({ params }: PageProps): Promise const UniversityListPage = async ({ params, searchParams }: PageProps) => { const { homeUniversity } = await params; - const initialSearchText = getFirstSearchParamValue(searchParams?.searchText).trim(); - const languageTestTypeParam = getFirstSearchParamValue(searchParams?.languageTestType).trim(); - const countryCodeParams = getSearchParamValues(searchParams?.countryCode).filter(isCountryCode); - const regionParams = getSearchParamValues(searchParams?.region).filter(isRegionFilterValue); + const resolvedSearchParams = await searchParams; + const initialSearchText = getFirstSearchParamValue(resolvedSearchParams?.searchText).trim(); + const languageTestTypeParam = getFirstSearchParamValue(resolvedSearchParams?.languageTestType).trim(); + const countryCodeParams = getSearchParamValues(resolvedSearchParams?.countryCode).filter(isCountryCode); + const regionParams = getSearchParamValues(resolvedSearchParams?.region).filter(isRegionFilterValue); const initialRegion = regionParams.length === 1 ? regionParams[0] : RegionEnumExtend.ALL; const languageTestType = isLanguageTestType(languageTestTypeParam) ? languageTestTypeParam : undefined; diff --git a/apps/web/src/app/university/application/apply/page.tsx b/apps/web/src/app/university/application/apply/page.tsx index dbe02f79..9ae1cfb7 100644 --- a/apps/web/src/app/university/application/apply/page.tsx +++ b/apps/web/src/app/university/application/apply/page.tsx @@ -1,18 +1,14 @@ import type { Metadata } from "next"; -import dynamic from "next/dynamic"; +import ApplyPageContent from "./ApplyPageContent"; export const metadata: Metadata = { title: "지원하기", }; -const ApplyPageContentDynamic = dynamic(() => import("./ApplyPageContent"), { - ssr: false, - loading: () => null, -}); const ApplyPage = () => { return (
- +
); }; diff --git a/apps/web/src/app/university/score/page.tsx b/apps/web/src/app/university/score/page.tsx index f8cd1778..013fd7be 100644 --- a/apps/web/src/app/university/score/page.tsx +++ b/apps/web/src/app/university/score/page.tsx @@ -1,9 +1,7 @@ import type { Metadata } from "next"; -import dynamic from "next/dynamic"; import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; - -const ScoreScreen = dynamic(() => import("./ScoreScreen"), { ssr: false }); +import ScoreScreen from "./ScoreScreen"; export const metadata: Metadata = { title: "성적 확인하기", diff --git a/apps/web/src/app/university/score/submit/gpa/_lib/schema.ts b/apps/web/src/app/university/score/submit/gpa/_lib/schema.ts index 2eedcd20..3f48c510 100644 --- a/apps/web/src/app/university/score/submit/gpa/_lib/schema.ts +++ b/apps/web/src/app/university/score/submit/gpa/_lib/schema.ts @@ -3,6 +3,7 @@ import { z } from "zod"; // 1. Zod 스키마 정의: GPA 폼 데이터의 유효성 규칙 const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB const ACCEPTED_FILE_TYPES = ["image/jpeg", "image/png", "application/pdf", "image/webp"]; +const isFileList = (value: unknown): value is FileList => typeof FileList !== "undefined" && value instanceof FileList; export const gpaSchema = z .object({ @@ -11,7 +12,7 @@ export const gpaSchema = z }), gpa: z.string().min(1, "점수를 입력해주세요."), file: z - .instanceof(FileList) + .custom(isFileList, "증명서 파일을 첨부해주세요.") .refine((files) => files?.length === 1, "증명서 파일을 첨부해주세요.") .refine((files) => files?.[0]?.size <= MAX_FILE_SIZE, `파일 크기는 5MB를 초과할 수 없습니다.`) .refine((files) => ACCEPTED_FILE_TYPES.includes(files?.[0]?.type), ".jpeg, .png, .webp, .pdf 파일만 지원합니다."), diff --git a/apps/web/src/app/university/score/submit/gpa/page.tsx b/apps/web/src/app/university/score/submit/gpa/page.tsx index 1007e08e..7845e544 100644 --- a/apps/web/src/app/university/score/submit/gpa/page.tsx +++ b/apps/web/src/app/university/score/submit/gpa/page.tsx @@ -1,9 +1,7 @@ import type { Metadata } from "next"; -import dynamic from "next/dynamic"; import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; - -const ClientGpaForm = dynamic(() => import("./GpaSubmitForm"), { ssr: false }); +import ClientGpaForm from "./GpaSubmitForm"; export const metadata: Metadata = { title: "성적 입력하기", diff --git a/apps/web/src/app/university/score/submit/language-test/_lib/schema.ts b/apps/web/src/app/university/score/submit/language-test/_lib/schema.ts index 44093db1..e8f4d833 100644 --- a/apps/web/src/app/university/score/submit/language-test/_lib/schema.ts +++ b/apps/web/src/app/university/score/submit/language-test/_lib/schema.ts @@ -5,6 +5,7 @@ import validateLanguageScore from "@/utils/scoreUtils"; // 1. Zod 스키마 정의: 폼 데이터의 유효성 규칙 const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB const ACCEPTED_FILE_TYPES = ["image/jpeg", "image/png", "image/webp", "application/pdf"]; +const isFileList = (value: unknown): value is FileList => typeof FileList !== "undefined" && value instanceof FileList; export const languageTestSchema = z .object({ @@ -13,7 +14,7 @@ export const languageTestSchema = z }), score: z.string().min(1, "점수를 입력해주세요."), file: z - .instanceof(FileList) + .custom(isFileList, "증명서 파일을 첨부해주세요.") .refine((files) => files?.length === 1, "증명서 파일을 첨부해주세요.") .refine((files) => files?.[0]?.size <= MAX_FILE_SIZE, `파일 크기는 5MB를 초과할 수 없습니다.`) .refine((files) => ACCEPTED_FILE_TYPES.includes(files?.[0]?.type), ".jpeg, .png, .pdf 파일만 지원합니다."), diff --git a/apps/web/src/app/university/score/submit/language-test/page.tsx b/apps/web/src/app/university/score/submit/language-test/page.tsx index 2ffb8cde..9325c986 100644 --- a/apps/web/src/app/university/score/submit/language-test/page.tsx +++ b/apps/web/src/app/university/score/submit/language-test/page.tsx @@ -1,9 +1,7 @@ import type { Metadata } from "next"; -import dynamic from "next/dynamic"; import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; - -const LanguageTestSubmitForm = dynamic(() => import("./LanguageTestSubmitForm"), { ssr: false }); +import LanguageTestSubmitForm from "./LanguageTestSubmitForm"; export const metadata: Metadata = { title: "성적 입력하기", diff --git a/apps/web/src/app/university/search/page.tsx b/apps/web/src/app/university/search/page.tsx index a019c2cd..ad28e4eb 100644 --- a/apps/web/src/app/university/search/page.tsx +++ b/apps/web/src/app/university/search/page.tsx @@ -1,9 +1,7 @@ import type { Metadata } from "next"; -import dynamic from "next/dynamic"; import TopDetailNavigation from "@/components/layout/TopDetailNavigation"; - -const SearchClientContent = dynamic(() => import("./SearchClientContent"), { ssr: false }); +import SearchClientContent from "./SearchClientContent"; export const metadata: Metadata = { title: "파견 학교 목록", diff --git a/apps/web/src/components/layout/GlobalLayout/index.tsx b/apps/web/src/components/layout/GlobalLayout/index.tsx index 4db968f5..537b7f25 100644 --- a/apps/web/src/components/layout/GlobalLayout/index.tsx +++ b/apps/web/src/components/layout/GlobalLayout/index.tsx @@ -1,14 +1,11 @@ -import dynamic from "next/dynamic"; import type { ReactNode } from "react"; +import AIInspectorFab from "./ui/AIInspectorFab"; import BottomNavigation from "./ui/BottomNavigation"; +import ClientModal from "./ui/ClientModal"; // import ServerModal from "./ui/ServerModal"; -// const BottomNavigationDynamic = dynamic(() => import("./ui/BottomNavigation"), { ssr: false, loading: () => null }); -const AIInspectorFab = dynamic(() => import("./ui/AIInspectorFab/index"), { ssr: false, loading: () => null }); -const ClientModal = dynamic(() => import("./ui/ClientModal"), { ssr: false, loading: () => null }); - type LayoutProps = { children: ReactNode; }; diff --git a/apps/web/src/components/ui/ChannelBadge.tsx b/apps/web/src/components/ui/ChannelBadge.tsx index 55fc978a..376204e3 100644 --- a/apps/web/src/components/ui/ChannelBadge.tsx +++ b/apps/web/src/components/ui/ChannelBadge.tsx @@ -6,6 +6,8 @@ interface ChannelBadgeProps { } const ChannelBadge = ({ channelType, text }: ChannelBadgeProps) => { + "use memo"; + return (
{ - const cookieStore = cookies(); +const isServerStateLogin = async (): Promise => { + const cookieStore = await cookies(); const refreshToken = cookieStore.get("refreshToken")?.value; const isLogin = !!(refreshToken && !isTokenExpired(refreshToken)); return isLogin; diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 6631e2db..99930c23 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -9,6 +9,7 @@ "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", + "target": "ES2017", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e28b482f..1142beef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -107,7 +107,7 @@ importers: version: 1.5.4 '@vitejs/plugin-react': specifier: ^6.0.2 - version: 6.0.2(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitejs/plugin-rsc': specifier: ^0.5.26 version: 0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) @@ -125,7 +125,7 @@ importers: version: 5.9.3 vinext: specifier: ^0.0.51 - version: 0.0.51(@vitejs/plugin-react@6.0.2(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(next@14.2.35(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.0.51(@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(next@14.2.35(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) vite: specifier: ^8.0.14 version: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) @@ -142,8 +142,8 @@ importers: specifier: ^5.2.2 version: 5.2.2(react-hook-form@7.71.1(react@18.3.1)) '@next/third-parties': - specifier: ^14.2.4 - version: 14.2.35(next@14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + specifier: ^15.5.18 + version: 15.5.18(next@15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@radix-ui/react-checkbox': specifier: ^1.1.4 version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -161,7 +161,7 @@ importers: version: 2.20.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@sentry/nextjs': specifier: ^10.22.0 - version: 10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.104.1) + version: 10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.104.1) '@solid-connect/ai-inspector': specifier: workspace:^ version: link:../../packages/ai-inspector @@ -179,7 +179,7 @@ importers: version: 3.13.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@vercel/speed-insights': specifier: ^1.3.1 - version: 1.3.1(next@14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 1.3.1(next@15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) axios: specifier: ^1.6.7 version: 1.13.2 @@ -202,14 +202,17 @@ importers: specifier: ^0.479.0 version: 0.479.0(react@18.3.1) next: - specifier: ^14.2.35 - version: 14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^15.5.18 + version: 15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-render-analyzer: specifier: ^0.1.2 version: 0.1.2 react: specifier: ^18 version: 18.3.1 + react-compiler-runtime: + specifier: 1.0.0 + version: 1.0.0(react@18.3.1) react-dom: specifier: ^18 version: 18.3.1(react@18.3.1) @@ -253,6 +256,9 @@ importers: autoprefixer: specifier: ^10.4.20 version: 10.4.23(postcss@8.5.6) + babel-plugin-react-compiler: + specifier: 1.0.0 + version: 1.0.0 critters: specifier: ^0.0.23 version: 0.0.23 @@ -1357,6 +1363,143 @@ packages: peerDependencies: react-hook-form: ^7.55.0 + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1395,48 +1538,93 @@ packages: '@next/env@14.2.35': resolution: {integrity: sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ==} + '@next/env@15.5.18': + resolution: {integrity: sha512-hAV85Ckd9QR6RvH04MEKwsfLTksvFpO47j9xwtoIuvuPnlwecpSi+uZTtm8HirVbtlI2Fnz//xpcSTjFdyJk+g==} + '@next/swc-darwin-arm64@14.2.33': resolution: {integrity: sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] + '@next/swc-darwin-arm64@15.5.18': + resolution: {integrity: sha512-w0WvQf1n+txiwns/9pwIQteCJpZTbxzO2SE0FLcwuD4v0WEh1JPOjdyxWL21XwJsdpx8cFRjyzxzCS/siP7HcQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@next/swc-darwin-x64@14.2.33': resolution: {integrity: sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] + '@next/swc-darwin-x64@15.5.18': + resolution: {integrity: sha512-znn71QmDuxm+BOaglihMZfvyySMnNljkVIY5Z2TCssBmm+WqL6c19VhtH5ktFkHa8EZ2bnTUpcNcmNSQsg67og==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@next/swc-linux-arm64-gnu@14.2.33': resolution: {integrity: sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-gnu@15.5.18': + resolution: {integrity: sha512-yPPe5MNL+igZUa+OsqQJisqSfh6oarIuA1Q0BDxljGJhRQyZeP+WRHh7rs/jZUGMh5aY0YdIjXZG0VohkKkUdw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-arm64-musl@14.2.33': resolution: {integrity: sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@next/swc-linux-arm64-musl@15.5.18': + resolution: {integrity: sha512-glaCczEWIrHsokFZ3pP08U4BpKxwIdnT+txdOM32OBgpL9Yw4aqx8NejmgtZQZOdstQ5f0L3CasIZudzCuD+nw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@next/swc-linux-x64-gnu@14.2.33': resolution: {integrity: sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-gnu@15.5.18': + resolution: {integrity: sha512-oUfg2EgJmU3R0OCOWiokGFUTvZiPfXtriXiuF3YNxRoROCdgvTedHIzYoeKH34gsZxS/V7mHbfq2hpAHwhH1/A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-linux-x64-musl@14.2.33': resolution: {integrity: sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@next/swc-linux-x64-musl@15.5.18': + resolution: {integrity: sha512-JLxSP3KTd9iu/bvUMQxH7RJo9xKSHf55/6RPE4a6FTSZygGn7uvZbCej0AHXydwkggQGSD9UddSjwv6Xz5ESfA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@next/swc-win32-arm64-msvc@14.2.33': resolution: {integrity: sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] + '@next/swc-win32-arm64-msvc@15.5.18': + resolution: {integrity: sha512-ir1v7enP52K2HNz3tQQvwF+x7VNxBk1ciiZ18WBPvxf4C59IqdfmHPJYK3vH7rSxpuCVw/8C712wTXNAtEp+NA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@next/swc-win32-ia32-msvc@14.2.33': resolution: {integrity: sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==} engines: {node: '>= 10'} @@ -1449,11 +1637,17 @@ packages: cpu: [x64] os: [win32] - '@next/third-parties@14.2.35': - resolution: {integrity: sha512-dG1J+4uYungW1snGViN7tAVyfO0iz0zoB+sqsLMUo8kwR0NED2muLTMbOChmrliHhzOFj6ZpHfkvhy5NJjFvSQ==} + '@next/swc-win32-x64-msvc@15.5.18': + resolution: {integrity: sha512-LIu5me6QTANCd25E7I5uIEfvgQ06RK7tvHAbYo3zCb3VpxQEPvMcSpd87NwUABDT6MbGPdEGR5VRiK4PPTJhQg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@next/third-parties@15.5.18': + resolution: {integrity: sha512-Kp51CbeHgYelpkasFI1gAeAeMPfMTctLcmVIfE2MiRRfC6oYbR3+lO4S0NbNRppOZ7RkbB5P6uW/qOewxth6iA==} peerDependencies: - next: ^13.0.0 || ^14.0.0 - react: ^18.2.0 + next: ^13.0.0 || ^14.0.0 || ^15.0.0 + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -2541,6 +2735,9 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@swc/helpers@0.5.5': resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} @@ -3049,6 +3246,9 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + babel-plugin-react-compiler@1.0.0: + resolution: {integrity: sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -4400,6 +4600,27 @@ packages: sass: optional: true + next@15.5.18: + resolution: {integrity: sha512-eKL8zUJkX9Y5lE+RX/2YJoItVdGlIscyVyboeD9wSpp0PaGqjoA4tTpT2qPqz9ax+5IzGESyLSeZ/RCwbSZ2uQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + nf3@0.3.17: resolution: {integrity: sha512-N9zEWySuJFw+gR0lhS5863YsvNeudOdqRyFvNb+jMXbeTJOdrjDqkCpDginIZfUm0LzT1t1nCRiDeqQm/8kirQ==} @@ -4703,6 +4924,11 @@ packages: randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + react-compiler-runtime@1.0.0: + resolution: {integrity: sha512-rRfjYv66HlG8896yPUDONgKzG5BxZD1nV9U6rkm+7VCuvQc903C4MjcoZR4zPw53IKSOX9wMQVpA1IAbRtzQ7w==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -4900,6 +5126,10 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -5016,6 +5246,19 @@ packages: babel-plugin-macros: optional: true + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + sucrase@3.35.1: resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} @@ -6937,6 +7180,103 @@ snapshots: '@standard-schema/utils': 0.3.0 react-hook-form: 7.71.1(react@18.3.1) + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -6987,38 +7327,65 @@ snapshots: - bufferutil - utf-8-validate - '@next/env@14.2.35': {} + '@next/env@14.2.35': + optional: true + + '@next/env@15.5.18': {} '@next/swc-darwin-arm64@14.2.33': optional: true + '@next/swc-darwin-arm64@15.5.18': + optional: true + '@next/swc-darwin-x64@14.2.33': optional: true + '@next/swc-darwin-x64@15.5.18': + optional: true + '@next/swc-linux-arm64-gnu@14.2.33': optional: true + '@next/swc-linux-arm64-gnu@15.5.18': + optional: true + '@next/swc-linux-arm64-musl@14.2.33': optional: true + '@next/swc-linux-arm64-musl@15.5.18': + optional: true + '@next/swc-linux-x64-gnu@14.2.33': optional: true + '@next/swc-linux-x64-gnu@15.5.18': + optional: true + '@next/swc-linux-x64-musl@14.2.33': optional: true + '@next/swc-linux-x64-musl@15.5.18': + optional: true + '@next/swc-win32-arm64-msvc@14.2.33': optional: true + '@next/swc-win32-arm64-msvc@15.5.18': + optional: true + '@next/swc-win32-ia32-msvc@14.2.33': optional: true '@next/swc-win32-x64-msvc@14.2.33': optional: true - '@next/third-parties@14.2.35(next@14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@next/swc-win32-x64-msvc@15.5.18': + optional: true + + '@next/third-parties@15.5.18(next@15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: - next: 14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 third-party-capital: 1.0.20 @@ -8003,7 +8370,7 @@ snapshots: '@sentry/core@10.34.0': {} - '@sentry/nextjs@10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.104.1)': + '@sentry/nextjs@10.34.0(@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0))(next@15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.104.1)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.39.0 @@ -8016,7 +8383,7 @@ snapshots: '@sentry/react': 10.34.0(react@18.3.1) '@sentry/vercel-edge': 10.34.0 '@sentry/webpack-plugin': 4.6.2(webpack@5.104.1) - next: 14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rollup: 4.55.1 stacktrace-parser: 0.1.11 transitivePeerDependencies: @@ -8217,12 +8584,18 @@ snapshots: - supports-color - typescript - '@swc/counter@0.1.3': {} + '@swc/counter@0.1.3': + optional: true + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 '@swc/helpers@0.5.5': dependencies: '@swc/counter': 0.1.3 tslib: 2.8.1 + optional: true '@tailwindcss/node@4.1.18': dependencies: @@ -8461,15 +8834,17 @@ snapshots: '@resvg/resvg-wasm': 2.4.0 satori: 0.16.0 - '@vercel/speed-insights@1.3.1(next@14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@vercel/speed-insights@1.3.1(next@15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': optionalDependencies: - next: 14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 - '@vitejs/plugin-react@6.0.2(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@rolldown/pluginutils': 1.0.1 vite: 8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + optionalDependencies: + babel-plugin-react-compiler: 1.0.0 '@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: @@ -8747,6 +9122,10 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-react-compiler@1.0.0: + dependencies: + '@babel/types': 7.28.6 + balanced-match@1.0.2: {} base64-js@0.0.8: {} @@ -8788,6 +9167,7 @@ snapshots: busboy@1.6.0: dependencies: streamsearch: 1.1.0 + optional: true cac@6.7.14: {} @@ -10024,7 +10404,7 @@ snapshots: transitivePeerDependencies: - supports-color - next@14.2.35(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.35(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@next/env': 14.2.35 '@swc/helpers': 0.5.5 @@ -10032,9 +10412,9 @@ snapshots: caniuse-lite: 1.0.30001764 graceful-fs: 4.2.11 postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(@babel/core@7.28.6)(react@18.3.1) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + styled-jsx: 5.1.1(react@19.2.6) optionalDependencies: '@next/swc-darwin-arm64': 14.2.33 '@next/swc-darwin-x64': 14.2.33 @@ -10049,33 +10429,32 @@ snapshots: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros + optional: true - next@14.2.35(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + next@15.5.18(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 14.2.35 - '@swc/helpers': 0.5.5 - busboy: 1.6.0 + '@next/env': 15.5.18 + '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001764 - graceful-fs: 4.2.11 postcss: 8.4.31 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - styled-jsx: 5.1.1(react@19.2.6) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(@babel/core@7.28.6)(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.33 - '@next/swc-darwin-x64': 14.2.33 - '@next/swc-linux-arm64-gnu': 14.2.33 - '@next/swc-linux-arm64-musl': 14.2.33 - '@next/swc-linux-x64-gnu': 14.2.33 - '@next/swc-linux-x64-musl': 14.2.33 - '@next/swc-win32-arm64-msvc': 14.2.33 - '@next/swc-win32-ia32-msvc': 14.2.33 - '@next/swc-win32-x64-msvc': 14.2.33 + '@next/swc-darwin-arm64': 15.5.18 + '@next/swc-darwin-x64': 15.5.18 + '@next/swc-linux-arm64-gnu': 15.5.18 + '@next/swc-linux-arm64-musl': 15.5.18 + '@next/swc-linux-x64-gnu': 15.5.18 + '@next/swc-linux-x64-musl': 15.5.18 + '@next/swc-win32-arm64-msvc': 15.5.18 + '@next/swc-win32-x64-msvc': 15.5.18 '@opentelemetry/api': 1.9.0 + babel-plugin-react-compiler: 1.0.0 + sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - optional: true nf3@0.3.17: {} @@ -10300,7 +10679,7 @@ snapshots: postcss@8.4.31: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -10367,6 +10746,10 @@ snapshots: dependencies: safe-buffer: 5.2.1 + react-compiler-runtime@1.0.0(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -10611,6 +10994,38 @@ snapshots: dependencies: randombytes: 2.1.0 + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -10676,7 +11091,8 @@ snapshots: stream-shift@1.0.3: optional: true - streamsearch@1.1.0: {} + streamsearch@1.1.0: + optional: true string-width@4.2.3: dependencies: @@ -10715,19 +11131,19 @@ snapshots: stubs@3.0.0: optional: true - styled-jsx@5.1.1(@babel/core@7.28.6)(react@18.3.1): - dependencies: - client-only: 0.0.1 - react: 18.3.1 - optionalDependencies: - '@babel/core': 7.28.6 - styled-jsx@5.1.1(react@19.2.6): dependencies: client-only: 0.0.1 react: 19.2.6 optional: true + styled-jsx@5.1.6(@babel/core@7.28.6)(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + optionalDependencies: + '@babel/core': 7.28.6 + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -11032,11 +11448,11 @@ snapshots: uuid@9.0.1: {} - vinext@0.0.51(@vitejs/plugin-react@6.0.2(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(next@14.2.35(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vinext@0.0.51(@vitejs/plugin-react@6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(@vitejs/plugin-rsc@0.5.26(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(next@14.2.35(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react-server-dom-webpack@19.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(webpack@5.104.1(esbuild@0.27.2)))(react@19.2.6)(typescript@5.9.3)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@unpic/react': 1.0.2(next@14.2.35(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@vercel/og': 0.8.6 - '@vitejs/plugin-react': 6.0.2(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-react': 6.0.2(babel-plugin-react-compiler@1.0.0)(vite@8.0.14(@types/node@22.19.7)(esbuild@0.27.2)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) image-size: 2.0.2 ipaddr.js: 2.4.0 magic-string: 0.30.21