diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..35596405
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+node_modules/
+.next/
+.env
+.env.local
+.DS_Store
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
\ No newline at end of file
diff --git a/README.md b/README.md
index fc259f87..b341a0bf 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
# ๐ผ ํ๋ค๋ง์ผ ํ๋ก์ ํธ
> _์ด ์ ์ฅ์๋ ํ๋ค๋ง์ผ ํ๋ก์ ํธ์ ํ๋ก ํธ์๋ ์ฝ๋๋ฅผ ๊ด๋ฆฌํ๋ ๊ณณ์
๋๋ค. ํ๋ก์ ํธ๋ฅผ ํด๋ก ํ์ฌ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ค์ ํ๊ณ , ๊ฐ ๋ธ๋์น์์ ํด๋น ์คํ๋ฆฐํธ ๋ฏธ์
์ ์ํํด ์ฃผ์ธ์!_ ๐ ๏ธ
@@ -48,3 +49,21 @@ _์ ์ด๋ฏธ์ง๋ ํ๋ค๋ง์ผ์ ๋ํ ์ด๋ฏธ์ง์
๋๋ค._ ๐ธ
---
๋ณธ ํ๋ก์ ํธ๋ [์ฝ๋์](https://www.codeit.kr)์ ์์ ์ด๋ฉฐ, ๊ต์ก ๋ชฉ์ ์ผ๋ก๋ง ์ฌ์ฉ๋ฉ๋๋ค. ยฉ 2024 Codeit. All rights reserved.
+=======
+# React + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+
+Currently, two official plugins are available:
+
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+
+## React Compiler
+
+The React Compiler is not enabled on this template. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
+
+## Expanding the ESLint configuration
+
+If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
+>>>>>>> d825b2c (CSS ๋ฆฌํฉํ ๋ง ๋ฐ ์ด๋ฏธ์ง ๊ด๋ฆฌ ๊ตฌ์กฐ ๊ฐ์ )
diff --git a/app/board/[id]/page.js b/app/board/[id]/page.js
new file mode 100644
index 00000000..8fdad135
--- /dev/null
+++ b/app/board/[id]/page.js
@@ -0,0 +1,360 @@
+'use client';
+
+import { useState, useEffect } from 'react';
+import Link from 'next/link';
+import Image from 'next/image';
+import { useRouter, useParams } from 'next/navigation';
+
+export default function PostDetailPage() {
+ const router = useRouter();
+ const params = useParams();
+ const postId = params?.id;
+
+ const [post, setPost] = useState(null);
+ const [comments, setComments] = useState([]);
+ const [commentInput, setCommentInput] = useState('');
+ const [editingCommentId, setEditingCommentId] = useState(null);
+ const [editingContent, setEditingContent] = useState('');
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ if (postId) {
+ fetchPostDetail();
+ fetchComments();
+ }
+ }, [postId]);
+
+ const fetchPostDetail = async () => {
+ try {
+ const response = await fetch(`https://panda-market-api.vercel.app/articles/${postId}`);
+ if (response.ok) {
+ const data = await response.json();
+ setPost(data);
+ }
+ } catch (error) {
+ console.error('๊ฒ์๊ธ ๋ก๋ ์คํจ:', error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const fetchComments = async () => {
+ try {
+ const response = await fetch(`https://panda-market-api.vercel.app/articles/${postId}/comments`);
+ if (response.ok) {
+ const data = await response.json();
+ setComments(data.list || []);
+ }
+ } catch (error) {
+ console.error('๋๊ธ ๋ก๋ ์คํจ:', error);
+ }
+ };
+
+ const handleCommentSubmit = async () => {
+ if (!commentInput.trim()) return;
+
+ try {
+ const response = await fetch(`https://panda-market-api.vercel.app/articles/${postId}/comments`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ content: commentInput.trim() }),
+ });
+
+ if (response.ok) {
+ setCommentInput('');
+ fetchComments();
+ }
+ } catch (error) {
+ console.error('๋๊ธ ๋ฑ๋ก ์คํจ:', error);
+ }
+ };
+
+ const handleCommentEdit = async (commentId) => {
+ if (!editingContent.trim()) return;
+
+ try {
+ const response = await fetch(`https://panda-market-api.vercel.app/comments/${commentId}`, {
+ method: 'PATCH',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ content: editingContent.trim() }),
+ });
+
+ if (response.ok) {
+ setEditingCommentId(null);
+ setEditingContent('');
+ fetchComments();
+ }
+ } catch (error) {
+ console.error('๋๊ธ ์์ ์คํจ:', error);
+ }
+ };
+
+ const handleCommentDelete = async (commentId) => {
+ if (!confirm('๋๊ธ์ ์ญ์ ํ์๊ฒ ์ต๋๊น?')) return;
+
+ try {
+ const response = await fetch(`https://panda-market-api.vercel.app/comments/${commentId}`, {
+ method: 'DELETE',
+ });
+
+ if (response.ok) {
+ fetchComments();
+ }
+ } catch (error) {
+ console.error('๋๊ธ ์ญ์ ์คํจ:', error);
+ }
+ };
+
+ const handlePostDelete = async () => {
+ if (!confirm('๊ฒ์๊ธ์ ์ญ์ ํ์๊ฒ ์ต๋๊น?')) return;
+
+ try {
+ const response = await fetch(`https://panda-market-api.vercel.app/articles/${postId}`, {
+ method: 'DELETE',
+ });
+
+ if (response.ok) {
+ alert('๊ฒ์๊ธ์ด ์ญ์ ๋์์ต๋๋ค.');
+ router.push('/board');
+ }
+ } catch (error) {
+ console.error('๊ฒ์๊ธ ์ญ์ ์คํจ:', error);
+ }
+ };
+
+ const formatDate = (dateString) => {
+ if (!dateString) return '';
+ const date = new Date(dateString);
+ return date.toLocaleDateString('ko-KR', { year: 'numeric', month: '2-digit', day: '2-digit' }).replace(/\. /g, '. ');
+ };
+
+ if (loading) {
+ return (
+
+
+
+
+
+
+
+ ์์ ๊ฒ์ํ
+ ์ค๊ณ ๋ง์ผ
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+ ๊ฒ์๊ธ์ ๋ถ๋ฌ์ค๋ ์ค์
๋๋ค...
+
+
+ );
+ }
+
+ if (!post) {
+ return (
+
+
+
+
+
+
+
+ ์์ ๊ฒ์ํ
+ ์ค๊ณ ๋ง์ผ
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+ ๊ฒ์๊ธ์ ์ฐพ์ ์ ์์ต๋๋ค.
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+ ์์ ๊ฒ์ํ
+
+
+ ์ค๊ณ ๋ง์ผ
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
+
+
+
+ โ ๋ชฉ๋ก์ผ๋ก
+
+
+
+ {post.title}
+
+ {post.image && (
+
+
{
+ e.target.style.display = 'none';
+ }}
+ />
+
+ )}
+
+
+
+ ํ๋ค๋ง์ผ
+ {formatDate(post.createdAt)}
+
+
+ ๐ค {post.likeCount || 0}
+
+ ์ญ์
+
+
+
+
+
+ {post.content}
+
+
+
+
+
+ ๋๊ธ ({comments.length})
+
+
+
+
+
+ {comments.map((comment) => (
+
+ {editingCommentId === comment.id ? (
+
+ ) : (
+
+
+
+ ํ๋ค๋ง์ผ
+ {formatDate(comment.createdAt)}
+
+
+ {
+ setEditingCommentId(comment.id);
+ setEditingContent(comment.content);
+ }}
+ className="text-[14px] text-[#6b7280] hover:text-[#111827]"
+ >
+ ์์
+
+ handleCommentDelete(comment.id)}
+ className="text-[14px] text-[#dc2626] hover:text-[#991b1b]"
+ >
+ ์ญ์
+
+
+
+
{comment.content}
+
+ )}
+
+ ))}
+
+
+
+
+
+
+
+
+
ยฉcodeit - 2024
+
+ Privacy Policy
+ FAQ
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/board/page.js b/app/board/page.js
new file mode 100644
index 00000000..7a70e297
--- /dev/null
+++ b/app/board/page.js
@@ -0,0 +1,258 @@
+'use client';
+
+import { useState, useEffect } from 'react';
+import Link from 'next/link';
+import Image from 'next/image';
+import { useRouter } from 'next/navigation';
+
+export default function BoardPage() {
+ const router = useRouter();
+ const [posts, setPosts] = useState([]);
+ const [bestPosts, setBestPosts] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [orderBy, setOrderBy] = useState('recent');
+ const [searchKeyword, setSearchKeyword] = useState('');
+ const [inputValue, setInputValue] = useState('');
+
+ useEffect(() => {
+ const fetchBestPosts = async () => {
+ try {
+ const response = await fetch('https://panda-market-api.vercel.app/articles?orderBy=like&pageSize=3');
+ const data = await response.json();
+ setBestPosts(data.list || []);
+ } catch (error) {
+ console.error('๋ฒ ์คํธ ๊ฒ์๊ธ ๋ก๋ ์คํจ:', error);
+ }
+ };
+
+ fetchBestPosts();
+ }, []);
+
+ useEffect(() => {
+ const fetchPosts = async () => {
+ setLoading(true);
+ try {
+ let url = `https://panda-market-api.vercel.app/articles?orderBy=${orderBy}&pageSize=10`;
+
+ if (searchKeyword) {
+ url += `&keyword=${encodeURIComponent(searchKeyword)}`;
+ }
+
+ const response = await fetch(url);
+ const data = await response.json();
+ setPosts(data.list || []);
+ } catch (error) {
+ console.error('๊ฒ์๊ธ ๋ก๋ ์คํจ:', error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchPosts();
+ }, [orderBy, searchKeyword]);
+
+ const handleSearch = () => {
+ setSearchKeyword(inputValue);
+ };
+
+ const handleKeyPress = (e) => {
+ if (e.key === 'Enter') {
+ handleSearch();
+ }
+ };
+
+ const handleSortChange = (e) => {
+ setOrderBy(e.target.value);
+ };
+
+ const handlePostClick = (postId) => {
+ router.push(`/board/${postId}`);
+ };
+
+ const formatDate = (dateString) => {
+ if (!dateString) return '';
+ const date = new Date(dateString);
+ return date.toLocaleDateString('ko-KR', { year: 'numeric', month: '2-digit', day: '2-digit' }).replace(/\. /g, '. ');
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ ์์ ๊ฒ์ํ
+
+
+ ์ค๊ณ ๋ง์ผ
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
+
+
+
+ ๋ฒ ์คํธ ๊ฒ์๊ธ
+
+ {bestPosts.length === 0 ? (
+
+ ๋ฒ ์คํธ ๊ฒ์๊ธ์ ๋ถ๋ฌ์ค๋ ์ค์
๋๋ค...
+
+ ) : (
+
+ {bestPosts.map((post) => (
+
handlePostClick(post.id)}
+ >
+
+ โญ Best
+
+
+
+
+
{post.title}
+
+
+
+ {post.image && (
+
{
+ e.target.style.display = 'none';
+ }}
+ />
+ )}
+
+
+
+
+
ํ๋ค๋ง์ผ
+
+ ๐ค {post.likeCount || 0}+
+ {formatDate(post.createdAt)}
+
+
+
+ ))}
+
+ )}
+
+
+
+
+
+
๊ฒ์๊ธ
+
+
+
+ + ๊ธ์ฐ๊ธฐ
+
+
+
+
+
+ setInputValue(e.target.value)}
+ onKeyPress={handleKeyPress}
+ />
+
+
+ ์ต์ ์
+ ์ข์์์
+
+
+
+ {loading ? (
+
๊ฒ์๊ธ์ ๋ถ๋ฌ์ค๋ ์ค์
๋๋ค...
+ ) : posts.length === 0 ? (
+
๋ฑ๋ก๋ ๊ฒ์๊ธ์ด ์์ต๋๋ค.
+ ) : (
+
+ {posts.map((post) => (
+
handlePostClick(post.id)}
+ >
+
+
{post.title}
+
+ ํ๋ค๋ง์ผ
+ {formatDate(post.createdAt)}
+ ๐ค {post.likeCount || 0}+
+
+
+
+ {post.image && (
+
{
+ e.target.style.display = 'none';
+ }}
+ />
+ )}
+
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+
+
ยฉcodeit - 2024
+
+ Privacy Policy
+ FAQ
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/board/write/page.jsx b/app/board/write/page.jsx
new file mode 100644
index 00000000..e607268d
--- /dev/null
+++ b/app/board/write/page.jsx
@@ -0,0 +1,145 @@
+'use client';
+
+import { useState } from 'react';
+import Link from 'next/link';
+import Image from 'next/image';
+import { useRouter } from 'next/navigation';
+
+export default function WritePostPage() {
+ const router = useRouter();
+ const [title, setTitle] = useState('');
+ const [content, setContent] = useState('');
+ const [isSubmitting, setIsSubmitting] = useState(false);
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+
+ if (!title.trim() || !content.trim()) {
+ alert('์ ๋ชฉ๊ณผ ๋ด์ฉ์ ๋ชจ๋ ์
๋ ฅํด์ฃผ์ธ์.');
+ return;
+ }
+
+ setIsSubmitting(true);
+
+ try {
+ const response = await fetch('https://panda-market-api.vercel.app/articles', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ title: title.trim(),
+ content: content.trim(),
+ }),
+ });
+
+ if (response.ok) {
+ alert('๊ฒ์๊ธ์ด ๋ฑ๋ก๋์์ต๋๋ค.');
+ router.push('/board');
+ } else {
+ alert('๊ฒ์๊ธ ๋ฑ๋ก์ ์คํจํ์ต๋๋ค.');
+ }
+ } catch (error) {
+ console.error('๊ฒ์๊ธ ๋ฑ๋ก ์คํจ:', error);
+ alert('๊ฒ์๊ธ ๋ฑ๋ก ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.');
+ } finally {
+ setIsSubmitting(false);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ ์์ ๊ฒ์ํ
+
+
+ ์ค๊ณ ๋ง์ผ
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
+
+
+
+
๊ฒ์๊ธ ์ฐ๊ธฐ
+
+ {isSubmitting ? '๋ฑ๋ก ์ค...' : '๋ฑ๋ก'}
+
+
+
+
+
+
+
+
+
+
+
ยฉcodeit - 2024
+
+ Privacy Policy
+ FAQ
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/globals.css b/app/globals.css
new file mode 100644
index 00000000..c1ce9a33
--- /dev/null
+++ b/app/globals.css
@@ -0,0 +1,906 @@
+@import "tailwindcss";
+
+/* ===== ๊ธฐ๋ณธ ์ค์ ===== */
+body {
+ font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ line-height: 1.5;
+ color: #333;
+ background: #fff;
+ margin: 0;
+ padding: 0;
+}
+
+/* ===== ํค๋ ๋ค๋น๊ฒ์ด์
===== */
+.header-nav {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 70px;
+ background: #ffffff;
+ border-bottom: 1px solid #dfdfdf;
+ z-index: 1000;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.nav-container {
+ width: 100%;
+ max-width: 1200px;
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ padding: 0 100px;
+ gap: 0;
+}
+
+.brand-logo {
+ width: 200px;
+ height: 67px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ flex-shrink: 0;
+ margin-right: 40px;
+}
+
+.brand-logo img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+.nav-menu-group {
+ display: flex;
+ gap: 24px;
+ align-items: center;
+ margin-left: 20px;
+}
+
+.board-link,
+.market-link {
+ color: #374151;
+ text-decoration: none;
+ font-size: 16px;
+ font-weight: 500;
+ transition: color 0.2s;
+}
+
+.board-link:hover,
+.market-link:hover {
+ color: #3b82f6;
+}
+
+.board-link.active,
+.market-link.active {
+ color: #3b82f6;
+}
+
+.nav-right {
+ margin-left: auto;
+}
+
+.login-button {
+ background: #3b82f6;
+ color: white;
+ padding: 12px 24px;
+ border: none;
+ border-radius: 8px;
+ font-size: 16px;
+ cursor: pointer;
+ text-decoration: none;
+ transition: background-color 0.2s;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.login-button:hover {
+ background: #2563eb;
+}
+
+/* ===== ํ์ด์ง ๋ ์ด์์ ===== */
+.page-container {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.main-content {
+ flex: 1;
+ margin-top: 70px;
+ padding-top: 60px;
+}
+
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 0 20px;
+}
+
+.center-container {
+ display: flex;
+ justify-content: center;
+ align-items: flex-start;
+}
+
+/* ===== ํผ ๊ณตํต ์คํ์ผ ===== */
+.form-container {
+ width: 640px;
+ background: transparent;
+ display: flex;
+ flex-direction: column;
+ margin: 0 auto;
+}
+
+.form-logo {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 28px;
+}
+
+.form-logo img {
+ width: 396px;
+ height: 132px;
+ object-fit: contain;
+}
+
+.input-group {
+ margin: 14px 0;
+}
+
+.input-label {
+ font-size: 13px;
+ font-weight: 700;
+ color: #374151;
+ margin-bottom: 6px;
+ display: block;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.text-input {
+ width: 100%;
+ height: 48px;
+ padding: 0 16px;
+ font-size: 16px;
+ border: 1px solid #e5e7eb;
+ border-radius: 12px;
+ background: #f3f4f6;
+ box-sizing: border-box;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.text-input:focus {
+ outline: none;
+ border-color: #3692ff;
+ background: #fff;
+ box-shadow: 0 0 0 3px rgba(54, 146, 255, 0.12);
+}
+
+.text-input::placeholder {
+ color: #9ca3af;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.text-input.error {
+ border-color: #dc2626 !important;
+ background: #fef2f2;
+}
+
+.error-message {
+ color: #dc2626;
+ font-size: 12px;
+ font-weight: 400;
+ margin-top: 4px;
+ margin-bottom: 8px;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.password-container {
+ position: relative;
+}
+
+.password-toggle-button {
+ position: absolute;
+ right: 10px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 36px;
+ height: 36px;
+ border: none;
+ background: #e5e7eb;
+ color: #6b7280;
+ border-radius: 8px;
+ cursor: pointer;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.submit-button {
+ width: 100%;
+ height: 48px;
+ border: none;
+ border-radius: 9999px;
+ font-size: 16px;
+ font-weight: 700;
+ color: #fff;
+ background: #9ca3af;
+ cursor: not-allowed;
+ margin-top: 10px;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.submit-button.active {
+ background: #3692ff;
+ cursor: pointer;
+}
+
+/* ===== ์์
๋ก๊ทธ์ธ ===== */
+.social-login-bar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background: #eaf3ff;
+ border-radius: 12px;
+ padding: 12px 16px;
+ margin-top: 16px;
+}
+
+.social-login-text {
+ font-size: 14px;
+ color: #374151;
+ font-weight: 500;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.social-icons-container {
+ display: flex;
+ gap: 12px;
+}
+
+.social-icon-link {
+ width: 44px;
+ height: 44px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 700;
+ font-size: 16px;
+ text-decoration: none;
+ border: 1px solid #d1d5db;
+ background: #fff;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.social-icon-link.google {
+ color: #4285f4;
+}
+
+.social-icon-link.kakao {
+ background: #fee500;
+ color: #3c1e1e;
+ border: none;
+}
+
+.bottom-navigation-link {
+ text-align: center;
+ margin-top: 12px;
+ font-size: 13px;
+ color: #6b7280;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.bottom-navigation-link a {
+ color: #3692ff;
+ text-decoration: none;
+ font-weight: 700;
+}
+
+/* ===== ๋น ํ์ด์ง ์คํ์ผ ===== */
+.empty-page-container {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 50px 20px;
+}
+
+.empty-page-content {
+ text-align: center;
+ max-width: 600px;
+}
+
+.empty-page-content h1 {
+ font-size: 48px;
+ font-weight: 700;
+ color: #1f2937;
+ margin-bottom: 20px;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.empty-page-content p {
+ font-size: 18px;
+ color: #6b7280;
+ margin-bottom: 30px;
+ font-family: 'Pretendard', sans-serif;
+}
+
+.back-to-home-button {
+ background: #3b82f6;
+ color: white;
+ padding: 16px 32px;
+ border: none;
+ border-radius: 12px;
+ font-size: 18px;
+ font-weight: 600;
+ cursor: pointer;
+ text-decoration: none;
+ display: inline-block;
+ transition: transform 0.2s, box-shadow 0.2s;
+ box-shadow: 0 4px 8px rgba(59, 130, 246, 0.3);
+ font-family: 'Pretendard', sans-serif;
+}
+
+.back-to-home-button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 16px rgba(59, 130, 246, 0.4);
+}
+
+/* ===== ๋๋ฉ ํ์ด์ง ์คํ์ผ ===== */
+.hero-section {
+ background: #bfdbfe;
+ height: 400px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ overflow: hidden;
+ margin-top: 70px;
+}
+
+.hero-content {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.hero-image-link {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: transform 0.2s, opacity 0.2s;
+}
+
+.hero-image-link:hover {
+ transform: scale(1.02);
+ opacity: 0.9;
+}
+
+.hero-image-link img {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+}
+
+.content-section {
+ padding: 138px 0;
+ max-width: 1200px;
+ margin: 0 auto;
+ background: #ffffff;
+}
+
+.section-inner {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 32px;
+}
+
+.section-image {
+ width: 100%;
+ max-width: 988px;
+ height: 444px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.section-image img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+.trust-section {
+ background: #bfdbfe;
+ height: 400px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ overflow: hidden;
+}
+
+.trust-section .section-image {
+ width: 100%;
+ max-width: 100%;
+ height: 100%;
+}
+
+.trust-section .section-image img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ max-width: none;
+ max-height: none;
+}
+
+/* ===== ๋ง์ผ ํ์ด์ง ์คํ์ผ ===== */
+.section-title {
+ font-size: 24px;
+ font-weight: 700;
+ margin-bottom: 24px;
+ color: #1f2937;
+ text-align: left;
+}
+
+.best-products-section {
+ margin-bottom: 80px;
+}
+
+.best-products-grid {
+ display: grid;
+ gap: 24px;
+ margin-bottom: 40px;
+}
+
+.products-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ margin-bottom: 32px;
+ gap: 20px;
+}
+
+.products-controls {
+ display: flex;
+ gap: 16px;
+ align-items: center;
+ flex-wrap: wrap;
+}
+
+.search-container {
+ display: flex;
+ align-items: center;
+ background: #f9fafb;
+ border: 1px solid #e5e7eb;
+ border-radius: 8px;
+ padding: 4px;
+ min-width: 280px;
+}
+
+.search-input {
+ border: none;
+ background: transparent;
+ padding: 8px 12px;
+ outline: none;
+ flex: 1;
+ font-size: 14px;
+}
+
+.search-button {
+ background: #3b82f6;
+ color: white;
+ border: none;
+ padding: 8px 12px;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: background-color 0.2s;
+}
+
+.search-button:hover {
+ background: #2563eb;
+}
+
+.register-button {
+ padding: 10px 20px;
+ background-color: #3692ff;
+ color: white;
+ text-decoration: none;
+ border-radius: 8px;
+ font-weight: 600;
+ font-size: 14px;
+ transition: background-color 0.2s;
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ white-space: nowrap;
+}
+
+.register-button:hover {
+ background-color: #2563eb;
+}
+
+.sort-select {
+ padding: 10px 14px;
+ border: 1px solid #e5e7eb;
+ border-radius: 8px;
+ background: white;
+ outline: none;
+ font-size: 14px;
+ cursor: pointer;
+ min-width: 120px;
+}
+
+.products-grid {
+ display: grid;
+ gap: 24px;
+ margin-bottom: 40px;
+}
+
+.product-card {
+ background: white;
+ border: 1px solid #e5e7eb;
+ border-radius: 12px;
+ overflow: hidden;
+ transition: transform 0.2s, box-shadow 0.2s;
+ cursor: pointer;
+ height: fit-content;
+}
+
+.product-card:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.product-image {
+ width: 100%;
+ height: 200px;
+ overflow: hidden;
+ background: #f9fafb;
+}
+
+.product-image img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.2s;
+}
+
+.product-card:hover .product-image img {
+ transform: scale(1.05);
+}
+
+.product-info {
+ padding: 16px;
+}
+
+.product-name {
+ font-size: 16px;
+ font-weight: 600;
+ margin-bottom: 8px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ color: #1f2937;
+}
+
+.product-price {
+ font-size: 18px;
+ font-weight: 700;
+ color: #1f2937;
+ margin-bottom: 12px;
+}
+
+.product-meta {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 14px;
+ color: #6b7280;
+}
+
+.product-favorite {
+ color: #ef4444;
+ font-weight: 500;
+}
+
+.product-date {
+ color: #9ca3af;
+}
+
+.pagination {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 8px;
+ margin: 40px 0;
+}
+
+.pagination-btn {
+ padding: 10px 16px;
+ border: 1px solid #e5e7eb;
+ background: white;
+ cursor: pointer;
+ border-radius: 8px;
+ transition: all 0.2s;
+ font-size: 14px;
+ color: #374151;
+}
+
+.pagination-btn:hover:not(:disabled) {
+ background: #f3f4f6;
+ border-color: #d1d5db;
+}
+
+.pagination-btn.active {
+ background: #3b82f6;
+ color: white;
+ border-color: #3b82f6;
+}
+
+.pagination-btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ background: #f9fafb;
+}
+
+.loading,
+.error,
+.no-products {
+ text-align: center;
+ padding: 60px 20px;
+ font-size: 16px;
+ color: #6b7280;
+ background: #f9fafb;
+ border-radius: 12px;
+ margin: 20px 0;
+}
+
+.error {
+ color: #ef4444;
+ background: #fef2f2;
+ border: 1px solid #fecaca;
+}
+
+.no-products {
+ color: #9ca3af;
+}
+
+/* ===== ํธํฐ ===== */
+.footer {
+ background: #111827;
+ padding: 32px 0;
+ margin-top: 80px;
+}
+
+.footer-container {
+ max-width: 1920px;
+ margin: 0 auto;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 200px;
+}
+
+.footer-text {
+ color: #9ca3af;
+ font-size: 16px;
+}
+
+.footer-links {
+ display: flex;
+ gap: 30px;
+}
+
+.footer-links a {
+ color: #9ca3af;
+ font-size: 16px;
+ text-decoration: none;
+ transition: color 0.2s;
+}
+
+.footer-links a:hover {
+ color: #d1d5db;
+}
+
+.footer-social-icons {
+ display: flex;
+ gap: 12px;
+}
+
+.footer-social-button {
+ display: flex;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: #374151;
+ align-items: center;
+ justify-content: center;
+ color: #9ca3af;
+ text-decoration: none;
+ font-size: 20px;
+ transition: background-color 0.2s, color 0.2s;
+}
+
+.footer-social-button:hover {
+ background: #4b5563;
+ color: #d1d5db;
+}
+
+/* ===== ๋ฐ์ํ ๋์์ธ ===== */
+@media (min-width: 1200px) {
+ .best-products-grid {
+ grid-template-columns: repeat(4, 1fr);
+ }
+ .products-grid {
+ grid-template-columns: repeat(5, 1fr);
+ }
+}
+
+@media (min-width: 744px) and (max-width: 1199px) {
+ .nav-container {
+ padding: 0 24px;
+ }
+
+ .brand-logo {
+ margin-right: 20px;
+ }
+
+ .nav-menu-group {
+ gap: 16px;
+ }
+
+ .footer-container {
+ padding: 0 24px;
+ }
+
+ .best-products-grid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ .products-grid {
+ grid-template-columns: repeat(3, 1fr);
+ }
+
+ .products-header {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .products-controls {
+ justify-content: space-between;
+ }
+
+ .search-container {
+ flex: 1;
+ min-width: 200px;
+ }
+
+ .content-section {
+ padding: 100px 24px;
+ }
+}
+
+@media (max-width: 743px) {
+ .nav-container {
+ padding: 0 16px;
+ }
+
+ .brand-logo {
+ width: 120px;
+ height: 40px;
+ margin-right: 16px;
+ }
+
+ .nav-menu-group {
+ gap: 12px;
+ margin-left: 12px;
+ }
+
+ .board-link,
+ .market-link {
+ font-size: 14px;
+ }
+
+ .login-button {
+ font-size: 14px;
+ padding: 8px 16px;
+ }
+
+ .form-container {
+ width: calc(100% - 32px);
+ max-width: 400px;
+ padding: 0 16px;
+ }
+
+ .form-logo img {
+ width: 100%;
+ max-width: 300px;
+ height: auto;
+ }
+
+ .footer-container {
+ padding: 0 16px;
+ flex-direction: column;
+ gap: 20px;
+ text-align: center;
+ }
+
+ .footer-links {
+ order: -1;
+ }
+
+ .footer-text {
+ order: 1;
+ }
+
+ .footer-social-icons {
+ order: 2;
+ }
+
+ .products-header {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .products-controls {
+ flex-direction: column;
+ gap: 12px;
+ }
+
+ .search-container {
+ min-width: auto;
+ }
+
+ .best-products-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .products-grid {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 16px;
+ }
+
+ .product-image {
+ height: 160px;
+ }
+
+ .product-info {
+ padding: 12px;
+ }
+
+ .product-name {
+ font-size: 14px;
+ }
+
+ .product-price {
+ font-size: 16px;
+ }
+
+ .content-section {
+ padding: 60px 32px;
+ }
+
+ .hero-section,
+ .trust-section {
+ height: 300px;
+ }
+
+ .section-image {
+ width: 100%;
+ height: auto;
+ padding: 0;
+ }
+
+ .section-image img {
+ width: 100%;
+ height: auto;
+ }
+}
\ No newline at end of file
diff --git a/app/items/page.js b/app/items/page.js
new file mode 100644
index 00000000..4ed38a35
--- /dev/null
+++ b/app/items/page.js
@@ -0,0 +1,27 @@
+'use client';
+
+import Link from 'next/link';
+import Image from 'next/image';
+
+export default function ItemsPage() {
+ return (
+
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
์ํ ๋ชฉ๋ก
+
์์ง ์ค๋น ์ค์ธ ํ์ด์ง์
๋๋ค. ๊ณง ๋ค์ํ ์ํ๋ค์ ๋ง๋๋ณด์ค ์ ์์ด์!
+
ํ์ผ๋ก ๋์๊ฐ๊ธฐ
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/layout.js b/app/layout.js
new file mode 100644
index 00000000..0b023a9c
--- /dev/null
+++ b/app/layout.js
@@ -0,0 +1,28 @@
+import { Providers } from './providers'
+import './globals.css'
+
+
+export const metadata = {
+ title: 'ํ๋ค๋ง์ผ',
+ description: '์ค๊ณ ๊ฑฐ๋๋ถํฐ ๋๋ค ์ ๋ณด๊น์ง, ์ด์๊ณผ ํจ๊ปํด์',
+}
+
+export default function RootLayout({ children }) {
+ return (
+
+
+
+
+
+
+
+
+ {children}
+
+
+
+ )
+}
diff --git a/app/login/page.js b/app/login/page.js
new file mode 100644
index 00000000..d56eb589
--- /dev/null
+++ b/app/login/page.js
@@ -0,0 +1,180 @@
+'use client';
+
+import { useState } from 'react';
+import { useRouter } from 'next/navigation';
+import Link from 'next/link';
+import Image from 'next/image';
+import { useAuth } from '@/hooks/useAuth';
+
+export default function LoginPage() {
+ const router = useRouter();
+ const { login } = useAuth();
+
+ const [formData, setFormData] = useState({
+ email: '',
+ password: ''
+ });
+
+ const [errors, setErrors] = useState({
+ email: '',
+ password: ''
+ });
+
+ const [showPassword, setShowPassword] = useState(false);
+ const [touched, setTouched] = useState({
+ email: false,
+ password: false
+ });
+
+ const validateEmail = (email) => {
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ return emailRegex.test(email);
+ };
+
+ const validatePassword = (password) => {
+ return password.length >= 8;
+ };
+
+ const validateEmailField = (value) => {
+ if (!value) return '์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.';
+ if (!validateEmail(value)) return '์๋ชป๋ ์ด๋ฉ์ผ ํ์์
๋๋ค';
+ return '';
+ };
+
+ const validatePasswordField = (value) => {
+ if (!value) return '๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.';
+ if (!validatePassword(value)) return '๋น๋ฐ๋ฒํธ๋ฅผ 8์ ์ด์ ์
๋ ฅํด์ฃผ์ธ์.';
+ return '';
+ };
+
+ const handleChange = (e) => {
+ const { id, value } = e.target;
+ setFormData(prev => ({ ...prev, [id]: value }));
+
+ if (touched[id]) {
+ const error = id === 'email'
+ ? validateEmailField(value)
+ : validatePasswordField(value);
+ setErrors(prev => ({ ...prev, [id]: error }));
+ }
+ };
+
+ const handleBlur = (e) => {
+ const { id, value } = e.target;
+ setTouched(prev => ({ ...prev, [id]: true }));
+
+ const error = id === 'email'
+ ? validateEmailField(value)
+ : validatePasswordField(value);
+ setErrors(prev => ({ ...prev, [id]: error }));
+ };
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+
+ const emailError = validateEmailField(formData.email);
+ const passwordError = validatePasswordField(formData.password);
+
+ setErrors({
+ email: emailError,
+ password: passwordError
+ });
+
+ if (emailError || passwordError) return;
+
+ try {
+ await login(formData.email, formData.password);
+ router.push('/market');
+ } catch (error) {
+ alert(error.message || '๋ก๊ทธ์ธ์ ์คํจํ์ต๋๋ค.');
+ }
+ };
+
+ const isFormValid =
+ formData.email &&
+ formData.password &&
+ !errors.email &&
+ !errors.password;
+
+ return (
+
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
+
+
+
+
+
+
์ด๋ฉ์ผ
+
+ {errors.email &&
{errors.email}
}
+
+
+
+
๋น๋ฐ๋ฒํธ
+
+
+ setShowPassword(!showPassword)}
+ >
+ {showPassword ? '๐' : '๐'}
+
+
+ {errors.password &&
{errors.password}
}
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
๊ฐํธ ๋ก๊ทธ์ธํ๊ธฐ
+
+
+
+
+ ํ๋ค๋ง์ผ์ด ์ฒ์์ด์ ๊ฐ์? ํ์๊ฐ์
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/market/page.js b/app/market/page.js
new file mode 100644
index 00000000..05840390
--- /dev/null
+++ b/app/market/page.js
@@ -0,0 +1,285 @@
+'use client';
+
+import { useState, useEffect } from 'react';
+import Link from 'next/link';
+import Image from 'next/image';
+import { useProducts } from '@/hooks/useProducts';
+import { useAuth } from '@/hooks/useAuth';
+
+export default function MarketPage() {
+ const { isAuthenticated } = useAuth();
+ const { products, loading, filters, fetchProducts, fetchBestItems, updateFilters } = useProducts();
+
+ const [bestItems, setBestItems] = useState([]);
+ const [bestLoading, setBestLoading] = useState(false);
+ const [searchInput, setSearchInput] = useState('');
+ const [currentPage, setCurrentPage] = useState(1);
+ const [pageSize, setPageSize] = useState(10);
+ const [totalCount, setTotalCount] = useState(0);
+
+ function getPageSize() {
+ if (typeof window === 'undefined') return 10;
+ const width = window.innerWidth;
+ if (width >= 1200) return 10;
+ if (width >= 744) return 6;
+ return 4;
+ }
+
+ useEffect(() => {
+ setPageSize(getPageSize());
+ loadBestProducts();
+ }, []);
+
+ useEffect(() => {
+ loadProducts();
+ }, [currentPage, pageSize, filters]);
+
+ useEffect(() => {
+ const handleResize = () => {
+ const newPageSize = getPageSize();
+ if (newPageSize !== pageSize) {
+ setPageSize(newPageSize);
+ setCurrentPage(1);
+ }
+ };
+ window.addEventListener('resize', handleResize);
+ return () => window.removeEventListener('resize', handleResize);
+ }, [pageSize]);
+
+ const loadBestProducts = async () => {
+ setBestLoading(true);
+ try {
+ const items = await fetchBestItems();
+ setBestItems(items.slice(0, 4));
+ } catch (error) {
+ console.error('๋ฒ ์คํธ ์ํ ๋ก๋ ์คํจ:', error);
+ } finally {
+ setBestLoading(false);
+ }
+ };
+
+ const loadProducts = async () => {
+ try {
+ const data = await fetchProducts({
+ page: currentPage,
+ pageSize,
+ orderBy: filters.sortBy,
+ keyword: filters.searchTerm
+ });
+ setTotalCount(data.totalCount || 0);
+ } catch (error) {
+ console.error('์ํ ๋ก๋ ์คํจ:', error);
+ }
+ };
+
+ const handleSearch = () => {
+ updateFilters({ searchTerm: searchInput });
+ setCurrentPage(1);
+ };
+
+ const handleSearchKeyPress = (e) => {
+ if (e.key === 'Enter') handleSearch();
+ };
+
+ const handleSortChange = (e) => {
+ updateFilters({ sortBy: e.target.value });
+ setCurrentPage(1);
+ };
+
+ const goToPage = (page) => {
+ setCurrentPage(page);
+ if (typeof window !== 'undefined') {
+ window.scrollTo({ top: 0, behavior: 'smooth' });
+ }
+ };
+
+ const renderProductCard = (product) => {
+ const imageUrl = product.images && product.images.length > 0
+ ? product.images[0]
+ : 'https://via.placeholder.com/200x200?text=No+Image';
+
+ return (
+
+
+
+
+
+
{product.name || '์ ๋ชฉ ์์'}
+
{formatPrice(product.price)}
+
+ โฅ {product.favoriteCount || 0}
+ {formatDate(product.createdAt)}
+
+
+
+ );
+ };
+
+ const formatPrice = (price) => {
+ if (!price) return '0์';
+ return new Intl.NumberFormat('ko-KR').format(price) + '์';
+ };
+
+ const formatDate = (dateString) => {
+ if (!dateString) return '';
+ const date = new Date(dateString);
+ const now = new Date();
+ const diff = now - date;
+ const hours = Math.floor(diff / (1000 * 60 * 60));
+
+ if (hours < 24) {
+ return hours < 1 ? '๋ฐฉ๊ธ ์ ' : `${hours}์๊ฐ ์ `;
+ }
+ const days = Math.floor(hours / 24);
+ return `${days}์ผ ์ `;
+ };
+
+ const renderPagination = () => {
+ const totalPages = Math.ceil(totalCount / pageSize);
+ if (totalPages <= 1) return null;
+
+ const maxVisible = 5;
+ let start = Math.max(1, currentPage - Math.floor(maxVisible / 2));
+ let end = Math.min(totalPages, start + maxVisible - 1);
+
+ if (end - start + 1 < maxVisible) {
+ start = Math.max(1, end - maxVisible + 1);
+ }
+
+ const visiblePages = Array.from({ length: end - start + 1 }, (_, i) => start + i);
+
+ return (
+
+ goToPage(currentPage - 1)}
+ disabled={currentPage === 1}
+ >
+ ์ด์
+
+ {visiblePages.map(page => (
+ goToPage(page)}
+ >
+ {page}
+
+ ))}
+ goToPage(currentPage + 1)}
+ disabled={currentPage === totalPages}
+ >
+ ๋ค์
+
+
+ );
+ };
+
+ return (
+ <>
+
+
+
+
+
+
+ ์์ ๊ฒ์ํ
+ ์ค๊ณ ๋ง์ผ
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
+
+
๋ฒ ์คํธ ์ํ
+
+ {bestLoading ? (
+
๋ฒ ์คํธ ์ํ์ ๋ถ๋ฌ์ค๊ณ ์์ต๋๋ค...
+ ) : (
+
+ {bestItems.map(product => renderProductCard(product))}
+
+ )}
+
+
+
+
+
+
+
+
ํ๋งค ์ค์ธ ์ํ
+
+
+ setSearchInput(e.target.value)}
+ onKeyPress={handleSearchKeyPress}
+ />
+ ๐
+
+
+ ์ํ ๋ฑ๋ก
+
+ ์ต์ ์
+ ์ข์์ ์
+
+
+
+
+
+ {loading ? (
+
์ํ์ ๋ถ๋ฌ์ค๊ณ ์์ต๋๋ค...
+ ) : products.length === 0 ? (
+
๋ฑ๋ก๋ ์ํ์ด ์์ต๋๋ค.
+ ) : (
+
+ {products.map(product => renderProductCard(product))}
+
+ )}
+
+
+
+
+
+
+
+
+
+
ยฉcodeit - 2024
+
+ Privacy Policy
+ FAQ
+
+
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/app/page.js b/app/page.js
new file mode 100644
index 00000000..8be1acd5
--- /dev/null
+++ b/app/page.js
@@ -0,0 +1,89 @@
+'use client';
+
+import Link from 'next/link';
+import Image from 'next/image';
+
+export default function HomePage() {
+ return (
+ <>
+
+
+
+
+
+
+ ์์ ๊ฒ์ํ
+ ์ค๊ณ ๋ง์ผ
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ยฉcodeit - 2024
+
+ Privacy Policy
+ FAQ
+
+
+
+
+ >
+ );
+}
diff --git a/app/page/page.js b/app/page/page.js
new file mode 100644
index 00000000..e1163e10
--- /dev/null
+++ b/app/page/page.js
@@ -0,0 +1,28 @@
+// FAQ Page - app/faq/page.js
+'use client';
+
+import Link from 'next/link';
+import Image from 'next/image';
+
+export default function FAQPage() {
+ return (
+
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
์์ฃผ ๋ฌป๋ ์ง๋ฌธ
+
ํ๋ค๋ง์ผ FAQ ํ์ด์ง์
๋๋ค. ํ์ฌ ์ค๋น ์ค์ธ ํ์ด์ง์
๋๋ค.
+
ํ์ผ๋ก ๋์๊ฐ๊ธฐ
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/paq/page.js b/app/paq/page.js
new file mode 100644
index 00000000..e1163e10
--- /dev/null
+++ b/app/paq/page.js
@@ -0,0 +1,28 @@
+// FAQ Page - app/faq/page.js
+'use client';
+
+import Link from 'next/link';
+import Image from 'next/image';
+
+export default function FAQPage() {
+ return (
+
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
์์ฃผ ๋ฌป๋ ์ง๋ฌธ
+
ํ๋ค๋ง์ผ FAQ ํ์ด์ง์
๋๋ค. ํ์ฌ ์ค๋น ์ค์ธ ํ์ด์ง์
๋๋ค.
+
ํ์ผ๋ก ๋์๊ฐ๊ธฐ
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/privacy/page.js b/app/privacy/page.js
new file mode 100644
index 00000000..adac942a
--- /dev/null
+++ b/app/privacy/page.js
@@ -0,0 +1,27 @@
+'use client';
+
+import Link from 'next/link';
+import Image from 'next/image';
+
+export default function PrivacyPage() {
+ return (
+
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
๊ฐ์ธ์ ๋ณด์ฒ๋ฆฌ๋ฐฉ์นจ
+
ํ๋ค๋ง์ผ์ ๊ฐ์ธ์ ๋ณด์ฒ๋ฆฌ๋ฐฉ์นจ ํ์ด์ง์
๋๋ค. ํ์ฌ ์ค๋น ์ค์ธ ํ์ด์ง์
๋๋ค.
+
ํ์ผ๋ก ๋์๊ฐ๊ธฐ
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/providers.js b/app/providers.js
new file mode 100644
index 00000000..23919376
--- /dev/null
+++ b/app/providers.js
@@ -0,0 +1,14 @@
+'use client';
+
+import { AuthProvider } from '@/contexts/AuthContext';
+import { ProductProvider } from '@/contexts/ProductContext';
+
+export function Providers({ children }) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/app/registration/page.js b/app/registration/page.js
new file mode 100644
index 00000000..17c33a63
--- /dev/null
+++ b/app/registration/page.js
@@ -0,0 +1,262 @@
+'use client';
+
+import { useState } from 'react';
+import { useRouter } from 'next/navigation';
+import Link from 'next/link';
+import { useProducts } from '@/hooks/useProducts';
+import { useAuth } from '@/hooks/useAuth';
+
+export default function RegistrationPage() {
+ const router = useRouter();
+ const { addProduct } = useProducts();
+ const { isAuthenticated } = useAuth();
+
+ const [formData, setFormData] = useState({
+ productName: '',
+ description: '',
+ price: '',
+ tags: []
+ });
+
+ const [errors, setErrors] = useState({
+ productName: '',
+ description: '',
+ price: '',
+ tag: ''
+ });
+
+ const [tagInput, setTagInput] = useState('');
+
+ const validateProductName = (value) => {
+ if (!value || value.length === 0) return '์ํ๋ช
์ ์
๋ ฅํด์ฃผ์ธ์';
+ if (value.length > 10) return '์ํ๋ช
์ 10์ ์ด๋ด๋ก ์
๋ ฅํด์ฃผ์ธ์';
+ return '';
+ };
+
+ const validateDescription = (value) => {
+ if (!value || value.length === 0) return '์ํ ์๊ฐ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์';
+ if (value.length < 10) return '์ํ ์๊ฐ๋ 10์ ์ด์ ์
๋ ฅํด์ฃผ์ธ์';
+ if (value.length > 100) return '์ํ ์๊ฐ๋ 100์ ์ด๋ด๋ก ์
๋ ฅํด์ฃผ์ธ์';
+ return '';
+ };
+
+ const validatePrice = (value) => {
+ if (!value) return 'ํ๋งค ๊ฐ๊ฒฉ์ ์
๋ ฅํด์ฃผ์ธ์';
+ if (isNaN(value) || Number(value) <= 0) return '์ฌ๋ฐ๋ฅธ ๊ฐ๊ฒฉ์ ์
๋ ฅํด์ฃผ์ธ์';
+ return '';
+ };
+
+ const validateTag = (value) => {
+ if (value.length > 5) return 'ํ๊ทธ๋ 5๊ธ์ ์ด๋ด๋ก ์
๋ ฅํด์ฃผ์ธ์';
+ return '';
+ };
+
+ const handleChange = (e) => {
+ const { id, value } = e.target;
+ setFormData(prev => ({ ...prev, [id]: value }));
+
+ let error = '';
+ if (id === 'productName') error = validateProductName(value);
+ else if (id === 'description') error = validateDescription(value);
+ else if (id === 'price') error = validatePrice(value);
+
+ setErrors(prev => ({ ...prev, [id]: error }));
+ };
+
+ const handleTagInputChange = (e) => {
+ const value = e.target.value;
+ setTagInput(value);
+ const error = validateTag(value);
+ setErrors(prev => ({ ...prev, tag: error }));
+ };
+
+ const handleTagKeyPress = (e) => {
+ if (e.key === 'Enter') {
+ e.preventDefault();
+ const value = tagInput.trim();
+
+ if (value && value.length <= 5) {
+ setFormData(prev => ({
+ ...prev,
+ tags: [...prev.tags, value]
+ }));
+ setTagInput('');
+ setErrors(prev => ({ ...prev, tag: '' }));
+ }
+ }
+ };
+
+ const removeTag = (index) => {
+ setFormData(prev => ({
+ ...prev,
+ tags: prev.tags.filter((_, i) => i !== index)
+ }));
+ };
+
+ const isFormValid = () => {
+ return (
+ formData.productName.trim() !== '' &&
+ formData.description.trim() !== '' &&
+ formData.price !== '' &&
+ !errors.productName &&
+ !errors.description &&
+ !errors.price &&
+ formData.productName.length >= 1 &&
+ formData.productName.length <= 10 &&
+ formData.description.length >= 10 &&
+ formData.description.length <= 100 &&
+ !isNaN(formData.price) &&
+ Number(formData.price) > 0
+ );
+ };
+
+ const handleSubmit = async () => {
+ if (!isFormValid()) return;
+
+ if (!isAuthenticated) {
+ alert('๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค.');
+ router.push('/login');
+ return;
+ }
+
+ try {
+ await addProduct({
+ name: formData.productName,
+ description: formData.description,
+ price: Number(formData.price),
+ tags: formData.tags
+ });
+
+ alert('์ํ์ด ๋ฑ๋ก๋์์ต๋๋ค!');
+ router.push('/market');
+ } catch (error) {
+ console.error('์ํ ๋ฑ๋ก ์คํจ:', error);
+ alert('์ํ ๋ฑ๋ก ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.');
+ }
+ };
+
+ return (
+
+
+
+
+
+ ํ๋ค๋ง์ผ
+
+
+
+ ์์ ๊ฒ์ํ
+
+
+ ์ค๊ณ ๋ง์ผ
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
+ ์ํ ๋ฑ๋กํ๊ธฐ
+
+
+
+
+ ์ํ๋ช
*
+
+
+ {errors.productName && (
+
{errors.productName}
+ )}
+
+
+
+
+ ์ํ ์๊ฐ *
+
+
+ {errors.description && (
+
{errors.description}
+ )}
+
+
+
+
+ ํ๋งค ๊ฐ๊ฒฉ *
+
+
+ {errors.price && (
+
{errors.price}
+ )}
+
+
+
+
ํ๊ทธ
+
+ {errors.tag && (
+
{errors.tag}
+ )}
+
+ {formData.tags.map((tag, index) => (
+
+ #{tag}
+ removeTag(index)}
+ className="cursor-pointer text-gray-600 hover:text-gray-900 font-semibold"
+ >
+ โ
+
+
+ ))}
+
+
+
+
+ ๋ฑ๋ก
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/signup/page.js b/app/signup/page.js
new file mode 100644
index 00000000..1a5e6ad3
--- /dev/null
+++ b/app/signup/page.js
@@ -0,0 +1,264 @@
+'use client';
+
+import { useState } from 'react';
+import { useRouter } from 'next/navigation';
+import Link from 'next/link';
+import Image from 'next/image';
+import { useAuth } from '@/hooks/useAuth';
+
+export default function SignupPage() {
+ const router = useRouter();
+ const { register } = useAuth();
+
+ const [formData, setFormData] = useState({
+ email: '',
+ nickname: '',
+ password: '',
+ passwordConfirm: ''
+ });
+
+ const [errors, setErrors] = useState({
+ email: '',
+ nickname: '',
+ password: '',
+ passwordConfirm: ''
+ });
+
+ const [showPassword, setShowPassword] = useState(false);
+ const [showPasswordConfirm, setShowPasswordConfirm] = useState(false);
+
+ const [touched, setTouched] = useState({
+ email: false,
+ nickname: false,
+ password: false,
+ passwordConfirm: false
+ });
+
+ const validateEmail = (email) => {
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ return emailRegex.test(email);
+ };
+
+ const validatePassword = (password) => {
+ return password.length >= 8;
+ };
+
+ const validateEmailField = (value) => {
+ if (!value) return '์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.';
+ if (!validateEmail(value)) return '์๋ชป๋ ์ด๋ฉ์ผ ํ์์
๋๋ค';
+ return '';
+ };
+
+ const validatePasswordField = (value) => {
+ if (!value) return '๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.';
+ if (!validatePassword(value)) return '๋น๋ฐ๋ฒํธ๋ฅผ 8์ ์ด์ ์
๋ ฅํด์ฃผ์ธ์.';
+ return '';
+ };
+
+ const validatePasswordConfirmField = (value) => {
+ if (!value) return '๋น๋ฐ๋ฒํธ ํ์ธ์ ์
๋ ฅํด์ฃผ์ธ์.';
+ if (value !== formData.password) return '๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.';
+ return '';
+ };
+
+ const handleChange = (e) => {
+ const { id, value } = e.target;
+ setFormData(prev => ({ ...prev, [id]: value }));
+
+ if (touched[id]) {
+ let error = '';
+ if (id === 'email') error = validateEmailField(value);
+ else if (id === 'password') error = validatePasswordField(value);
+ else if (id === 'passwordConfirm') error = validatePasswordConfirmField(value);
+
+ setErrors(prev => ({ ...prev, [id]: error }));
+
+ if (id === 'password' && formData.passwordConfirm && touched.passwordConfirm) {
+ setErrors(prev => ({
+ ...prev,
+ passwordConfirm: value !== formData.passwordConfirm ? '๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.' : ''
+ }));
+ }
+ }
+ };
+
+ const handleBlur = (e) => {
+ const { id, value } = e.target;
+ setTouched(prev => ({ ...prev, [id]: true }));
+
+ let error = '';
+ if (id === 'email') error = validateEmailField(value);
+ else if (id === 'password') {
+ error = validatePasswordField(value);
+ if (formData.passwordConfirm) {
+ setErrors(prev => ({
+ ...prev,
+ passwordConfirm: validatePasswordConfirmField(formData.passwordConfirm)
+ }));
+ }
+ }
+ else if (id === 'passwordConfirm') error = validatePasswordConfirmField(value);
+
+ setErrors(prev => ({ ...prev, [id]: error }));
+ };
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+
+ const emailError = validateEmailField(formData.email);
+ const passwordError = validatePasswordField(formData.password);
+ const confirmError = validatePasswordConfirmField(formData.passwordConfirm);
+
+ setErrors({
+ email: emailError,
+ nickname: '',
+ password: passwordError,
+ passwordConfirm: confirmError
+ });
+
+ if (emailError || passwordError || confirmError) return;
+
+ try {
+ await register({
+ email: formData.email,
+ nickname: formData.nickname,
+ password: formData.password
+ });
+ router.push('/login');
+ } catch (error) {
+ if (error.message.includes('์ด๋ฉ์ผ')) {
+ alert('์ฌ์ฉ ์ค์ธ ์ด๋ฉ์ผ์
๋๋ค');
+ } else {
+ alert(error.message || 'ํ์๊ฐ์
์ ์คํจํ์ต๋๋ค.');
+ }
+ }
+ };
+
+ const isFormValid =
+ formData.email &&
+ formData.nickname &&
+ formData.password &&
+ formData.passwordConfirm &&
+ !errors.email &&
+ !errors.password &&
+ !errors.passwordConfirm;
+
+ return (
+
+
+
+
+
+
+ ๋ก๊ทธ์ธ
+
+
+
+
+
+
+
+
+
+
+
+
์ด๋ฉ์ผ
+
+ {errors.email &&
{errors.email}
}
+
+
+
+ ๋๋ค์
+
+
+
+
+
๋น๋ฐ๋ฒํธ
+
+
+ setShowPassword(!showPassword)}
+ >
+ {showPassword ? '๐' : '๐'}
+
+
+ {errors.password &&
{errors.password}
}
+
+
+
+
๋น๋ฐ๋ฒํธ ํ์ธ
+
+
+ setShowPasswordConfirm(!showPasswordConfirm)}
+ >
+ {showPasswordConfirm ? '๐' : '๐'}
+
+
+ {errors.passwordConfirm &&
{errors.passwordConfirm}
}
+
+
+
+ ํ์๊ฐ์
+
+
+
+
+
๊ฐํธ ํ์๊ฐ์
ํ๊ธฐ
+
+
+
+
+ ์ด๋ฏธ ํ์์ด์ ๊ฐ์? ๋ก๊ทธ์ธ
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 00000000..cee1e2c7
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,29 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import reactHooks from 'eslint-plugin-react-hooks'
+import reactRefresh from 'eslint-plugin-react-refresh'
+import { defineConfig, globalIgnores } from 'eslint/config'
+
+export default defineConfig([
+ globalIgnores(['dist']),
+ {
+ files: ['**/*.{js,jsx}'],
+ extends: [
+ js.configs.recommended,
+ reactHooks.configs['recommended-latest'],
+ reactRefresh.configs.vite,
+ ],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser,
+ parserOptions: {
+ ecmaVersion: 'latest',
+ ecmaFeatures: { jsx: true },
+ sourceType: 'module',
+ },
+ },
+ rules: {
+ 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
+ },
+ },
+])
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 00000000..f4438352
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,16 @@
+import { defineConfig, globalIgnores } from "eslint/config";
+import nextVitals from "eslint-config-next/core-web-vitals";
+
+const eslintConfig = defineConfig([
+ ...nextVitals,
+ // Override default ignores of eslint-config-next.
+ globalIgnores([
+ // Default ignores of eslint-config-next:
+ ".next/**",
+ "out/**",
+ "build/**",
+ "next-env.d.ts",
+ ]),
+]);
+
+export default eslintConfig;
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 00000000..b8d6842d
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,7 @@
+{
+ "compilerOptions": {
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/my-app b/my-app
new file mode 160000
index 00000000..ad28c80e
--- /dev/null
+++ b/my-app
@@ -0,0 +1 @@
+Subproject commit ad28c80e887104b67a869e35799abf66ae9c1650
diff --git a/next.config.js b/next.config.js
new file mode 100644
index 00000000..7fdd005e
--- /dev/null
+++ b/next.config.js
@@ -0,0 +1,18 @@
+// next.config.js
+const path = require("path");
+
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ reactStrictMode: true,
+ images: {
+ remotePatterns: [
+ { protocol: "https", hostname: "via.placeholder.com" },
+ { protocol: "https", hostname: "mellifluous-empanada-fa5948.netlify.app" },
+ ],
+ },
+ turbopack: {
+ root: path.resolve(__dirname),
+ },
+};
+
+module.exports = nextConfig;
diff --git a/next.config.mjs b/next.config.mjs
new file mode 100644
index 00000000..690d2d0d
--- /dev/null
+++ b/next.config.mjs
@@ -0,0 +1,7 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ /* config options here */
+ reactCompiler: true,
+};
+
+export default nextConfig;
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..7de5ea21
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2848 @@
+{
+ "name": "panda-market-frontend",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "panda-market-frontend",
+ "version": "0.0.0",
+ "dependencies": {
+ "next": "^16.0.1",
+ "react": "^19.2.0",
+ "react-dom": "^19.2.0"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.36.0",
+ "@tailwindcss/postcss": "^4.1.16",
+ "@types/react": "^19.1.13",
+ "@types/react-dom": "^19.1.9",
+ "autoprefixer": "^10.4.21",
+ "eslint": "^9.36.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "eslint-plugin-react-refresh": "^0.4.20",
+ "globals": "^16.4.0",
+ "postcss": "^8.5.6",
+ "tailwindcss": "^4.1.16"
+ }
+ },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.6.0.tgz",
+ "integrity": "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
+ "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
+ "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
+ "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.39.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.0.tgz",
+ "integrity": "sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
+ "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
+ "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@img/colour": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz",
+ "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.4.tgz",
+ "integrity": "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.4.tgz",
+ "integrity": "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.3.tgz",
+ "integrity": "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.3.tgz",
+ "integrity": "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.3.tgz",
+ "integrity": "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.3.tgz",
+ "integrity": "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.3.tgz",
+ "integrity": "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.3.tgz",
+ "integrity": "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.3.tgz",
+ "integrity": "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.3.tgz",
+ "integrity": "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.3.tgz",
+ "integrity": "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.4.tgz",
+ "integrity": "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.4.tgz",
+ "integrity": "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.4.tgz",
+ "integrity": "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.4.tgz",
+ "integrity": "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.4.tgz",
+ "integrity": "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.4.tgz",
+ "integrity": "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.4.tgz",
+ "integrity": "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.3"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.4.tgz",
+ "integrity": "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.5.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.4.tgz",
+ "integrity": "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.4.tgz",
+ "integrity": "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.4.tgz",
+ "integrity": "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@next/env": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.1.tgz",
+ "integrity": "sha512-LFvlK0TG2L3fEOX77OC35KowL8D7DlFF45C0OvKMC4hy8c/md1RC4UMNDlUGJqfCoCS2VWrZ4dSE6OjaX5+8mw==",
+ "license": "MIT"
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.1.tgz",
+ "integrity": "sha512-R0YxRp6/4W7yG1nKbfu41bp3d96a0EalonQXiMe+1H9GTHfKxGNCGFNWUho18avRBPsO8T3RmdWuzmfurlQPbg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.1.tgz",
+ "integrity": "sha512-kETZBocRux3xITiZtOtVoVvXyQLB7VBxN7L6EPqgI5paZiUlnsgYv4q8diTNYeHmF9EiehydOBo20lTttCbHAg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.1.tgz",
+ "integrity": "sha512-hWg3BtsxQuSKhfe0LunJoqxjO4NEpBmKkE+P2Sroos7yB//OOX3jD5ISP2wv8QdUwtRehMdwYz6VB50mY6hqAg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.1.tgz",
+ "integrity": "sha512-UPnOvYg+fjAhP3b1iQStcYPWeBFRLrugEyK/lDKGk7kLNua8t5/DvDbAEFotfV1YfcOY6bru76qN9qnjLoyHCQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-gnu": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.1.tgz",
+ "integrity": "sha512-Et81SdWkcRqAJziIgFtsFyJizHoWne4fzJkvjd6V4wEkWTB4MX6J0uByUb0peiJQ4WeAt6GGmMszE5KrXK6WKg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.1.tgz",
+ "integrity": "sha512-qBbgYEBRrC1egcG03FZaVfVxrJm8wBl7vr8UFKplnxNRprctdP26xEv9nJ07Ggq4y1adwa0nz2mz83CELY7N6Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.1.tgz",
+ "integrity": "sha512-cPuBjYP6I699/RdbHJonb3BiRNEDm5CKEBuJ6SD8k3oLam2fDRMKAvmrli4QMDgT2ixyRJ0+DTkiODbIQhRkeQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.1.tgz",
+ "integrity": "sha512-XeEUJsE4JYtfrXe/LaJn3z1pD19fK0Q6Er8Qoufi+HqvdO4LEPyCxLUt4rxA+4RfYo6S9gMlmzCMU2F+AatFqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.15",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+ "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.16.tgz",
+ "integrity": "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.4",
+ "enhanced-resolve": "^5.18.3",
+ "jiti": "^2.6.1",
+ "lightningcss": "1.30.2",
+ "magic-string": "^0.30.19",
+ "source-map-js": "^1.2.1",
+ "tailwindcss": "4.1.16"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.16.tgz",
+ "integrity": "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.1.16",
+ "@tailwindcss/oxide-darwin-arm64": "4.1.16",
+ "@tailwindcss/oxide-darwin-x64": "4.1.16",
+ "@tailwindcss/oxide-freebsd-x64": "4.1.16",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.1.16",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.1.16",
+ "@tailwindcss/oxide-linux-x64-musl": "4.1.16",
+ "@tailwindcss/oxide-wasm32-wasi": "4.1.16",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.1.16"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.16.tgz",
+ "integrity": "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.16.tgz",
+ "integrity": "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.16.tgz",
+ "integrity": "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.16.tgz",
+ "integrity": "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.16.tgz",
+ "integrity": "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.16.tgz",
+ "integrity": "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.16.tgz",
+ "integrity": "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.16.tgz",
+ "integrity": "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.16.tgz",
+ "integrity": "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.16.tgz",
+ "integrity": "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==",
+ "bundleDependencies": [
+ "@napi-rs/wasm-runtime",
+ "@emnapi/core",
+ "@emnapi/runtime",
+ "@tybys/wasm-util",
+ "@emnapi/wasi-threads",
+ "tslib"
+ ],
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.5.0",
+ "@emnapi/runtime": "^1.5.0",
+ "@emnapi/wasi-threads": "^1.1.0",
+ "@napi-rs/wasm-runtime": "^1.0.7",
+ "@tybys/wasm-util": "^0.10.1",
+ "tslib": "^2.4.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.16.tgz",
+ "integrity": "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.16.tgz",
+ "integrity": "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/postcss": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.16.tgz",
+ "integrity": "sha512-Qn3SFGPXYQMKR/UtqS+dqvPrzEeBZHrFA92maT4zijCVggdsXnDBMsPFJo1eArX3J+O+Gi+8pV4PkqjLCNBk3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "@tailwindcss/node": "4.1.16",
+ "@tailwindcss/oxide": "4.1.16",
+ "postcss": "^8.4.41",
+ "tailwindcss": "4.1.16"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "19.2.2",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
+ "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.2.2",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz",
+ "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.21",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
+ "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "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"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.8.23",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.23.tgz",
+ "integrity": "sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.27.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz",
+ "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "baseline-browser-mapping": "^2.8.19",
+ "caniuse-lite": "^1.0.30001751",
+ "electron-to-chromium": "^1.5.238",
+ "node-releases": "^2.0.26",
+ "update-browserslist-db": "^1.1.4"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001753",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz",
+ "integrity": "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.244",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz",
+ "integrity": "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.3",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
+ "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.39.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.0.tgz",
+ "integrity": "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.1",
+ "@eslint/config-helpers": "^0.4.2",
+ "@eslint/core": "^0.17.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.39.0",
+ "@eslint/plugin-kit": "^0.4.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
+ "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react-refresh": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz",
+ "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "eslint": ">=8.40"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.5.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
+ "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lightningcss": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz",
+ "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.30.2",
+ "lightningcss-darwin-arm64": "1.30.2",
+ "lightningcss-darwin-x64": "1.30.2",
+ "lightningcss-freebsd-x64": "1.30.2",
+ "lightningcss-linux-arm-gnueabihf": "1.30.2",
+ "lightningcss-linux-arm64-gnu": "1.30.2",
+ "lightningcss-linux-arm64-musl": "1.30.2",
+ "lightningcss-linux-x64-gnu": "1.30.2",
+ "lightningcss-linux-x64-musl": "1.30.2",
+ "lightningcss-win32-arm64-msvc": "1.30.2",
+ "lightningcss-win32-x64-msvc": "1.30.2"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
+ "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
+ "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
+ "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
+ "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
+ "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
+ "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
+ "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
+ "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
+ "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
+ "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
+ "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/next": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.0.1.tgz",
+ "integrity": "sha512-e9RLSssZwd35p7/vOa+hoDFggUZIUbZhIUSLZuETCwrCVvxOs87NamoUzT+vbcNAL8Ld9GobBnWOA6SbV/arOw==",
+ "license": "MIT",
+ "dependencies": {
+ "@next/env": "16.0.1",
+ "@swc/helpers": "0.5.15",
+ "caniuse-lite": "^1.0.30001579",
+ "postcss": "8.4.31",
+ "styled-jsx": "5.1.6"
+ },
+ "bin": {
+ "next": "dist/bin/next"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "optionalDependencies": {
+ "@next/swc-darwin-arm64": "16.0.1",
+ "@next/swc-darwin-x64": "16.0.1",
+ "@next/swc-linux-arm64-gnu": "16.0.1",
+ "@next/swc-linux-arm64-musl": "16.0.1",
+ "@next/swc-linux-x64-gnu": "16.0.1",
+ "@next/swc-linux-x64-musl": "16.0.1",
+ "@next/swc-win32-arm64-msvc": "16.0.1",
+ "@next/swc-win32-x64-msvc": "16.0.1",
+ "sharp": "^0.34.4"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/next/node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/react": {
+ "version": "19.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
+ "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
+ "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.27.0"
+ },
+ "peerDependencies": {
+ "react": "^19.2.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sharp": {
+ "version": "0.34.4",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz",
+ "integrity": "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "@img/colour": "^1.0.0",
+ "detect-libc": "^2.1.0",
+ "semver": "^7.7.2"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "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"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/styled-jsx": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
+ "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
+ "license": "MIT",
+ "dependencies": {
+ "client-only": "0.0.1"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "peerDependencies": {
+ "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
+ }
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz",
+ "integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tapable": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
+ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
+ "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..823ed335
--- /dev/null
+++ b/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "panda-market-frontend",
+ "private": true,
+ "version": "0.0.0",
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "next": "^16.0.1",
+ "react": "^19.2.0",
+ "react-dom": "^19.2.0"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.36.0",
+ "@tailwindcss/postcss": "^4.1.16",
+ "@types/react": "^19.1.13",
+ "@types/react-dom": "^19.1.9",
+ "autoprefixer": "^10.4.21",
+ "eslint": "^9.36.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "eslint-plugin-react-refresh": "^0.4.20",
+ "globals": "^16.4.0",
+ "postcss": "^8.5.6",
+ "tailwindcss": "^4.1.16"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 00000000..87608a34
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+// postcss.config.js
+module.exports = {
+ plugins: {
+ "@tailwindcss/postcss": {},
+ },
+};
diff --git a/postcss.config.mjs b/postcss.config.mjs
new file mode 100644
index 00000000..61e36849
--- /dev/null
+++ b/postcss.config.mjs
@@ -0,0 +1,7 @@
+const config = {
+ plugins: {
+ "@tailwindcss/postcss": {},
+ },
+};
+
+export default config;
diff --git a/public/file.svg b/public/file.svg
new file mode 100644
index 00000000..004145cd
--- /dev/null
+++ b/public/file.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/globe.svg b/public/globe.svg
new file mode 100644
index 00000000..567f17b0
--- /dev/null
+++ b/public/globe.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/images/facebook.png b/public/images/facebook.png
new file mode 100644
index 00000000..b2b9469b
Binary files /dev/null and b/public/images/facebook.png differ
diff --git a/public/images/insta.png b/public/images/insta.png
new file mode 100644
index 00000000..df99929f
Binary files /dev/null and b/public/images/insta.png differ
diff --git a/public/images/panda1.png b/public/images/panda1.png
new file mode 100644
index 00000000..7740eaf0
Binary files /dev/null and b/public/images/panda1.png differ
diff --git a/public/images/panda2.png b/public/images/panda2.png
new file mode 100644
index 00000000..090eac01
Binary files /dev/null and b/public/images/panda2.png differ
diff --git a/public/images/panda3.png b/public/images/panda3.png
new file mode 100644
index 00000000..5d8ef91f
Binary files /dev/null and b/public/images/panda3.png differ
diff --git a/public/images/panda4.png b/public/images/panda4.png
new file mode 100644
index 00000000..2d6b56d5
Binary files /dev/null and b/public/images/panda4.png differ
diff --git a/public/images/panda5.png b/public/images/panda5.png
new file mode 100644
index 00000000..84f5f8cd
Binary files /dev/null and b/public/images/panda5.png differ
diff --git a/public/images/pandalogo.png b/public/images/pandalogo.png
new file mode 100644
index 00000000..9b53b257
Binary files /dev/null and b/public/images/pandalogo.png differ
diff --git a/public/images/tw.png b/public/images/tw.png
new file mode 100644
index 00000000..45bfdabf
Binary files /dev/null and b/public/images/tw.png differ
diff --git a/public/images/youtube.png b/public/images/youtube.png
new file mode 100644
index 00000000..4c8c1cd9
Binary files /dev/null and b/public/images/youtube.png differ
diff --git a/public/next.svg b/public/next.svg
new file mode 100644
index 00000000..5174b28c
--- /dev/null
+++ b/public/next.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/vercel.svg b/public/vercel.svg
new file mode 100644
index 00000000..77053960
--- /dev/null
+++ b/public/vercel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/window.svg b/public/window.svg
new file mode 100644
index 00000000..b2b2a44f
--- /dev/null
+++ b/public/window.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/app/board/page.js b/src/app/board/page.js
new file mode 100644
index 00000000..691817bc
--- /dev/null
+++ b/src/app/board/page.js
@@ -0,0 +1,65 @@
+import Image from "next/image";
+
+export default function Home() {
+ return (
+
+
+
+
+
+ To get started, edit the page.js file.
+
+
+ Looking for a starting point or more instructions? Head over to{" "}
+
+ Templates
+ {" "}
+ or the{" "}
+
+ Learning
+ {" "}
+ center.
+
+
+
+
+
+ );
+}
diff --git a/src/app/favicon.ico b/src/app/favicon.ico
new file mode 100644
index 00000000..718d6fea
Binary files /dev/null and b/src/app/favicon.ico differ
diff --git a/src/app/layout.js b/src/app/layout.js
new file mode 100644
index 00000000..7bf337d3
--- /dev/null
+++ b/src/app/layout.js
@@ -0,0 +1,29 @@
+import { Geist, Geist_Mono } from "next/font/google";
+import "./globals.css";
+
+const geistSans = Geist({
+ variable: "--font-geist-sans",
+ subsets: ["latin"],
+});
+
+const geistMono = Geist_Mono({
+ variable: "--font-geist-mono",
+ subsets: ["latin"],
+});
+
+export const metadata = {
+ title: "Create Next App",
+ description: "Generated by create next app",
+};
+
+export default function RootLayout({ children }) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/src/assets/images/facebook.png b/src/assets/images/facebook.png
new file mode 100644
index 00000000..b2b9469b
Binary files /dev/null and b/src/assets/images/facebook.png differ
diff --git a/src/assets/images/insta.png b/src/assets/images/insta.png
new file mode 100644
index 00000000..df99929f
Binary files /dev/null and b/src/assets/images/insta.png differ
diff --git a/src/assets/images/panda1.png b/src/assets/images/panda1.png
new file mode 100644
index 00000000..7740eaf0
Binary files /dev/null and b/src/assets/images/panda1.png differ
diff --git a/src/assets/images/panda2.png b/src/assets/images/panda2.png
new file mode 100644
index 00000000..090eac01
Binary files /dev/null and b/src/assets/images/panda2.png differ
diff --git a/src/assets/images/panda3.png b/src/assets/images/panda3.png
new file mode 100644
index 00000000..5d8ef91f
Binary files /dev/null and b/src/assets/images/panda3.png differ
diff --git a/src/assets/images/panda4.png b/src/assets/images/panda4.png
new file mode 100644
index 00000000..2d6b56d5
Binary files /dev/null and b/src/assets/images/panda4.png differ
diff --git a/src/assets/images/panda5.png b/src/assets/images/panda5.png
new file mode 100644
index 00000000..84f5f8cd
Binary files /dev/null and b/src/assets/images/panda5.png differ
diff --git a/src/assets/images/pandalogo.png b/src/assets/images/pandalogo.png
new file mode 100644
index 00000000..9b53b257
Binary files /dev/null and b/src/assets/images/pandalogo.png differ
diff --git a/src/assets/images/tw.png b/src/assets/images/tw.png
new file mode 100644
index 00000000..45bfdabf
Binary files /dev/null and b/src/assets/images/tw.png differ
diff --git a/src/assets/images/youtube.png b/src/assets/images/youtube.png
new file mode 100644
index 00000000..4c8c1cd9
Binary files /dev/null and b/src/assets/images/youtube.png differ
diff --git a/src/assets/public/vite.svg b/src/assets/public/vite.svg
new file mode 100644
index 00000000..e7b8dfb1
--- /dev/null
+++ b/src/assets/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/contexts/AuthContext.jsx b/src/contexts/AuthContext.jsx
new file mode 100644
index 00000000..612119f8
--- /dev/null
+++ b/src/contexts/AuthContext.jsx
@@ -0,0 +1,49 @@
+import { createContext, useState, useEffect } from 'react';
+
+export const AuthContext = createContext(null);
+
+export function AuthProvider({ children }) {
+ const [user, setUser] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ const token = localStorage.getItem('token');
+ if (token) {
+ // TODO: ํ ํฐ์ผ๋ก ์ฌ์ฉ์ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
+ setUser({ email: 'test@test.com' }); // ์์
+ }
+ setLoading(false);
+ }, []);
+
+ const login = async (email, password) => {
+ // TODO: ์ค์ API ํธ์ถ
+ setUser({ email });
+ localStorage.setItem('token', 'dummy-token');
+ };
+
+ const logout = () => {
+ setUser(null);
+ localStorage.removeItem('token');
+ };
+
+ const register = async (userData) => {
+ // TODO: ์ค์ API ํธ์ถ
+ setUser({ email: userData.email });
+ localStorage.setItem('token', 'dummy-token');
+ };
+
+ const value = {
+ user,
+ loading,
+ login,
+ logout,
+ register,
+ isAuthenticated: !!user
+ };
+
+ return (
+
+ {children}
+
+ );
+}
\ No newline at end of file
diff --git a/src/contexts/ProductContext.jsx b/src/contexts/ProductContext.jsx
new file mode 100644
index 00000000..93af1e5a
--- /dev/null
+++ b/src/contexts/ProductContext.jsx
@@ -0,0 +1,88 @@
+import { createContext, useState } from 'react';
+
+export const ProductContext = createContext(null);
+
+export function ProductProvider({ children }) {
+ const [products, setProducts] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [filters, setFilters] = useState({
+ sortBy: 'recent',
+ searchTerm: ''
+ });
+
+ const fetchProducts = async (params) => {
+ setLoading(true);
+ try {
+ const queryParams = new URLSearchParams({
+ page: params.page || 1,
+ pageSize: params.pageSize || 10,
+ orderBy: params.orderBy || 'recent',
+ });
+
+ if (params.keyword) {
+ queryParams.append('keyword', params.keyword);
+ }
+
+ const response = await fetch(
+ `https://panda-market-api.vercel.app/products?${queryParams}`
+ );
+ const data = await response.json();
+ setProducts(data.list || []);
+ return data;
+ } catch (error) {
+ console.error('์ํ ๋ก๋ ์คํจ:', error);
+ return { list: [], totalCount: 0 };
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const fetchBestItems = async () => {
+ try {
+ const response = await fetch(
+ 'https://panda-market-api.vercel.app/products?orderBy=favorite&pageSize=4'
+ );
+ const data = await response.json();
+ return data.list || [];
+ } catch (error) {
+ console.error('๋ฒ ์คํธ ์ํ ๋ก๋ ์คํจ:', error);
+ return [];
+ }
+ };
+
+ const addProduct = async (productData) => {
+ try {
+ const response = await fetch('https://panda-market-api.vercel.app/products', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(productData)
+ });
+ const newProduct = await response.json();
+ setProducts(prev => [newProduct, ...prev]);
+ return newProduct;
+ } catch (error) {
+ console.error('์ํ ๋ฑ๋ก ์คํจ:', error);
+ throw error;
+ }
+ };
+
+ const updateFilters = (newFilters) => {
+ setFilters(prev => ({ ...prev, ...newFilters }));
+ };
+
+ const value = {
+ products,
+ loading,
+ filters,
+ fetchProducts,
+ fetchBestItems,
+ addProduct,
+ updateFilters
+ };
+
+ return (
+
+ {children}
+
+ );
+}
\ No newline at end of file
diff --git a/src/hooks/useAuth.js b/src/hooks/useAuth.js
new file mode 100644
index 00000000..d02989d3
--- /dev/null
+++ b/src/hooks/useAuth.js
@@ -0,0 +1,10 @@
+import { useContext } from 'react';
+import { AuthContext } from '../contexts/AuthContext';
+
+export function useAuth() {
+ const context = useContext(AuthContext);
+ if (!context) {
+ throw new Error('useAuth must be used within AuthProvider');
+ }
+ return context;
+}
\ No newline at end of file
diff --git a/src/hooks/useProducts.js b/src/hooks/useProducts.js
new file mode 100644
index 00000000..55b58cd8
--- /dev/null
+++ b/src/hooks/useProducts.js
@@ -0,0 +1,10 @@
+import { useContext } from 'react';
+import { ProductContext } from '../contexts/ProductContext';
+
+export function useProducts() {
+ const context = useContext(ProductContext);
+ if (!context) {
+ throw new Error('useProducts must be used within ProductProvider');
+ }
+ return context;
+}
\ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 00000000..c1ae65b5
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,13 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
+ './pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/**/*.{js,ts,jsx,tsx,mdx}',
+ ],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 00000000..8b0f57b9
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [react()],
+})