woojun-jung commited on
Commit
e253d75
·
0 Parent(s):

Initial commit

Browse files
.gitignore ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.js
7
+ .yarn/install-state.gz
8
+
9
+ # testing
10
+ /coverage
11
+
12
+ # next.js
13
+ /.next/
14
+ /out/
15
+
16
+ # production
17
+ /build
18
+
19
+ # misc
20
+ .DS_Store
21
+ *.pem
22
+
23
+ # debug
24
+ npm-debug.log*
25
+ yarn-debug.log*
26
+ yarn-error.log*
27
+
28
+ # local env files
29
+ .env*.local
30
+
31
+ # vercel
32
+ .vercel
33
+
34
+ # typescript
35
+ *.tsbuildinfo
36
+ next-env.d.ts
37
+
38
+ # binary file
39
+ bun.lockb
CLAUDE.md ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ A Next.js application that displays GitHub-style contribution heatmaps for Korean AI organizations and users, tracking their model/dataset/space releases on Hugging Face. The app fetches data from Hugging Face's public API and visualizes release activity over a rolling 12-month period.
8
+
9
+ ## Development Commands
10
+
11
+ ```bash
12
+ npm run dev # Start development server (http://localhost:3000)
13
+ npm run build # Build for production
14
+ npm run start # Start production server
15
+ npm run lint # Run ESLint
16
+ ```
17
+
18
+ ## Architecture
19
+
20
+ ### Data Flow
21
+ 1. **Static Generation (ISR)**: The main page (`src/pages/index.tsx`) uses `getStaticProps` with 1-hour revalidation to fetch data for all configured providers
22
+ 2. **Dynamic Route**: `src/pages/[author]/index.tsx` uses `getServerSideProps` for on-demand heatmap generation for any Hugging Face user/org
23
+ 3. **Search Dialog**: Client-side search via `UserSearchDialog` component that fetches data on demand
24
+
25
+ ### Key Concepts
26
+
27
+ **Providers**: Organizations grouped under a single entity. Defined in `src/pages/index.tsx` as the `PROVIDERS` array. Each provider has:
28
+ - `color`: Hex color for heatmap visualization
29
+ - `authors`: Array of Hugging Face usernames/orgs that map to this provider (e.g., `["clovaix", "navervision"]` both map to Naver)
30
+
31
+ **Calendar Generation**: `src/utils/calendar.ts` transforms raw Hugging Face model/dataset/space data into:
32
+ - Daily activity counts for the past 12 months
33
+ - Intensity levels (0-4) calculated relative to each provider's average release rate
34
+ - Zero-filled entries for days with no activity
35
+
36
+ **API Integration**: `src/utils/authors.ts` handles all Hugging Face API calls:
37
+ - `fetchOrganizationData()`: Gets org/user metadata (avatar, name, stats) - tries org API first, falls back to user API
38
+ - `fetchAuthorData()`: Fetches all models/datasets/spaces for a given author
39
+ - Falls back gracefully with empty/default data on API errors
40
+
41
+ ### Component Structure
42
+
43
+ - **Heatmap**: Core visualization component using `react-activity-calendar` library
44
+ - **ProviderSummary**: Horizontal summary cards showing top providers with ranking badges
45
+ - **OrganizationCard**: Provider header with avatar, name, stats, and verification badges
46
+ - **UserSearchDialog**: Modal for searching any Hugging Face user/org and generating embed codes
47
+
48
+ ### Styling
49
+
50
+ - Tailwind CSS with custom config in `tailwind.config.ts`
51
+ - Radix UI primitives via `src/components/ui/` (dialog, button, input, tooltip, avatar)
52
+ - MUI components (`@mui/material`) for specific elements like Avatar and Tooltip in Heatmap
53
+ - Responsive design with mobile-first approach
54
+
55
+ ## Adding/Modifying Providers
56
+
57
+ Edit the `PROVIDERS` array in `src/pages/index.tsx`. Each provider needs:
58
+ - A unique color
59
+ - At least one author in the `authors` array
60
+ - The first author is used as the primary key for calendar data aggregation
Dockerfile ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # syntax=docker/dockerfile:1.4
2
+
3
+ FROM oven/bun:1 AS base
4
+
5
+ # Install dependencies only when needed
6
+ FROM base AS deps
7
+ WORKDIR /app
8
+
9
+ # Install dependencies based on the preferred package manager
10
+ COPY --link package.json bun.lockb* ./
11
+ RUN bun install --frozen-lockfile
12
+
13
+ # Rebuild the source code only when needed
14
+ FROM base AS builder
15
+ WORKDIR /app
16
+ COPY --from=deps --link /app/node_modules ./node_modules
17
+ COPY --link . .
18
+
19
+ # Next.js collects completely anonymous telemetry data about general usage.
20
+ # Uncomment the following line in case you want to disable telemetry during the build.
21
+ # ENV NEXT_TELEMETRY_DISABLED 1
22
+
23
+ RUN bun run build
24
+
25
+ # Production image, copy all the files and run next
26
+ FROM base AS runner
27
+ WORKDIR /app
28
+
29
+ ENV NODE_ENV production
30
+ # Uncomment the following line in case you want to disable telemetry during runtime.
31
+ # ENV NEXT_TELEMETRY_DISABLED 1
32
+
33
+ RUN groupadd -g 1001 nodejs \
34
+ && useradd -u 1001 -g nodejs -r -s /usr/sbin/nologin nextjs
35
+
36
+ COPY --from=builder --link /app/public ./public
37
+
38
+ # Automatically leverage output traces to reduce image size
39
+ COPY --from=builder --link --chown=1001:1001 /app/.next/standalone ./
40
+ COPY --from=builder --link --chown=1001:1001 /app/.next/static ./.next/static
41
+
42
+ USER nextjs
43
+
44
+ EXPOSE 3000
45
+
46
+ ENV PORT 3000
47
+ ENV HOSTNAME 0.0.0.0
48
+ CMD ["bun", "run", "server.js"]
README.md ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Korean Open Source Heatmap
3
+ emoji: 🔥
4
+ colorFrom: purple
5
+ colorTo: red
6
+ sdk: docker
7
+ pinned: true
8
+ app_port: 3000
9
+ license: apache-2.0
10
+ ---
11
+
12
+ ## About
13
+
14
+ This project displays GitHub-style contribution heatmaps for Korean AI organizations, tracking their model/dataset/space releases on Hugging Face.
15
+
16
+ **Original Source**: Based on [zh-ai-community/model-release-heatmap-zh](https://huggingface.co/spaces/zh-ai-community/model-release-heatmap-zh)
17
+
18
+ ---
19
+
20
+ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
21
+
22
+ ## Getting Started
23
+
24
+ First, run the development server:
25
+
26
+ ```bash
27
+ npm run dev
28
+ # or
29
+ yarn dev
30
+ # or
31
+ pnpm dev
32
+ # or
33
+ bun dev
34
+ ```
35
+
36
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
37
+
38
+ You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
39
+
40
+ [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
41
+
42
+ The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
43
+
44
+ This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
45
+
46
+ ## Learn More
47
+
48
+ To learn more about Next.js, take a look at the following resources:
49
+
50
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
51
+ - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
52
+
53
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
54
+
55
+ ## Deploy on Vercel
56
+
57
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
58
+
59
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
components.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "default",
4
+ "rsc": false,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "tailwind.config.ts",
8
+ "css": "src/styles/globals.css",
9
+ "baseColor": "slate",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "aliases": {
14
+ "components": "@/components",
15
+ "utils": "@/lib/utils"
16
+ }
17
+ }
next.config.mjs ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ output: "standalone",
4
+ reactStrictMode: true,
5
+ };
6
+
7
+ export default nextConfig;
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "-",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "@emotion/react": "^11.13.0",
13
+ "@emotion/styled": "^11.13.0",
14
+ "@mui/material": "^5.16.6",
15
+ "@radix-ui/react-avatar": "^1.1.0",
16
+ "@radix-ui/react-dialog": "^1.1.1",
17
+ "@radix-ui/react-slot": "^1.1.0",
18
+ "@radix-ui/react-tooltip": "^1.1.2",
19
+ "class-variance-authority": "^0.7.0",
20
+ "clsx": "^2.1.1",
21
+ "lucide-react": "^0.427.0",
22
+ "next": "^16.1.1",
23
+ "react": "^18",
24
+ "react-activity-calendar": "^2.2.11",
25
+ "react-dom": "^18",
26
+ "tailwind-merge": "^2.4.0",
27
+ "tailwindcss-animate": "^1.0.7"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20",
31
+ "@types/react": "^18",
32
+ "@types/react-dom": "^18",
33
+ "postcss": "^8",
34
+ "tailwindcss": "^3.4.1",
35
+ "typescript": "^5"
36
+ }
37
+ }
pnpm-lock.yaml ADDED
@@ -0,0 +1,2495 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ lockfileVersion: '9.0'
2
+
3
+ settings:
4
+ autoInstallPeers: true
5
+ excludeLinksFromLockfile: false
6
+
7
+ importers:
8
+
9
+ .:
10
+ dependencies:
11
+ '@emotion/react':
12
+ specifier: ^11.13.0
13
+ version: 11.14.0(@types/react@18.3.23)(react@18.3.1)
14
+ '@emotion/styled':
15
+ specifier: ^11.13.0
16
+ version: 11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1)
17
+ '@mui/material':
18
+ specifier: ^5.16.6
19
+ version: 5.17.1(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
20
+ '@radix-ui/react-avatar':
21
+ specifier: ^1.1.0
22
+ version: 1.1.10(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
23
+ '@radix-ui/react-dialog':
24
+ specifier: ^1.1.1
25
+ version: 1.1.14(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
26
+ '@radix-ui/react-slot':
27
+ specifier: ^1.1.0
28
+ version: 1.2.3(@types/react@18.3.23)(react@18.3.1)
29
+ '@radix-ui/react-tooltip':
30
+ specifier: ^1.1.2
31
+ version: 1.2.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
32
+ class-variance-authority:
33
+ specifier: ^0.7.0
34
+ version: 0.7.1
35
+ clsx:
36
+ specifier: ^2.1.1
37
+ version: 2.1.1
38
+ lucide-react:
39
+ specifier: ^0.427.0
40
+ version: 0.427.0(react@18.3.1)
41
+ next:
42
+ specifier: 14.2.5
43
+ version: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
44
+ react:
45
+ specifier: ^18
46
+ version: 18.3.1
47
+ react-activity-calendar:
48
+ specifier: ^2.2.11
49
+ version: 2.7.12(react@18.3.1)
50
+ react-dom:
51
+ specifier: ^18
52
+ version: 18.3.1(react@18.3.1)
53
+ tailwind-merge:
54
+ specifier: ^2.4.0
55
+ version: 2.6.0
56
+ tailwindcss-animate:
57
+ specifier: ^1.0.7
58
+ version: 1.0.7(tailwindcss@3.4.17)
59
+ devDependencies:
60
+ '@types/node':
61
+ specifier: ^20
62
+ version: 20.19.0
63
+ '@types/react':
64
+ specifier: ^18
65
+ version: 18.3.23
66
+ '@types/react-dom':
67
+ specifier: ^18
68
+ version: 18.3.7(@types/react@18.3.23)
69
+ postcss:
70
+ specifier: ^8
71
+ version: 8.5.4
72
+ tailwindcss:
73
+ specifier: ^3.4.1
74
+ version: 3.4.17
75
+ typescript:
76
+ specifier: ^5
77
+ version: 5.8.3
78
+
79
+ packages:
80
+
81
+ '@alloc/quick-lru@5.2.0':
82
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
83
+ engines: {node: '>=10'}
84
+
85
+ '@babel/code-frame@7.27.1':
86
+ resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
87
+ engines: {node: '>=6.9.0'}
88
+
89
+ '@babel/generator@7.27.5':
90
+ resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==}
91
+ engines: {node: '>=6.9.0'}
92
+
93
+ '@babel/helper-module-imports@7.27.1':
94
+ resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==}
95
+ engines: {node: '>=6.9.0'}
96
+
97
+ '@babel/helper-string-parser@7.27.1':
98
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
99
+ engines: {node: '>=6.9.0'}
100
+
101
+ '@babel/helper-validator-identifier@7.27.1':
102
+ resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
103
+ engines: {node: '>=6.9.0'}
104
+
105
+ '@babel/parser@7.27.5':
106
+ resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==}
107
+ engines: {node: '>=6.0.0'}
108
+ hasBin: true
109
+
110
+ '@babel/runtime@7.27.6':
111
+ resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==}
112
+ engines: {node: '>=6.9.0'}
113
+
114
+ '@babel/template@7.27.2':
115
+ resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
116
+ engines: {node: '>=6.9.0'}
117
+
118
+ '@babel/traverse@7.27.4':
119
+ resolution: {integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==}
120
+ engines: {node: '>=6.9.0'}
121
+
122
+ '@babel/types@7.27.6':
123
+ resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==}
124
+ engines: {node: '>=6.9.0'}
125
+
126
+ '@emotion/babel-plugin@11.13.5':
127
+ resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==}
128
+
129
+ '@emotion/cache@11.14.0':
130
+ resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==}
131
+
132
+ '@emotion/hash@0.9.2':
133
+ resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==}
134
+
135
+ '@emotion/is-prop-valid@1.3.1':
136
+ resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==}
137
+
138
+ '@emotion/memoize@0.9.0':
139
+ resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==}
140
+
141
+ '@emotion/react@11.14.0':
142
+ resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==}
143
+ peerDependencies:
144
+ '@types/react': '*'
145
+ react: '>=16.8.0'
146
+ peerDependenciesMeta:
147
+ '@types/react':
148
+ optional: true
149
+
150
+ '@emotion/serialize@1.3.3':
151
+ resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==}
152
+
153
+ '@emotion/sheet@1.4.0':
154
+ resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==}
155
+
156
+ '@emotion/styled@11.14.0':
157
+ resolution: {integrity: sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==}
158
+ peerDependencies:
159
+ '@emotion/react': ^11.0.0-rc.0
160
+ '@types/react': '*'
161
+ react: '>=16.8.0'
162
+ peerDependenciesMeta:
163
+ '@types/react':
164
+ optional: true
165
+
166
+ '@emotion/unitless@0.10.0':
167
+ resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==}
168
+
169
+ '@emotion/use-insertion-effect-with-fallbacks@1.2.0':
170
+ resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==}
171
+ peerDependencies:
172
+ react: '>=16.8.0'
173
+
174
+ '@emotion/utils@1.4.2':
175
+ resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==}
176
+
177
+ '@emotion/weak-memoize@0.4.0':
178
+ resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==}
179
+
180
+ '@floating-ui/core@1.7.1':
181
+ resolution: {integrity: sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==}
182
+
183
+ '@floating-ui/dom@1.7.1':
184
+ resolution: {integrity: sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==}
185
+
186
+ '@floating-ui/react-dom@2.1.3':
187
+ resolution: {integrity: sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==}
188
+ peerDependencies:
189
+ react: '>=16.8.0'
190
+ react-dom: '>=16.8.0'
191
+
192
+ '@floating-ui/utils@0.2.9':
193
+ resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
194
+
195
+ '@isaacs/cliui@8.0.2':
196
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
197
+ engines: {node: '>=12'}
198
+
199
+ '@jridgewell/gen-mapping@0.3.8':
200
+ resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
201
+ engines: {node: '>=6.0.0'}
202
+
203
+ '@jridgewell/resolve-uri@3.1.2':
204
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
205
+ engines: {node: '>=6.0.0'}
206
+
207
+ '@jridgewell/set-array@1.2.1':
208
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
209
+ engines: {node: '>=6.0.0'}
210
+
211
+ '@jridgewell/sourcemap-codec@1.5.0':
212
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
213
+
214
+ '@jridgewell/trace-mapping@0.3.25':
215
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
216
+
217
+ '@mui/core-downloads-tracker@5.17.1':
218
+ resolution: {integrity: sha512-OcZj+cs6EfUD39IoPBOgN61zf1XFVY+imsGoBDwXeSq2UHJZE3N59zzBOVjclck91Ne3e9gudONOeILvHCIhUA==}
219
+
220
+ '@mui/material@5.17.1':
221
+ resolution: {integrity: sha512-2B33kQf+GmPnrvXXweWAx+crbiUEsxCdCN979QDYnlH9ox4pd+0/IBriWLV+l6ORoBF60w39cWjFnJYGFdzXcw==}
222
+ engines: {node: '>=12.0.0'}
223
+ peerDependencies:
224
+ '@emotion/react': ^11.5.0
225
+ '@emotion/styled': ^11.3.0
226
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
227
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
228
+ react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
229
+ peerDependenciesMeta:
230
+ '@emotion/react':
231
+ optional: true
232
+ '@emotion/styled':
233
+ optional: true
234
+ '@types/react':
235
+ optional: true
236
+
237
+ '@mui/private-theming@5.17.1':
238
+ resolution: {integrity: sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==}
239
+ engines: {node: '>=12.0.0'}
240
+ peerDependencies:
241
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
242
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
243
+ peerDependenciesMeta:
244
+ '@types/react':
245
+ optional: true
246
+
247
+ '@mui/styled-engine@5.16.14':
248
+ resolution: {integrity: sha512-UAiMPZABZ7p8mUW4akDV6O7N3+4DatStpXMZwPlt+H/dA0lt67qawN021MNND+4QTpjaiMYxbhKZeQcyWCbuKw==}
249
+ engines: {node: '>=12.0.0'}
250
+ peerDependencies:
251
+ '@emotion/react': ^11.4.1
252
+ '@emotion/styled': ^11.3.0
253
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
254
+ peerDependenciesMeta:
255
+ '@emotion/react':
256
+ optional: true
257
+ '@emotion/styled':
258
+ optional: true
259
+
260
+ '@mui/system@5.17.1':
261
+ resolution: {integrity: sha512-aJrmGfQpyF0U4D4xYwA6ueVtQcEMebET43CUmKMP7e7iFh3sMIF3sBR0l8Urb4pqx1CBjHAaWgB0ojpND4Q3Jg==}
262
+ engines: {node: '>=12.0.0'}
263
+ peerDependencies:
264
+ '@emotion/react': ^11.5.0
265
+ '@emotion/styled': ^11.3.0
266
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
267
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
268
+ peerDependenciesMeta:
269
+ '@emotion/react':
270
+ optional: true
271
+ '@emotion/styled':
272
+ optional: true
273
+ '@types/react':
274
+ optional: true
275
+
276
+ '@mui/types@7.2.24':
277
+ resolution: {integrity: sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==}
278
+ peerDependencies:
279
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
280
+ peerDependenciesMeta:
281
+ '@types/react':
282
+ optional: true
283
+
284
+ '@mui/utils@5.17.1':
285
+ resolution: {integrity: sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==}
286
+ engines: {node: '>=12.0.0'}
287
+ peerDependencies:
288
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
289
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
290
+ peerDependenciesMeta:
291
+ '@types/react':
292
+ optional: true
293
+
294
+ '@next/env@14.2.5':
295
+ resolution: {integrity: sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==}
296
+
297
+ '@next/swc-darwin-arm64@14.2.5':
298
+ resolution: {integrity: sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==}
299
+ engines: {node: '>= 10'}
300
+ cpu: [arm64]
301
+ os: [darwin]
302
+
303
+ '@next/swc-darwin-x64@14.2.5':
304
+ resolution: {integrity: sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==}
305
+ engines: {node: '>= 10'}
306
+ cpu: [x64]
307
+ os: [darwin]
308
+
309
+ '@next/swc-linux-arm64-gnu@14.2.5':
310
+ resolution: {integrity: sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==}
311
+ engines: {node: '>= 10'}
312
+ cpu: [arm64]
313
+ os: [linux]
314
+
315
+ '@next/swc-linux-arm64-musl@14.2.5':
316
+ resolution: {integrity: sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==}
317
+ engines: {node: '>= 10'}
318
+ cpu: [arm64]
319
+ os: [linux]
320
+
321
+ '@next/swc-linux-x64-gnu@14.2.5':
322
+ resolution: {integrity: sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==}
323
+ engines: {node: '>= 10'}
324
+ cpu: [x64]
325
+ os: [linux]
326
+
327
+ '@next/swc-linux-x64-musl@14.2.5':
328
+ resolution: {integrity: sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==}
329
+ engines: {node: '>= 10'}
330
+ cpu: [x64]
331
+ os: [linux]
332
+
333
+ '@next/swc-win32-arm64-msvc@14.2.5':
334
+ resolution: {integrity: sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==}
335
+ engines: {node: '>= 10'}
336
+ cpu: [arm64]
337
+ os: [win32]
338
+
339
+ '@next/swc-win32-ia32-msvc@14.2.5':
340
+ resolution: {integrity: sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==}
341
+ engines: {node: '>= 10'}
342
+ cpu: [ia32]
343
+ os: [win32]
344
+
345
+ '@next/swc-win32-x64-msvc@14.2.5':
346
+ resolution: {integrity: sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==}
347
+ engines: {node: '>= 10'}
348
+ cpu: [x64]
349
+ os: [win32]
350
+
351
+ '@nodelib/fs.scandir@2.1.5':
352
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
353
+ engines: {node: '>= 8'}
354
+
355
+ '@nodelib/fs.stat@2.0.5':
356
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
357
+ engines: {node: '>= 8'}
358
+
359
+ '@nodelib/fs.walk@1.2.8':
360
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
361
+ engines: {node: '>= 8'}
362
+
363
+ '@pkgjs/parseargs@0.11.0':
364
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
365
+ engines: {node: '>=14'}
366
+
367
+ '@popperjs/core@2.11.8':
368
+ resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
369
+
370
+ '@radix-ui/primitive@1.1.2':
371
+ resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==}
372
+
373
+ '@radix-ui/react-arrow@1.1.7':
374
+ resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==}
375
+ peerDependencies:
376
+ '@types/react': '*'
377
+ '@types/react-dom': '*'
378
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
379
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
380
+ peerDependenciesMeta:
381
+ '@types/react':
382
+ optional: true
383
+ '@types/react-dom':
384
+ optional: true
385
+
386
+ '@radix-ui/react-avatar@1.1.10':
387
+ resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==}
388
+ peerDependencies:
389
+ '@types/react': '*'
390
+ '@types/react-dom': '*'
391
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
392
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
393
+ peerDependenciesMeta:
394
+ '@types/react':
395
+ optional: true
396
+ '@types/react-dom':
397
+ optional: true
398
+
399
+ '@radix-ui/react-compose-refs@1.1.2':
400
+ resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==}
401
+ peerDependencies:
402
+ '@types/react': '*'
403
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
404
+ peerDependenciesMeta:
405
+ '@types/react':
406
+ optional: true
407
+
408
+ '@radix-ui/react-context@1.1.2':
409
+ resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==}
410
+ peerDependencies:
411
+ '@types/react': '*'
412
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
413
+ peerDependenciesMeta:
414
+ '@types/react':
415
+ optional: true
416
+
417
+ '@radix-ui/react-dialog@1.1.14':
418
+ resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==}
419
+ peerDependencies:
420
+ '@types/react': '*'
421
+ '@types/react-dom': '*'
422
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
423
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
424
+ peerDependenciesMeta:
425
+ '@types/react':
426
+ optional: true
427
+ '@types/react-dom':
428
+ optional: true
429
+
430
+ '@radix-ui/react-dismissable-layer@1.1.10':
431
+ resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==}
432
+ peerDependencies:
433
+ '@types/react': '*'
434
+ '@types/react-dom': '*'
435
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
436
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
437
+ peerDependenciesMeta:
438
+ '@types/react':
439
+ optional: true
440
+ '@types/react-dom':
441
+ optional: true
442
+
443
+ '@radix-ui/react-focus-guards@1.1.2':
444
+ resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==}
445
+ peerDependencies:
446
+ '@types/react': '*'
447
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
448
+ peerDependenciesMeta:
449
+ '@types/react':
450
+ optional: true
451
+
452
+ '@radix-ui/react-focus-scope@1.1.7':
453
+ resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==}
454
+ peerDependencies:
455
+ '@types/react': '*'
456
+ '@types/react-dom': '*'
457
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
458
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
459
+ peerDependenciesMeta:
460
+ '@types/react':
461
+ optional: true
462
+ '@types/react-dom':
463
+ optional: true
464
+
465
+ '@radix-ui/react-id@1.1.1':
466
+ resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==}
467
+ peerDependencies:
468
+ '@types/react': '*'
469
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
470
+ peerDependenciesMeta:
471
+ '@types/react':
472
+ optional: true
473
+
474
+ '@radix-ui/react-popper@1.2.7':
475
+ resolution: {integrity: sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==}
476
+ peerDependencies:
477
+ '@types/react': '*'
478
+ '@types/react-dom': '*'
479
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
480
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
481
+ peerDependenciesMeta:
482
+ '@types/react':
483
+ optional: true
484
+ '@types/react-dom':
485
+ optional: true
486
+
487
+ '@radix-ui/react-portal@1.1.9':
488
+ resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==}
489
+ peerDependencies:
490
+ '@types/react': '*'
491
+ '@types/react-dom': '*'
492
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
493
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
494
+ peerDependenciesMeta:
495
+ '@types/react':
496
+ optional: true
497
+ '@types/react-dom':
498
+ optional: true
499
+
500
+ '@radix-ui/react-presence@1.1.4':
501
+ resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==}
502
+ peerDependencies:
503
+ '@types/react': '*'
504
+ '@types/react-dom': '*'
505
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
506
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
507
+ peerDependenciesMeta:
508
+ '@types/react':
509
+ optional: true
510
+ '@types/react-dom':
511
+ optional: true
512
+
513
+ '@radix-ui/react-primitive@2.1.3':
514
+ resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==}
515
+ peerDependencies:
516
+ '@types/react': '*'
517
+ '@types/react-dom': '*'
518
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
519
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
520
+ peerDependenciesMeta:
521
+ '@types/react':
522
+ optional: true
523
+ '@types/react-dom':
524
+ optional: true
525
+
526
+ '@radix-ui/react-slot@1.2.3':
527
+ resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==}
528
+ peerDependencies:
529
+ '@types/react': '*'
530
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
531
+ peerDependenciesMeta:
532
+ '@types/react':
533
+ optional: true
534
+
535
+ '@radix-ui/react-tooltip@1.2.7':
536
+ resolution: {integrity: sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==}
537
+ peerDependencies:
538
+ '@types/react': '*'
539
+ '@types/react-dom': '*'
540
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
541
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
542
+ peerDependenciesMeta:
543
+ '@types/react':
544
+ optional: true
545
+ '@types/react-dom':
546
+ optional: true
547
+
548
+ '@radix-ui/react-use-callback-ref@1.1.1':
549
+ resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==}
550
+ peerDependencies:
551
+ '@types/react': '*'
552
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
553
+ peerDependenciesMeta:
554
+ '@types/react':
555
+ optional: true
556
+
557
+ '@radix-ui/react-use-controllable-state@1.2.2':
558
+ resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==}
559
+ peerDependencies:
560
+ '@types/react': '*'
561
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
562
+ peerDependenciesMeta:
563
+ '@types/react':
564
+ optional: true
565
+
566
+ '@radix-ui/react-use-effect-event@0.0.2':
567
+ resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==}
568
+ peerDependencies:
569
+ '@types/react': '*'
570
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
571
+ peerDependenciesMeta:
572
+ '@types/react':
573
+ optional: true
574
+
575
+ '@radix-ui/react-use-escape-keydown@1.1.1':
576
+ resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==}
577
+ peerDependencies:
578
+ '@types/react': '*'
579
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
580
+ peerDependenciesMeta:
581
+ '@types/react':
582
+ optional: true
583
+
584
+ '@radix-ui/react-use-is-hydrated@0.1.0':
585
+ resolution: {integrity: sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==}
586
+ peerDependencies:
587
+ '@types/react': '*'
588
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
589
+ peerDependenciesMeta:
590
+ '@types/react':
591
+ optional: true
592
+
593
+ '@radix-ui/react-use-layout-effect@1.1.1':
594
+ resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==}
595
+ peerDependencies:
596
+ '@types/react': '*'
597
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
598
+ peerDependenciesMeta:
599
+ '@types/react':
600
+ optional: true
601
+
602
+ '@radix-ui/react-use-rect@1.1.1':
603
+ resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==}
604
+ peerDependencies:
605
+ '@types/react': '*'
606
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
607
+ peerDependenciesMeta:
608
+ '@types/react':
609
+ optional: true
610
+
611
+ '@radix-ui/react-use-size@1.1.1':
612
+ resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==}
613
+ peerDependencies:
614
+ '@types/react': '*'
615
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
616
+ peerDependenciesMeta:
617
+ '@types/react':
618
+ optional: true
619
+
620
+ '@radix-ui/react-visually-hidden@1.2.3':
621
+ resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==}
622
+ peerDependencies:
623
+ '@types/react': '*'
624
+ '@types/react-dom': '*'
625
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
626
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
627
+ peerDependenciesMeta:
628
+ '@types/react':
629
+ optional: true
630
+ '@types/react-dom':
631
+ optional: true
632
+
633
+ '@radix-ui/rect@1.1.1':
634
+ resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
635
+
636
+ '@swc/counter@0.1.3':
637
+ resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
638
+
639
+ '@swc/helpers@0.5.5':
640
+ resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
641
+
642
+ '@types/node@20.19.0':
643
+ resolution: {integrity: sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q==}
644
+
645
+ '@types/parse-json@4.0.2':
646
+ resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
647
+
648
+ '@types/prop-types@15.7.15':
649
+ resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
650
+
651
+ '@types/react-dom@18.3.7':
652
+ resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==}
653
+ peerDependencies:
654
+ '@types/react': ^18.0.0
655
+
656
+ '@types/react-transition-group@4.4.12':
657
+ resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==}
658
+ peerDependencies:
659
+ '@types/react': '*'
660
+
661
+ '@types/react@18.3.23':
662
+ resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==}
663
+
664
+ ansi-regex@5.0.1:
665
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
666
+ engines: {node: '>=8'}
667
+
668
+ ansi-regex@6.1.0:
669
+ resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
670
+ engines: {node: '>=12'}
671
+
672
+ ansi-styles@4.3.0:
673
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
674
+ engines: {node: '>=8'}
675
+
676
+ ansi-styles@6.2.1:
677
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
678
+ engines: {node: '>=12'}
679
+
680
+ any-promise@1.3.0:
681
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
682
+
683
+ anymatch@3.1.3:
684
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
685
+ engines: {node: '>= 8'}
686
+
687
+ arg@5.0.2:
688
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
689
+
690
+ aria-hidden@1.2.6:
691
+ resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
692
+ engines: {node: '>=10'}
693
+
694
+ babel-plugin-macros@3.1.0:
695
+ resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
696
+ engines: {node: '>=10', npm: '>=6'}
697
+
698
+ balanced-match@1.0.2:
699
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
700
+
701
+ binary-extensions@2.3.0:
702
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
703
+ engines: {node: '>=8'}
704
+
705
+ brace-expansion@2.0.1:
706
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
707
+
708
+ braces@3.0.3:
709
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
710
+ engines: {node: '>=8'}
711
+
712
+ busboy@1.6.0:
713
+ resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
714
+ engines: {node: '>=10.16.0'}
715
+
716
+ callsites@3.1.0:
717
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
718
+ engines: {node: '>=6'}
719
+
720
+ camelcase-css@2.0.1:
721
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
722
+ engines: {node: '>= 6'}
723
+
724
+ caniuse-lite@1.0.30001721:
725
+ resolution: {integrity: sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==}
726
+
727
+ chokidar@3.6.0:
728
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
729
+ engines: {node: '>= 8.10.0'}
730
+
731
+ class-variance-authority@0.7.1:
732
+ resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
733
+
734
+ client-only@0.0.1:
735
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
736
+
737
+ clsx@2.1.1:
738
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
739
+ engines: {node: '>=6'}
740
+
741
+ color-convert@2.0.1:
742
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
743
+ engines: {node: '>=7.0.0'}
744
+
745
+ color-name@1.1.4:
746
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
747
+
748
+ commander@4.1.1:
749
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
750
+ engines: {node: '>= 6'}
751
+
752
+ convert-source-map@1.9.0:
753
+ resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
754
+
755
+ cosmiconfig@7.1.0:
756
+ resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
757
+ engines: {node: '>=10'}
758
+
759
+ cross-spawn@7.0.6:
760
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
761
+ engines: {node: '>= 8'}
762
+
763
+ cssesc@3.0.0:
764
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
765
+ engines: {node: '>=4'}
766
+ hasBin: true
767
+
768
+ csstype@3.1.3:
769
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
770
+
771
+ date-fns@4.1.0:
772
+ resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
773
+
774
+ debug@4.4.1:
775
+ resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
776
+ engines: {node: '>=6.0'}
777
+ peerDependencies:
778
+ supports-color: '*'
779
+ peerDependenciesMeta:
780
+ supports-color:
781
+ optional: true
782
+
783
+ detect-node-es@1.1.0:
784
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
785
+
786
+ didyoumean@1.2.2:
787
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
788
+
789
+ dlv@1.1.3:
790
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
791
+
792
+ dom-helpers@5.2.1:
793
+ resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
794
+
795
+ eastasianwidth@0.2.0:
796
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
797
+
798
+ emoji-regex@8.0.0:
799
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
800
+
801
+ emoji-regex@9.2.2:
802
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
803
+
804
+ error-ex@1.3.2:
805
+ resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
806
+
807
+ escape-string-regexp@4.0.0:
808
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
809
+ engines: {node: '>=10'}
810
+
811
+ fast-glob@3.3.3:
812
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
813
+ engines: {node: '>=8.6.0'}
814
+
815
+ fastq@1.19.1:
816
+ resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
817
+
818
+ fill-range@7.1.1:
819
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
820
+ engines: {node: '>=8'}
821
+
822
+ find-root@1.1.0:
823
+ resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
824
+
825
+ foreground-child@3.3.1:
826
+ resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
827
+ engines: {node: '>=14'}
828
+
829
+ fsevents@2.3.3:
830
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
831
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
832
+ os: [darwin]
833
+
834
+ function-bind@1.1.2:
835
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
836
+
837
+ get-nonce@1.0.1:
838
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
839
+ engines: {node: '>=6'}
840
+
841
+ glob-parent@5.1.2:
842
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
843
+ engines: {node: '>= 6'}
844
+
845
+ glob-parent@6.0.2:
846
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
847
+ engines: {node: '>=10.13.0'}
848
+
849
+ glob@10.4.5:
850
+ resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
851
+ hasBin: true
852
+
853
+ globals@11.12.0:
854
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
855
+ engines: {node: '>=4'}
856
+
857
+ graceful-fs@4.2.11:
858
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
859
+
860
+ hasown@2.0.2:
861
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
862
+ engines: {node: '>= 0.4'}
863
+
864
+ hoist-non-react-statics@3.3.2:
865
+ resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
866
+
867
+ import-fresh@3.3.1:
868
+ resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
869
+ engines: {node: '>=6'}
870
+
871
+ is-arrayish@0.2.1:
872
+ resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
873
+
874
+ is-binary-path@2.1.0:
875
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
876
+ engines: {node: '>=8'}
877
+
878
+ is-core-module@2.16.1:
879
+ resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
880
+ engines: {node: '>= 0.4'}
881
+
882
+ is-extglob@2.1.1:
883
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
884
+ engines: {node: '>=0.10.0'}
885
+
886
+ is-fullwidth-code-point@3.0.0:
887
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
888
+ engines: {node: '>=8'}
889
+
890
+ is-glob@4.0.3:
891
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
892
+ engines: {node: '>=0.10.0'}
893
+
894
+ is-number@7.0.0:
895
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
896
+ engines: {node: '>=0.12.0'}
897
+
898
+ isexe@2.0.0:
899
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
900
+
901
+ jackspeak@3.4.3:
902
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
903
+
904
+ jiti@1.21.7:
905
+ resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
906
+ hasBin: true
907
+
908
+ js-tokens@4.0.0:
909
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
910
+
911
+ jsesc@3.1.0:
912
+ resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
913
+ engines: {node: '>=6'}
914
+ hasBin: true
915
+
916
+ json-parse-even-better-errors@2.3.1:
917
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
918
+
919
+ lilconfig@3.1.3:
920
+ resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
921
+ engines: {node: '>=14'}
922
+
923
+ lines-and-columns@1.2.4:
924
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
925
+
926
+ loose-envify@1.4.0:
927
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
928
+ hasBin: true
929
+
930
+ lru-cache@10.4.3:
931
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
932
+
933
+ lucide-react@0.427.0:
934
+ resolution: {integrity: sha512-lv9s6c5BDF/ccuA0EgTdskTxIe11qpwBDmzRZHJAKtp8LTewAvDvOM+pTES9IpbBuTqkjiMhOmGpJ/CB+mKjFw==}
935
+ peerDependencies:
936
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc
937
+
938
+ merge2@1.4.1:
939
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
940
+ engines: {node: '>= 8'}
941
+
942
+ micromatch@4.0.8:
943
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
944
+ engines: {node: '>=8.6'}
945
+
946
+ minimatch@9.0.5:
947
+ resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
948
+ engines: {node: '>=16 || 14 >=14.17'}
949
+
950
+ minipass@7.1.2:
951
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
952
+ engines: {node: '>=16 || 14 >=14.17'}
953
+
954
+ ms@2.1.3:
955
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
956
+
957
+ mz@2.7.0:
958
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
959
+
960
+ nanoid@3.3.11:
961
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
962
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
963
+ hasBin: true
964
+
965
+ next@14.2.5:
966
+ resolution: {integrity: sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==}
967
+ engines: {node: '>=18.17.0'}
968
+ hasBin: true
969
+ peerDependencies:
970
+ '@opentelemetry/api': ^1.1.0
971
+ '@playwright/test': ^1.41.2
972
+ react: ^18.2.0
973
+ react-dom: ^18.2.0
974
+ sass: ^1.3.0
975
+ peerDependenciesMeta:
976
+ '@opentelemetry/api':
977
+ optional: true
978
+ '@playwright/test':
979
+ optional: true
980
+ sass:
981
+ optional: true
982
+
983
+ normalize-path@3.0.0:
984
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
985
+ engines: {node: '>=0.10.0'}
986
+
987
+ object-assign@4.1.1:
988
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
989
+ engines: {node: '>=0.10.0'}
990
+
991
+ object-hash@3.0.0:
992
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
993
+ engines: {node: '>= 6'}
994
+
995
+ package-json-from-dist@1.0.1:
996
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
997
+
998
+ parent-module@1.0.1:
999
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
1000
+ engines: {node: '>=6'}
1001
+
1002
+ parse-json@5.2.0:
1003
+ resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
1004
+ engines: {node: '>=8'}
1005
+
1006
+ path-key@3.1.1:
1007
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1008
+ engines: {node: '>=8'}
1009
+
1010
+ path-parse@1.0.7:
1011
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1012
+
1013
+ path-scurry@1.11.1:
1014
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
1015
+ engines: {node: '>=16 || 14 >=14.18'}
1016
+
1017
+ path-type@4.0.0:
1018
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
1019
+ engines: {node: '>=8'}
1020
+
1021
+ picocolors@1.1.1:
1022
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
1023
+
1024
+ picomatch@2.3.1:
1025
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1026
+ engines: {node: '>=8.6'}
1027
+
1028
+ pify@2.3.0:
1029
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
1030
+ engines: {node: '>=0.10.0'}
1031
+
1032
+ pirates@4.0.7:
1033
+ resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
1034
+ engines: {node: '>= 6'}
1035
+
1036
+ postcss-import@15.1.0:
1037
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
1038
+ engines: {node: '>=14.0.0'}
1039
+ peerDependencies:
1040
+ postcss: ^8.0.0
1041
+
1042
+ postcss-js@4.0.1:
1043
+ resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
1044
+ engines: {node: ^12 || ^14 || >= 16}
1045
+ peerDependencies:
1046
+ postcss: ^8.4.21
1047
+
1048
+ postcss-load-config@4.0.2:
1049
+ resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
1050
+ engines: {node: '>= 14'}
1051
+ peerDependencies:
1052
+ postcss: '>=8.0.9'
1053
+ ts-node: '>=9.0.0'
1054
+ peerDependenciesMeta:
1055
+ postcss:
1056
+ optional: true
1057
+ ts-node:
1058
+ optional: true
1059
+
1060
+ postcss-nested@6.2.0:
1061
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
1062
+ engines: {node: '>=12.0'}
1063
+ peerDependencies:
1064
+ postcss: ^8.2.14
1065
+
1066
+ postcss-selector-parser@6.1.2:
1067
+ resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
1068
+ engines: {node: '>=4'}
1069
+
1070
+ postcss-value-parser@4.2.0:
1071
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
1072
+
1073
+ postcss@8.4.31:
1074
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
1075
+ engines: {node: ^10 || ^12 || >=14}
1076
+
1077
+ postcss@8.5.4:
1078
+ resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==}
1079
+ engines: {node: ^10 || ^12 || >=14}
1080
+
1081
+ prop-types@15.8.1:
1082
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
1083
+
1084
+ queue-microtask@1.2.3:
1085
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1086
+
1087
+ react-activity-calendar@2.7.12:
1088
+ resolution: {integrity: sha512-OzVconQ5LA/uF2ZN3zDeWZb4UxjOmGr1ymaGCSEAMLSzwjzP7ojdyZs8DyV7jcV+rZ+lmwp6BTpBJqdW8ehXyw==}
1089
+ peerDependencies:
1090
+ react: ^18.0.0 || ^19.0.0
1091
+
1092
+ react-dom@18.3.1:
1093
+ resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
1094
+ peerDependencies:
1095
+ react: ^18.3.1
1096
+
1097
+ react-is@16.13.1:
1098
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
1099
+
1100
+ react-is@19.1.0:
1101
+ resolution: {integrity: sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==}
1102
+
1103
+ react-remove-scroll-bar@2.3.8:
1104
+ resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
1105
+ engines: {node: '>=10'}
1106
+ peerDependencies:
1107
+ '@types/react': '*'
1108
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1109
+ peerDependenciesMeta:
1110
+ '@types/react':
1111
+ optional: true
1112
+
1113
+ react-remove-scroll@2.7.1:
1114
+ resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==}
1115
+ engines: {node: '>=10'}
1116
+ peerDependencies:
1117
+ '@types/react': '*'
1118
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
1119
+ peerDependenciesMeta:
1120
+ '@types/react':
1121
+ optional: true
1122
+
1123
+ react-style-singleton@2.2.3:
1124
+ resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
1125
+ engines: {node: '>=10'}
1126
+ peerDependencies:
1127
+ '@types/react': '*'
1128
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
1129
+ peerDependenciesMeta:
1130
+ '@types/react':
1131
+ optional: true
1132
+
1133
+ react-transition-group@4.4.5:
1134
+ resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
1135
+ peerDependencies:
1136
+ react: '>=16.6.0'
1137
+ react-dom: '>=16.6.0'
1138
+
1139
+ react@18.3.1:
1140
+ resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
1141
+ engines: {node: '>=0.10.0'}
1142
+
1143
+ read-cache@1.0.0:
1144
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
1145
+
1146
+ readdirp@3.6.0:
1147
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
1148
+ engines: {node: '>=8.10.0'}
1149
+
1150
+ resolve-from@4.0.0:
1151
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
1152
+ engines: {node: '>=4'}
1153
+
1154
+ resolve@1.22.10:
1155
+ resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
1156
+ engines: {node: '>= 0.4'}
1157
+ hasBin: true
1158
+
1159
+ reusify@1.1.0:
1160
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
1161
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1162
+
1163
+ run-parallel@1.2.0:
1164
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1165
+
1166
+ scheduler@0.23.2:
1167
+ resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
1168
+
1169
+ shebang-command@2.0.0:
1170
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1171
+ engines: {node: '>=8'}
1172
+
1173
+ shebang-regex@3.0.0:
1174
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1175
+ engines: {node: '>=8'}
1176
+
1177
+ signal-exit@4.1.0:
1178
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
1179
+ engines: {node: '>=14'}
1180
+
1181
+ source-map-js@1.2.1:
1182
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
1183
+ engines: {node: '>=0.10.0'}
1184
+
1185
+ source-map@0.5.7:
1186
+ resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
1187
+ engines: {node: '>=0.10.0'}
1188
+
1189
+ streamsearch@1.1.0:
1190
+ resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
1191
+ engines: {node: '>=10.0.0'}
1192
+
1193
+ string-width@4.2.3:
1194
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
1195
+ engines: {node: '>=8'}
1196
+
1197
+ string-width@5.1.2:
1198
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
1199
+ engines: {node: '>=12'}
1200
+
1201
+ strip-ansi@6.0.1:
1202
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1203
+ engines: {node: '>=8'}
1204
+
1205
+ strip-ansi@7.1.0:
1206
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
1207
+ engines: {node: '>=12'}
1208
+
1209
+ styled-jsx@5.1.1:
1210
+ resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==}
1211
+ engines: {node: '>= 12.0.0'}
1212
+ peerDependencies:
1213
+ '@babel/core': '*'
1214
+ babel-plugin-macros: '*'
1215
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0'
1216
+ peerDependenciesMeta:
1217
+ '@babel/core':
1218
+ optional: true
1219
+ babel-plugin-macros:
1220
+ optional: true
1221
+
1222
+ stylis@4.2.0:
1223
+ resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==}
1224
+
1225
+ sucrase@3.35.0:
1226
+ resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
1227
+ engines: {node: '>=16 || 14 >=14.17'}
1228
+ hasBin: true
1229
+
1230
+ supports-preserve-symlinks-flag@1.0.0:
1231
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
1232
+ engines: {node: '>= 0.4'}
1233
+
1234
+ tailwind-merge@2.6.0:
1235
+ resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==}
1236
+
1237
+ tailwindcss-animate@1.0.7:
1238
+ resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
1239
+ peerDependencies:
1240
+ tailwindcss: '>=3.0.0 || insiders'
1241
+
1242
+ tailwindcss@3.4.17:
1243
+ resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==}
1244
+ engines: {node: '>=14.0.0'}
1245
+ hasBin: true
1246
+
1247
+ thenify-all@1.6.0:
1248
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
1249
+ engines: {node: '>=0.8'}
1250
+
1251
+ thenify@3.3.1:
1252
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
1253
+
1254
+ to-regex-range@5.0.1:
1255
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1256
+ engines: {node: '>=8.0'}
1257
+
1258
+ ts-interface-checker@0.1.13:
1259
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
1260
+
1261
+ tslib@2.8.1:
1262
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
1263
+
1264
+ typescript@5.8.3:
1265
+ resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
1266
+ engines: {node: '>=14.17'}
1267
+ hasBin: true
1268
+
1269
+ undici-types@6.21.0:
1270
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
1271
+
1272
+ use-callback-ref@1.3.3:
1273
+ resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
1274
+ engines: {node: '>=10'}
1275
+ peerDependencies:
1276
+ '@types/react': '*'
1277
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
1278
+ peerDependenciesMeta:
1279
+ '@types/react':
1280
+ optional: true
1281
+
1282
+ use-sidecar@1.1.3:
1283
+ resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
1284
+ engines: {node: '>=10'}
1285
+ peerDependencies:
1286
+ '@types/react': '*'
1287
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
1288
+ peerDependenciesMeta:
1289
+ '@types/react':
1290
+ optional: true
1291
+
1292
+ use-sync-external-store@1.5.0:
1293
+ resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==}
1294
+ peerDependencies:
1295
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1296
+
1297
+ util-deprecate@1.0.2:
1298
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
1299
+
1300
+ which@2.0.2:
1301
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1302
+ engines: {node: '>= 8'}
1303
+ hasBin: true
1304
+
1305
+ wrap-ansi@7.0.0:
1306
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
1307
+ engines: {node: '>=10'}
1308
+
1309
+ wrap-ansi@8.1.0:
1310
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
1311
+ engines: {node: '>=12'}
1312
+
1313
+ yaml@1.10.2:
1314
+ resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
1315
+ engines: {node: '>= 6'}
1316
+
1317
+ yaml@2.8.0:
1318
+ resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==}
1319
+ engines: {node: '>= 14.6'}
1320
+ hasBin: true
1321
+
1322
+ snapshots:
1323
+
1324
+ '@alloc/quick-lru@5.2.0': {}
1325
+
1326
+ '@babel/code-frame@7.27.1':
1327
+ dependencies:
1328
+ '@babel/helper-validator-identifier': 7.27.1
1329
+ js-tokens: 4.0.0
1330
+ picocolors: 1.1.1
1331
+
1332
+ '@babel/generator@7.27.5':
1333
+ dependencies:
1334
+ '@babel/parser': 7.27.5
1335
+ '@babel/types': 7.27.6
1336
+ '@jridgewell/gen-mapping': 0.3.8
1337
+ '@jridgewell/trace-mapping': 0.3.25
1338
+ jsesc: 3.1.0
1339
+
1340
+ '@babel/helper-module-imports@7.27.1':
1341
+ dependencies:
1342
+ '@babel/traverse': 7.27.4
1343
+ '@babel/types': 7.27.6
1344
+ transitivePeerDependencies:
1345
+ - supports-color
1346
+
1347
+ '@babel/helper-string-parser@7.27.1': {}
1348
+
1349
+ '@babel/helper-validator-identifier@7.27.1': {}
1350
+
1351
+ '@babel/parser@7.27.5':
1352
+ dependencies:
1353
+ '@babel/types': 7.27.6
1354
+
1355
+ '@babel/runtime@7.27.6': {}
1356
+
1357
+ '@babel/template@7.27.2':
1358
+ dependencies:
1359
+ '@babel/code-frame': 7.27.1
1360
+ '@babel/parser': 7.27.5
1361
+ '@babel/types': 7.27.6
1362
+
1363
+ '@babel/traverse@7.27.4':
1364
+ dependencies:
1365
+ '@babel/code-frame': 7.27.1
1366
+ '@babel/generator': 7.27.5
1367
+ '@babel/parser': 7.27.5
1368
+ '@babel/template': 7.27.2
1369
+ '@babel/types': 7.27.6
1370
+ debug: 4.4.1
1371
+ globals: 11.12.0
1372
+ transitivePeerDependencies:
1373
+ - supports-color
1374
+
1375
+ '@babel/types@7.27.6':
1376
+ dependencies:
1377
+ '@babel/helper-string-parser': 7.27.1
1378
+ '@babel/helper-validator-identifier': 7.27.1
1379
+
1380
+ '@emotion/babel-plugin@11.13.5':
1381
+ dependencies:
1382
+ '@babel/helper-module-imports': 7.27.1
1383
+ '@babel/runtime': 7.27.6
1384
+ '@emotion/hash': 0.9.2
1385
+ '@emotion/memoize': 0.9.0
1386
+ '@emotion/serialize': 1.3.3
1387
+ babel-plugin-macros: 3.1.0
1388
+ convert-source-map: 1.9.0
1389
+ escape-string-regexp: 4.0.0
1390
+ find-root: 1.1.0
1391
+ source-map: 0.5.7
1392
+ stylis: 4.2.0
1393
+ transitivePeerDependencies:
1394
+ - supports-color
1395
+
1396
+ '@emotion/cache@11.14.0':
1397
+ dependencies:
1398
+ '@emotion/memoize': 0.9.0
1399
+ '@emotion/sheet': 1.4.0
1400
+ '@emotion/utils': 1.4.2
1401
+ '@emotion/weak-memoize': 0.4.0
1402
+ stylis: 4.2.0
1403
+
1404
+ '@emotion/hash@0.9.2': {}
1405
+
1406
+ '@emotion/is-prop-valid@1.3.1':
1407
+ dependencies:
1408
+ '@emotion/memoize': 0.9.0
1409
+
1410
+ '@emotion/memoize@0.9.0': {}
1411
+
1412
+ '@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1)':
1413
+ dependencies:
1414
+ '@babel/runtime': 7.27.6
1415
+ '@emotion/babel-plugin': 11.13.5
1416
+ '@emotion/cache': 11.14.0
1417
+ '@emotion/serialize': 1.3.3
1418
+ '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1)
1419
+ '@emotion/utils': 1.4.2
1420
+ '@emotion/weak-memoize': 0.4.0
1421
+ hoist-non-react-statics: 3.3.2
1422
+ react: 18.3.1
1423
+ optionalDependencies:
1424
+ '@types/react': 18.3.23
1425
+ transitivePeerDependencies:
1426
+ - supports-color
1427
+
1428
+ '@emotion/serialize@1.3.3':
1429
+ dependencies:
1430
+ '@emotion/hash': 0.9.2
1431
+ '@emotion/memoize': 0.9.0
1432
+ '@emotion/unitless': 0.10.0
1433
+ '@emotion/utils': 1.4.2
1434
+ csstype: 3.1.3
1435
+
1436
+ '@emotion/sheet@1.4.0': {}
1437
+
1438
+ '@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1)':
1439
+ dependencies:
1440
+ '@babel/runtime': 7.27.6
1441
+ '@emotion/babel-plugin': 11.13.5
1442
+ '@emotion/is-prop-valid': 1.3.1
1443
+ '@emotion/react': 11.14.0(@types/react@18.3.23)(react@18.3.1)
1444
+ '@emotion/serialize': 1.3.3
1445
+ '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1)
1446
+ '@emotion/utils': 1.4.2
1447
+ react: 18.3.1
1448
+ optionalDependencies:
1449
+ '@types/react': 18.3.23
1450
+ transitivePeerDependencies:
1451
+ - supports-color
1452
+
1453
+ '@emotion/unitless@0.10.0': {}
1454
+
1455
+ '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@18.3.1)':
1456
+ dependencies:
1457
+ react: 18.3.1
1458
+
1459
+ '@emotion/utils@1.4.2': {}
1460
+
1461
+ '@emotion/weak-memoize@0.4.0': {}
1462
+
1463
+ '@floating-ui/core@1.7.1':
1464
+ dependencies:
1465
+ '@floating-ui/utils': 0.2.9
1466
+
1467
+ '@floating-ui/dom@1.7.1':
1468
+ dependencies:
1469
+ '@floating-ui/core': 1.7.1
1470
+ '@floating-ui/utils': 0.2.9
1471
+
1472
+ '@floating-ui/react-dom@2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1473
+ dependencies:
1474
+ '@floating-ui/dom': 1.7.1
1475
+ react: 18.3.1
1476
+ react-dom: 18.3.1(react@18.3.1)
1477
+
1478
+ '@floating-ui/utils@0.2.9': {}
1479
+
1480
+ '@isaacs/cliui@8.0.2':
1481
+ dependencies:
1482
+ string-width: 5.1.2
1483
+ string-width-cjs: string-width@4.2.3
1484
+ strip-ansi: 7.1.0
1485
+ strip-ansi-cjs: strip-ansi@6.0.1
1486
+ wrap-ansi: 8.1.0
1487
+ wrap-ansi-cjs: wrap-ansi@7.0.0
1488
+
1489
+ '@jridgewell/gen-mapping@0.3.8':
1490
+ dependencies:
1491
+ '@jridgewell/set-array': 1.2.1
1492
+ '@jridgewell/sourcemap-codec': 1.5.0
1493
+ '@jridgewell/trace-mapping': 0.3.25
1494
+
1495
+ '@jridgewell/resolve-uri@3.1.2': {}
1496
+
1497
+ '@jridgewell/set-array@1.2.1': {}
1498
+
1499
+ '@jridgewell/sourcemap-codec@1.5.0': {}
1500
+
1501
+ '@jridgewell/trace-mapping@0.3.25':
1502
+ dependencies:
1503
+ '@jridgewell/resolve-uri': 3.1.2
1504
+ '@jridgewell/sourcemap-codec': 1.5.0
1505
+
1506
+ '@mui/core-downloads-tracker@5.17.1': {}
1507
+
1508
+ '@mui/material@5.17.1(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1509
+ dependencies:
1510
+ '@babel/runtime': 7.27.6
1511
+ '@mui/core-downloads-tracker': 5.17.1
1512
+ '@mui/system': 5.17.1(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1)
1513
+ '@mui/types': 7.2.24(@types/react@18.3.23)
1514
+ '@mui/utils': 5.17.1(@types/react@18.3.23)(react@18.3.1)
1515
+ '@popperjs/core': 2.11.8
1516
+ '@types/react-transition-group': 4.4.12(@types/react@18.3.23)
1517
+ clsx: 2.1.1
1518
+ csstype: 3.1.3
1519
+ prop-types: 15.8.1
1520
+ react: 18.3.1
1521
+ react-dom: 18.3.1(react@18.3.1)
1522
+ react-is: 19.1.0
1523
+ react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1524
+ optionalDependencies:
1525
+ '@emotion/react': 11.14.0(@types/react@18.3.23)(react@18.3.1)
1526
+ '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1)
1527
+ '@types/react': 18.3.23
1528
+
1529
+ '@mui/private-theming@5.17.1(@types/react@18.3.23)(react@18.3.1)':
1530
+ dependencies:
1531
+ '@babel/runtime': 7.27.6
1532
+ '@mui/utils': 5.17.1(@types/react@18.3.23)(react@18.3.1)
1533
+ prop-types: 15.8.1
1534
+ react: 18.3.1
1535
+ optionalDependencies:
1536
+ '@types/react': 18.3.23
1537
+
1538
+ '@mui/styled-engine@5.16.14(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1))(react@18.3.1)':
1539
+ dependencies:
1540
+ '@babel/runtime': 7.27.6
1541
+ '@emotion/cache': 11.14.0
1542
+ csstype: 3.1.3
1543
+ prop-types: 15.8.1
1544
+ react: 18.3.1
1545
+ optionalDependencies:
1546
+ '@emotion/react': 11.14.0(@types/react@18.3.23)(react@18.3.1)
1547
+ '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1)
1548
+
1549
+ '@mui/system@5.17.1(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1)':
1550
+ dependencies:
1551
+ '@babel/runtime': 7.27.6
1552
+ '@mui/private-theming': 5.17.1(@types/react@18.3.23)(react@18.3.1)
1553
+ '@mui/styled-engine': 5.16.14(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1))(react@18.3.1)
1554
+ '@mui/types': 7.2.24(@types/react@18.3.23)
1555
+ '@mui/utils': 5.17.1(@types/react@18.3.23)(react@18.3.1)
1556
+ clsx: 2.1.1
1557
+ csstype: 3.1.3
1558
+ prop-types: 15.8.1
1559
+ react: 18.3.1
1560
+ optionalDependencies:
1561
+ '@emotion/react': 11.14.0(@types/react@18.3.23)(react@18.3.1)
1562
+ '@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react@18.3.1)
1563
+ '@types/react': 18.3.23
1564
+
1565
+ '@mui/types@7.2.24(@types/react@18.3.23)':
1566
+ optionalDependencies:
1567
+ '@types/react': 18.3.23
1568
+
1569
+ '@mui/utils@5.17.1(@types/react@18.3.23)(react@18.3.1)':
1570
+ dependencies:
1571
+ '@babel/runtime': 7.27.6
1572
+ '@mui/types': 7.2.24(@types/react@18.3.23)
1573
+ '@types/prop-types': 15.7.15
1574
+ clsx: 2.1.1
1575
+ prop-types: 15.8.1
1576
+ react: 18.3.1
1577
+ react-is: 19.1.0
1578
+ optionalDependencies:
1579
+ '@types/react': 18.3.23
1580
+
1581
+ '@next/env@14.2.5': {}
1582
+
1583
+ '@next/swc-darwin-arm64@14.2.5':
1584
+ optional: true
1585
+
1586
+ '@next/swc-darwin-x64@14.2.5':
1587
+ optional: true
1588
+
1589
+ '@next/swc-linux-arm64-gnu@14.2.5':
1590
+ optional: true
1591
+
1592
+ '@next/swc-linux-arm64-musl@14.2.5':
1593
+ optional: true
1594
+
1595
+ '@next/swc-linux-x64-gnu@14.2.5':
1596
+ optional: true
1597
+
1598
+ '@next/swc-linux-x64-musl@14.2.5':
1599
+ optional: true
1600
+
1601
+ '@next/swc-win32-arm64-msvc@14.2.5':
1602
+ optional: true
1603
+
1604
+ '@next/swc-win32-ia32-msvc@14.2.5':
1605
+ optional: true
1606
+
1607
+ '@next/swc-win32-x64-msvc@14.2.5':
1608
+ optional: true
1609
+
1610
+ '@nodelib/fs.scandir@2.1.5':
1611
+ dependencies:
1612
+ '@nodelib/fs.stat': 2.0.5
1613
+ run-parallel: 1.2.0
1614
+
1615
+ '@nodelib/fs.stat@2.0.5': {}
1616
+
1617
+ '@nodelib/fs.walk@1.2.8':
1618
+ dependencies:
1619
+ '@nodelib/fs.scandir': 2.1.5
1620
+ fastq: 1.19.1
1621
+
1622
+ '@pkgjs/parseargs@0.11.0':
1623
+ optional: true
1624
+
1625
+ '@popperjs/core@2.11.8': {}
1626
+
1627
+ '@radix-ui/primitive@1.1.2': {}
1628
+
1629
+ '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1630
+ dependencies:
1631
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1632
+ react: 18.3.1
1633
+ react-dom: 18.3.1(react@18.3.1)
1634
+ optionalDependencies:
1635
+ '@types/react': 18.3.23
1636
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1637
+
1638
+ '@radix-ui/react-avatar@1.1.10(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1639
+ dependencies:
1640
+ '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1641
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1642
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1643
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@18.3.23)(react@18.3.1)
1644
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1645
+ react: 18.3.1
1646
+ react-dom: 18.3.1(react@18.3.1)
1647
+ optionalDependencies:
1648
+ '@types/react': 18.3.23
1649
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1650
+
1651
+ '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.23)(react@18.3.1)':
1652
+ dependencies:
1653
+ react: 18.3.1
1654
+ optionalDependencies:
1655
+ '@types/react': 18.3.23
1656
+
1657
+ '@radix-ui/react-context@1.1.2(@types/react@18.3.23)(react@18.3.1)':
1658
+ dependencies:
1659
+ react: 18.3.1
1660
+ optionalDependencies:
1661
+ '@types/react': 18.3.23
1662
+
1663
+ '@radix-ui/react-dialog@1.1.14(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1664
+ dependencies:
1665
+ '@radix-ui/primitive': 1.1.2
1666
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1667
+ '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1668
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1669
+ '@radix-ui/react-focus-guards': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1670
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1671
+ '@radix-ui/react-id': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1672
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1673
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1674
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1675
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.3.23)(react@18.3.1)
1676
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1)
1677
+ aria-hidden: 1.2.6
1678
+ react: 18.3.1
1679
+ react-dom: 18.3.1(react@18.3.1)
1680
+ react-remove-scroll: 2.7.1(@types/react@18.3.23)(react@18.3.1)
1681
+ optionalDependencies:
1682
+ '@types/react': 18.3.23
1683
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1684
+
1685
+ '@radix-ui/react-dismissable-layer@1.1.10(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1686
+ dependencies:
1687
+ '@radix-ui/primitive': 1.1.2
1688
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1689
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1690
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1691
+ '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1692
+ react: 18.3.1
1693
+ react-dom: 18.3.1(react@18.3.1)
1694
+ optionalDependencies:
1695
+ '@types/react': 18.3.23
1696
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1697
+
1698
+ '@radix-ui/react-focus-guards@1.1.2(@types/react@18.3.23)(react@18.3.1)':
1699
+ dependencies:
1700
+ react: 18.3.1
1701
+ optionalDependencies:
1702
+ '@types/react': 18.3.23
1703
+
1704
+ '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1705
+ dependencies:
1706
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1707
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1708
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1709
+ react: 18.3.1
1710
+ react-dom: 18.3.1(react@18.3.1)
1711
+ optionalDependencies:
1712
+ '@types/react': 18.3.23
1713
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1714
+
1715
+ '@radix-ui/react-id@1.1.1(@types/react@18.3.23)(react@18.3.1)':
1716
+ dependencies:
1717
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1718
+ react: 18.3.1
1719
+ optionalDependencies:
1720
+ '@types/react': 18.3.23
1721
+
1722
+ '@radix-ui/react-popper@1.2.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1723
+ dependencies:
1724
+ '@floating-ui/react-dom': 2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1725
+ '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1726
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1727
+ '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1728
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1729
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1730
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1731
+ '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1732
+ '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1733
+ '@radix-ui/rect': 1.1.1
1734
+ react: 18.3.1
1735
+ react-dom: 18.3.1(react@18.3.1)
1736
+ optionalDependencies:
1737
+ '@types/react': 18.3.23
1738
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1739
+
1740
+ '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1741
+ dependencies:
1742
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1743
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1744
+ react: 18.3.1
1745
+ react-dom: 18.3.1(react@18.3.1)
1746
+ optionalDependencies:
1747
+ '@types/react': 18.3.23
1748
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1749
+
1750
+ '@radix-ui/react-presence@1.1.4(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1751
+ dependencies:
1752
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1753
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1754
+ react: 18.3.1
1755
+ react-dom: 18.3.1(react@18.3.1)
1756
+ optionalDependencies:
1757
+ '@types/react': 18.3.23
1758
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1759
+
1760
+ '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1761
+ dependencies:
1762
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.3.23)(react@18.3.1)
1763
+ react: 18.3.1
1764
+ react-dom: 18.3.1(react@18.3.1)
1765
+ optionalDependencies:
1766
+ '@types/react': 18.3.23
1767
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1768
+
1769
+ '@radix-ui/react-slot@1.2.3(@types/react@18.3.23)(react@18.3.1)':
1770
+ dependencies:
1771
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1772
+ react: 18.3.1
1773
+ optionalDependencies:
1774
+ '@types/react': 18.3.23
1775
+
1776
+ '@radix-ui/react-tooltip@1.2.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1777
+ dependencies:
1778
+ '@radix-ui/primitive': 1.1.2
1779
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1780
+ '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1)
1781
+ '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1782
+ '@radix-ui/react-id': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1783
+ '@radix-ui/react-popper': 1.2.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1784
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1785
+ '@radix-ui/react-presence': 1.1.4(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1786
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1787
+ '@radix-ui/react-slot': 1.2.3(@types/react@18.3.23)(react@18.3.1)
1788
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1)
1789
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1790
+ react: 18.3.1
1791
+ react-dom: 18.3.1(react@18.3.1)
1792
+ optionalDependencies:
1793
+ '@types/react': 18.3.23
1794
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1795
+
1796
+ '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.23)(react@18.3.1)':
1797
+ dependencies:
1798
+ react: 18.3.1
1799
+ optionalDependencies:
1800
+ '@types/react': 18.3.23
1801
+
1802
+ '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.3.23)(react@18.3.1)':
1803
+ dependencies:
1804
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.23)(react@18.3.1)
1805
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1806
+ react: 18.3.1
1807
+ optionalDependencies:
1808
+ '@types/react': 18.3.23
1809
+
1810
+ '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.3.23)(react@18.3.1)':
1811
+ dependencies:
1812
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1813
+ react: 18.3.1
1814
+ optionalDependencies:
1815
+ '@types/react': 18.3.23
1816
+
1817
+ '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.23)(react@18.3.1)':
1818
+ dependencies:
1819
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1820
+ react: 18.3.1
1821
+ optionalDependencies:
1822
+ '@types/react': 18.3.23
1823
+
1824
+ '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@18.3.23)(react@18.3.1)':
1825
+ dependencies:
1826
+ react: 18.3.1
1827
+ use-sync-external-store: 1.5.0(react@18.3.1)
1828
+ optionalDependencies:
1829
+ '@types/react': 18.3.23
1830
+
1831
+ '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.23)(react@18.3.1)':
1832
+ dependencies:
1833
+ react: 18.3.1
1834
+ optionalDependencies:
1835
+ '@types/react': 18.3.23
1836
+
1837
+ '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.23)(react@18.3.1)':
1838
+ dependencies:
1839
+ '@radix-ui/rect': 1.1.1
1840
+ react: 18.3.1
1841
+ optionalDependencies:
1842
+ '@types/react': 18.3.23
1843
+
1844
+ '@radix-ui/react-use-size@1.1.1(@types/react@18.3.23)(react@18.3.1)':
1845
+ dependencies:
1846
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1)
1847
+ react: 18.3.1
1848
+ optionalDependencies:
1849
+ '@types/react': 18.3.23
1850
+
1851
+ '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1852
+ dependencies:
1853
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1854
+ react: 18.3.1
1855
+ react-dom: 18.3.1(react@18.3.1)
1856
+ optionalDependencies:
1857
+ '@types/react': 18.3.23
1858
+ '@types/react-dom': 18.3.7(@types/react@18.3.23)
1859
+
1860
+ '@radix-ui/rect@1.1.1': {}
1861
+
1862
+ '@swc/counter@0.1.3': {}
1863
+
1864
+ '@swc/helpers@0.5.5':
1865
+ dependencies:
1866
+ '@swc/counter': 0.1.3
1867
+ tslib: 2.8.1
1868
+
1869
+ '@types/node@20.19.0':
1870
+ dependencies:
1871
+ undici-types: 6.21.0
1872
+
1873
+ '@types/parse-json@4.0.2': {}
1874
+
1875
+ '@types/prop-types@15.7.15': {}
1876
+
1877
+ '@types/react-dom@18.3.7(@types/react@18.3.23)':
1878
+ dependencies:
1879
+ '@types/react': 18.3.23
1880
+
1881
+ '@types/react-transition-group@4.4.12(@types/react@18.3.23)':
1882
+ dependencies:
1883
+ '@types/react': 18.3.23
1884
+
1885
+ '@types/react@18.3.23':
1886
+ dependencies:
1887
+ '@types/prop-types': 15.7.15
1888
+ csstype: 3.1.3
1889
+
1890
+ ansi-regex@5.0.1: {}
1891
+
1892
+ ansi-regex@6.1.0: {}
1893
+
1894
+ ansi-styles@4.3.0:
1895
+ dependencies:
1896
+ color-convert: 2.0.1
1897
+
1898
+ ansi-styles@6.2.1: {}
1899
+
1900
+ any-promise@1.3.0: {}
1901
+
1902
+ anymatch@3.1.3:
1903
+ dependencies:
1904
+ normalize-path: 3.0.0
1905
+ picomatch: 2.3.1
1906
+
1907
+ arg@5.0.2: {}
1908
+
1909
+ aria-hidden@1.2.6:
1910
+ dependencies:
1911
+ tslib: 2.8.1
1912
+
1913
+ babel-plugin-macros@3.1.0:
1914
+ dependencies:
1915
+ '@babel/runtime': 7.27.6
1916
+ cosmiconfig: 7.1.0
1917
+ resolve: 1.22.10
1918
+
1919
+ balanced-match@1.0.2: {}
1920
+
1921
+ binary-extensions@2.3.0: {}
1922
+
1923
+ brace-expansion@2.0.1:
1924
+ dependencies:
1925
+ balanced-match: 1.0.2
1926
+
1927
+ braces@3.0.3:
1928
+ dependencies:
1929
+ fill-range: 7.1.1
1930
+
1931
+ busboy@1.6.0:
1932
+ dependencies:
1933
+ streamsearch: 1.1.0
1934
+
1935
+ callsites@3.1.0: {}
1936
+
1937
+ camelcase-css@2.0.1: {}
1938
+
1939
+ caniuse-lite@1.0.30001721: {}
1940
+
1941
+ chokidar@3.6.0:
1942
+ dependencies:
1943
+ anymatch: 3.1.3
1944
+ braces: 3.0.3
1945
+ glob-parent: 5.1.2
1946
+ is-binary-path: 2.1.0
1947
+ is-glob: 4.0.3
1948
+ normalize-path: 3.0.0
1949
+ readdirp: 3.6.0
1950
+ optionalDependencies:
1951
+ fsevents: 2.3.3
1952
+
1953
+ class-variance-authority@0.7.1:
1954
+ dependencies:
1955
+ clsx: 2.1.1
1956
+
1957
+ client-only@0.0.1: {}
1958
+
1959
+ clsx@2.1.1: {}
1960
+
1961
+ color-convert@2.0.1:
1962
+ dependencies:
1963
+ color-name: 1.1.4
1964
+
1965
+ color-name@1.1.4: {}
1966
+
1967
+ commander@4.1.1: {}
1968
+
1969
+ convert-source-map@1.9.0: {}
1970
+
1971
+ cosmiconfig@7.1.0:
1972
+ dependencies:
1973
+ '@types/parse-json': 4.0.2
1974
+ import-fresh: 3.3.1
1975
+ parse-json: 5.2.0
1976
+ path-type: 4.0.0
1977
+ yaml: 1.10.2
1978
+
1979
+ cross-spawn@7.0.6:
1980
+ dependencies:
1981
+ path-key: 3.1.1
1982
+ shebang-command: 2.0.0
1983
+ which: 2.0.2
1984
+
1985
+ cssesc@3.0.0: {}
1986
+
1987
+ csstype@3.1.3: {}
1988
+
1989
+ date-fns@4.1.0: {}
1990
+
1991
+ debug@4.4.1:
1992
+ dependencies:
1993
+ ms: 2.1.3
1994
+
1995
+ detect-node-es@1.1.0: {}
1996
+
1997
+ didyoumean@1.2.2: {}
1998
+
1999
+ dlv@1.1.3: {}
2000
+
2001
+ dom-helpers@5.2.1:
2002
+ dependencies:
2003
+ '@babel/runtime': 7.27.6
2004
+ csstype: 3.1.3
2005
+
2006
+ eastasianwidth@0.2.0: {}
2007
+
2008
+ emoji-regex@8.0.0: {}
2009
+
2010
+ emoji-regex@9.2.2: {}
2011
+
2012
+ error-ex@1.3.2:
2013
+ dependencies:
2014
+ is-arrayish: 0.2.1
2015
+
2016
+ escape-string-regexp@4.0.0: {}
2017
+
2018
+ fast-glob@3.3.3:
2019
+ dependencies:
2020
+ '@nodelib/fs.stat': 2.0.5
2021
+ '@nodelib/fs.walk': 1.2.8
2022
+ glob-parent: 5.1.2
2023
+ merge2: 1.4.1
2024
+ micromatch: 4.0.8
2025
+
2026
+ fastq@1.19.1:
2027
+ dependencies:
2028
+ reusify: 1.1.0
2029
+
2030
+ fill-range@7.1.1:
2031
+ dependencies:
2032
+ to-regex-range: 5.0.1
2033
+
2034
+ find-root@1.1.0: {}
2035
+
2036
+ foreground-child@3.3.1:
2037
+ dependencies:
2038
+ cross-spawn: 7.0.6
2039
+ signal-exit: 4.1.0
2040
+
2041
+ fsevents@2.3.3:
2042
+ optional: true
2043
+
2044
+ function-bind@1.1.2: {}
2045
+
2046
+ get-nonce@1.0.1: {}
2047
+
2048
+ glob-parent@5.1.2:
2049
+ dependencies:
2050
+ is-glob: 4.0.3
2051
+
2052
+ glob-parent@6.0.2:
2053
+ dependencies:
2054
+ is-glob: 4.0.3
2055
+
2056
+ glob@10.4.5:
2057
+ dependencies:
2058
+ foreground-child: 3.3.1
2059
+ jackspeak: 3.4.3
2060
+ minimatch: 9.0.5
2061
+ minipass: 7.1.2
2062
+ package-json-from-dist: 1.0.1
2063
+ path-scurry: 1.11.1
2064
+
2065
+ globals@11.12.0: {}
2066
+
2067
+ graceful-fs@4.2.11: {}
2068
+
2069
+ hasown@2.0.2:
2070
+ dependencies:
2071
+ function-bind: 1.1.2
2072
+
2073
+ hoist-non-react-statics@3.3.2:
2074
+ dependencies:
2075
+ react-is: 16.13.1
2076
+
2077
+ import-fresh@3.3.1:
2078
+ dependencies:
2079
+ parent-module: 1.0.1
2080
+ resolve-from: 4.0.0
2081
+
2082
+ is-arrayish@0.2.1: {}
2083
+
2084
+ is-binary-path@2.1.0:
2085
+ dependencies:
2086
+ binary-extensions: 2.3.0
2087
+
2088
+ is-core-module@2.16.1:
2089
+ dependencies:
2090
+ hasown: 2.0.2
2091
+
2092
+ is-extglob@2.1.1: {}
2093
+
2094
+ is-fullwidth-code-point@3.0.0: {}
2095
+
2096
+ is-glob@4.0.3:
2097
+ dependencies:
2098
+ is-extglob: 2.1.1
2099
+
2100
+ is-number@7.0.0: {}
2101
+
2102
+ isexe@2.0.0: {}
2103
+
2104
+ jackspeak@3.4.3:
2105
+ dependencies:
2106
+ '@isaacs/cliui': 8.0.2
2107
+ optionalDependencies:
2108
+ '@pkgjs/parseargs': 0.11.0
2109
+
2110
+ jiti@1.21.7: {}
2111
+
2112
+ js-tokens@4.0.0: {}
2113
+
2114
+ jsesc@3.1.0: {}
2115
+
2116
+ json-parse-even-better-errors@2.3.1: {}
2117
+
2118
+ lilconfig@3.1.3: {}
2119
+
2120
+ lines-and-columns@1.2.4: {}
2121
+
2122
+ loose-envify@1.4.0:
2123
+ dependencies:
2124
+ js-tokens: 4.0.0
2125
+
2126
+ lru-cache@10.4.3: {}
2127
+
2128
+ lucide-react@0.427.0(react@18.3.1):
2129
+ dependencies:
2130
+ react: 18.3.1
2131
+
2132
+ merge2@1.4.1: {}
2133
+
2134
+ micromatch@4.0.8:
2135
+ dependencies:
2136
+ braces: 3.0.3
2137
+ picomatch: 2.3.1
2138
+
2139
+ minimatch@9.0.5:
2140
+ dependencies:
2141
+ brace-expansion: 2.0.1
2142
+
2143
+ minipass@7.1.2: {}
2144
+
2145
+ ms@2.1.3: {}
2146
+
2147
+ mz@2.7.0:
2148
+ dependencies:
2149
+ any-promise: 1.3.0
2150
+ object-assign: 4.1.1
2151
+ thenify-all: 1.6.0
2152
+
2153
+ nanoid@3.3.11: {}
2154
+
2155
+ next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
2156
+ dependencies:
2157
+ '@next/env': 14.2.5
2158
+ '@swc/helpers': 0.5.5
2159
+ busboy: 1.6.0
2160
+ caniuse-lite: 1.0.30001721
2161
+ graceful-fs: 4.2.11
2162
+ postcss: 8.4.31
2163
+ react: 18.3.1
2164
+ react-dom: 18.3.1(react@18.3.1)
2165
+ styled-jsx: 5.1.1(react@18.3.1)
2166
+ optionalDependencies:
2167
+ '@next/swc-darwin-arm64': 14.2.5
2168
+ '@next/swc-darwin-x64': 14.2.5
2169
+ '@next/swc-linux-arm64-gnu': 14.2.5
2170
+ '@next/swc-linux-arm64-musl': 14.2.5
2171
+ '@next/swc-linux-x64-gnu': 14.2.5
2172
+ '@next/swc-linux-x64-musl': 14.2.5
2173
+ '@next/swc-win32-arm64-msvc': 14.2.5
2174
+ '@next/swc-win32-ia32-msvc': 14.2.5
2175
+ '@next/swc-win32-x64-msvc': 14.2.5
2176
+ transitivePeerDependencies:
2177
+ - '@babel/core'
2178
+ - babel-plugin-macros
2179
+
2180
+ normalize-path@3.0.0: {}
2181
+
2182
+ object-assign@4.1.1: {}
2183
+
2184
+ object-hash@3.0.0: {}
2185
+
2186
+ package-json-from-dist@1.0.1: {}
2187
+
2188
+ parent-module@1.0.1:
2189
+ dependencies:
2190
+ callsites: 3.1.0
2191
+
2192
+ parse-json@5.2.0:
2193
+ dependencies:
2194
+ '@babel/code-frame': 7.27.1
2195
+ error-ex: 1.3.2
2196
+ json-parse-even-better-errors: 2.3.1
2197
+ lines-and-columns: 1.2.4
2198
+
2199
+ path-key@3.1.1: {}
2200
+
2201
+ path-parse@1.0.7: {}
2202
+
2203
+ path-scurry@1.11.1:
2204
+ dependencies:
2205
+ lru-cache: 10.4.3
2206
+ minipass: 7.1.2
2207
+
2208
+ path-type@4.0.0: {}
2209
+
2210
+ picocolors@1.1.1: {}
2211
+
2212
+ picomatch@2.3.1: {}
2213
+
2214
+ pify@2.3.0: {}
2215
+
2216
+ pirates@4.0.7: {}
2217
+
2218
+ postcss-import@15.1.0(postcss@8.5.4):
2219
+ dependencies:
2220
+ postcss: 8.5.4
2221
+ postcss-value-parser: 4.2.0
2222
+ read-cache: 1.0.0
2223
+ resolve: 1.22.10
2224
+
2225
+ postcss-js@4.0.1(postcss@8.5.4):
2226
+ dependencies:
2227
+ camelcase-css: 2.0.1
2228
+ postcss: 8.5.4
2229
+
2230
+ postcss-load-config@4.0.2(postcss@8.5.4):
2231
+ dependencies:
2232
+ lilconfig: 3.1.3
2233
+ yaml: 2.8.0
2234
+ optionalDependencies:
2235
+ postcss: 8.5.4
2236
+
2237
+ postcss-nested@6.2.0(postcss@8.5.4):
2238
+ dependencies:
2239
+ postcss: 8.5.4
2240
+ postcss-selector-parser: 6.1.2
2241
+
2242
+ postcss-selector-parser@6.1.2:
2243
+ dependencies:
2244
+ cssesc: 3.0.0
2245
+ util-deprecate: 1.0.2
2246
+
2247
+ postcss-value-parser@4.2.0: {}
2248
+
2249
+ postcss@8.4.31:
2250
+ dependencies:
2251
+ nanoid: 3.3.11
2252
+ picocolors: 1.1.1
2253
+ source-map-js: 1.2.1
2254
+
2255
+ postcss@8.5.4:
2256
+ dependencies:
2257
+ nanoid: 3.3.11
2258
+ picocolors: 1.1.1
2259
+ source-map-js: 1.2.1
2260
+
2261
+ prop-types@15.8.1:
2262
+ dependencies:
2263
+ loose-envify: 1.4.0
2264
+ object-assign: 4.1.1
2265
+ react-is: 16.13.1
2266
+
2267
+ queue-microtask@1.2.3: {}
2268
+
2269
+ react-activity-calendar@2.7.12(react@18.3.1):
2270
+ dependencies:
2271
+ date-fns: 4.1.0
2272
+ react: 18.3.1
2273
+
2274
+ react-dom@18.3.1(react@18.3.1):
2275
+ dependencies:
2276
+ loose-envify: 1.4.0
2277
+ react: 18.3.1
2278
+ scheduler: 0.23.2
2279
+
2280
+ react-is@16.13.1: {}
2281
+
2282
+ react-is@19.1.0: {}
2283
+
2284
+ react-remove-scroll-bar@2.3.8(@types/react@18.3.23)(react@18.3.1):
2285
+ dependencies:
2286
+ react: 18.3.1
2287
+ react-style-singleton: 2.2.3(@types/react@18.3.23)(react@18.3.1)
2288
+ tslib: 2.8.1
2289
+ optionalDependencies:
2290
+ '@types/react': 18.3.23
2291
+
2292
+ react-remove-scroll@2.7.1(@types/react@18.3.23)(react@18.3.1):
2293
+ dependencies:
2294
+ react: 18.3.1
2295
+ react-remove-scroll-bar: 2.3.8(@types/react@18.3.23)(react@18.3.1)
2296
+ react-style-singleton: 2.2.3(@types/react@18.3.23)(react@18.3.1)
2297
+ tslib: 2.8.1
2298
+ use-callback-ref: 1.3.3(@types/react@18.3.23)(react@18.3.1)
2299
+ use-sidecar: 1.1.3(@types/react@18.3.23)(react@18.3.1)
2300
+ optionalDependencies:
2301
+ '@types/react': 18.3.23
2302
+
2303
+ react-style-singleton@2.2.3(@types/react@18.3.23)(react@18.3.1):
2304
+ dependencies:
2305
+ get-nonce: 1.0.1
2306
+ react: 18.3.1
2307
+ tslib: 2.8.1
2308
+ optionalDependencies:
2309
+ '@types/react': 18.3.23
2310
+
2311
+ react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
2312
+ dependencies:
2313
+ '@babel/runtime': 7.27.6
2314
+ dom-helpers: 5.2.1
2315
+ loose-envify: 1.4.0
2316
+ prop-types: 15.8.1
2317
+ react: 18.3.1
2318
+ react-dom: 18.3.1(react@18.3.1)
2319
+
2320
+ react@18.3.1:
2321
+ dependencies:
2322
+ loose-envify: 1.4.0
2323
+
2324
+ read-cache@1.0.0:
2325
+ dependencies:
2326
+ pify: 2.3.0
2327
+
2328
+ readdirp@3.6.0:
2329
+ dependencies:
2330
+ picomatch: 2.3.1
2331
+
2332
+ resolve-from@4.0.0: {}
2333
+
2334
+ resolve@1.22.10:
2335
+ dependencies:
2336
+ is-core-module: 2.16.1
2337
+ path-parse: 1.0.7
2338
+ supports-preserve-symlinks-flag: 1.0.0
2339
+
2340
+ reusify@1.1.0: {}
2341
+
2342
+ run-parallel@1.2.0:
2343
+ dependencies:
2344
+ queue-microtask: 1.2.3
2345
+
2346
+ scheduler@0.23.2:
2347
+ dependencies:
2348
+ loose-envify: 1.4.0
2349
+
2350
+ shebang-command@2.0.0:
2351
+ dependencies:
2352
+ shebang-regex: 3.0.0
2353
+
2354
+ shebang-regex@3.0.0: {}
2355
+
2356
+ signal-exit@4.1.0: {}
2357
+
2358
+ source-map-js@1.2.1: {}
2359
+
2360
+ source-map@0.5.7: {}
2361
+
2362
+ streamsearch@1.1.0: {}
2363
+
2364
+ string-width@4.2.3:
2365
+ dependencies:
2366
+ emoji-regex: 8.0.0
2367
+ is-fullwidth-code-point: 3.0.0
2368
+ strip-ansi: 6.0.1
2369
+
2370
+ string-width@5.1.2:
2371
+ dependencies:
2372
+ eastasianwidth: 0.2.0
2373
+ emoji-regex: 9.2.2
2374
+ strip-ansi: 7.1.0
2375
+
2376
+ strip-ansi@6.0.1:
2377
+ dependencies:
2378
+ ansi-regex: 5.0.1
2379
+
2380
+ strip-ansi@7.1.0:
2381
+ dependencies:
2382
+ ansi-regex: 6.1.0
2383
+
2384
+ styled-jsx@5.1.1(react@18.3.1):
2385
+ dependencies:
2386
+ client-only: 0.0.1
2387
+ react: 18.3.1
2388
+
2389
+ stylis@4.2.0: {}
2390
+
2391
+ sucrase@3.35.0:
2392
+ dependencies:
2393
+ '@jridgewell/gen-mapping': 0.3.8
2394
+ commander: 4.1.1
2395
+ glob: 10.4.5
2396
+ lines-and-columns: 1.2.4
2397
+ mz: 2.7.0
2398
+ pirates: 4.0.7
2399
+ ts-interface-checker: 0.1.13
2400
+
2401
+ supports-preserve-symlinks-flag@1.0.0: {}
2402
+
2403
+ tailwind-merge@2.6.0: {}
2404
+
2405
+ tailwindcss-animate@1.0.7(tailwindcss@3.4.17):
2406
+ dependencies:
2407
+ tailwindcss: 3.4.17
2408
+
2409
+ tailwindcss@3.4.17:
2410
+ dependencies:
2411
+ '@alloc/quick-lru': 5.2.0
2412
+ arg: 5.0.2
2413
+ chokidar: 3.6.0
2414
+ didyoumean: 1.2.2
2415
+ dlv: 1.1.3
2416
+ fast-glob: 3.3.3
2417
+ glob-parent: 6.0.2
2418
+ is-glob: 4.0.3
2419
+ jiti: 1.21.7
2420
+ lilconfig: 3.1.3
2421
+ micromatch: 4.0.8
2422
+ normalize-path: 3.0.0
2423
+ object-hash: 3.0.0
2424
+ picocolors: 1.1.1
2425
+ postcss: 8.5.4
2426
+ postcss-import: 15.1.0(postcss@8.5.4)
2427
+ postcss-js: 4.0.1(postcss@8.5.4)
2428
+ postcss-load-config: 4.0.2(postcss@8.5.4)
2429
+ postcss-nested: 6.2.0(postcss@8.5.4)
2430
+ postcss-selector-parser: 6.1.2
2431
+ resolve: 1.22.10
2432
+ sucrase: 3.35.0
2433
+ transitivePeerDependencies:
2434
+ - ts-node
2435
+
2436
+ thenify-all@1.6.0:
2437
+ dependencies:
2438
+ thenify: 3.3.1
2439
+
2440
+ thenify@3.3.1:
2441
+ dependencies:
2442
+ any-promise: 1.3.0
2443
+
2444
+ to-regex-range@5.0.1:
2445
+ dependencies:
2446
+ is-number: 7.0.0
2447
+
2448
+ ts-interface-checker@0.1.13: {}
2449
+
2450
+ tslib@2.8.1: {}
2451
+
2452
+ typescript@5.8.3: {}
2453
+
2454
+ undici-types@6.21.0: {}
2455
+
2456
+ use-callback-ref@1.3.3(@types/react@18.3.23)(react@18.3.1):
2457
+ dependencies:
2458
+ react: 18.3.1
2459
+ tslib: 2.8.1
2460
+ optionalDependencies:
2461
+ '@types/react': 18.3.23
2462
+
2463
+ use-sidecar@1.1.3(@types/react@18.3.23)(react@18.3.1):
2464
+ dependencies:
2465
+ detect-node-es: 1.1.0
2466
+ react: 18.3.1
2467
+ tslib: 2.8.1
2468
+ optionalDependencies:
2469
+ '@types/react': 18.3.23
2470
+
2471
+ use-sync-external-store@1.5.0(react@18.3.1):
2472
+ dependencies:
2473
+ react: 18.3.1
2474
+
2475
+ util-deprecate@1.0.2: {}
2476
+
2477
+ which@2.0.2:
2478
+ dependencies:
2479
+ isexe: 2.0.0
2480
+
2481
+ wrap-ansi@7.0.0:
2482
+ dependencies:
2483
+ ansi-styles: 4.3.0
2484
+ string-width: 4.2.3
2485
+ strip-ansi: 6.0.1
2486
+
2487
+ wrap-ansi@8.1.0:
2488
+ dependencies:
2489
+ ansi-styles: 6.2.1
2490
+ string-width: 5.1.2
2491
+ strip-ansi: 7.1.0
2492
+
2493
+ yaml@1.10.2: {}
2494
+
2495
+ yaml@2.8.0: {}
postcss.config.mjs ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ tailwindcss: {},
5
+ },
6
+ };
7
+
8
+ export default config;
public/favicon.ico ADDED
public/next.svg ADDED
public/vercel.svg ADDED
src/components/Heatmap.tsx ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import ActivityCalendar from "react-activity-calendar";
3
+ import { Tooltip, Avatar } from "@mui/material";
4
+ import Link from "next/link";
5
+
6
+ type HeatmapProps = {
7
+ data: Array<{ date: string; count: number; level: number }>;
8
+ color: string;
9
+ providerName: string;
10
+ fullName: string;
11
+ avatarUrl: string;
12
+ authorId: string;
13
+ showHeader?: boolean;
14
+ };
15
+
16
+ const Heatmap: React.FC<HeatmapProps> = ({ data, color, providerName, fullName, avatarUrl, authorId, showHeader = true }) => {
17
+ return (
18
+ <div className="flex flex-col items-center w-full mx-auto">
19
+ {showHeader && (
20
+ <div className="flex flex-col sm:flex-row items-center mb-4 w-full justify-center">
21
+ {avatarUrl && (
22
+ <Avatar src={avatarUrl} alt={fullName} className="mb-2 sm:mb-0 sm:mr-4" sx={{ width: 48, height: 48 }} />
23
+ )}
24
+ <div className="text-center sm:text-left">
25
+ <h2 className="text-lg font-semibold">
26
+ <Link
27
+ href={`https://huggingface.co/${authorId}`}
28
+ target="_blank"
29
+ rel="noopener noreferrer"
30
+ className="hover:text-blue-500 hover:underline"
31
+ >
32
+ {fullName}
33
+ </Link>
34
+ </h2>
35
+ </div>
36
+ </div>
37
+ )}
38
+ <div className="w-full overflow-x-auto flex justify-center">
39
+ <ActivityCalendar
40
+ data={data}
41
+ theme={{
42
+ dark: ["#161b22", color],
43
+ light: ["#e0e0e0", color],
44
+ }}
45
+ hideTotalCount
46
+ renderBlock={(block, activity) => (
47
+ <Tooltip
48
+ title={`${activity.count} events on ${activity.date}`}
49
+ arrow
50
+ >
51
+ {block}
52
+ </Tooltip>
53
+ )}
54
+ />
55
+ </div>
56
+ </div>
57
+ );
58
+ };
59
+
60
+ export default Heatmap;
src/components/OrganizationCard.tsx ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { ProviderInfo } from "../types/heatmap";
3
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
4
+
5
+ interface OrganizationCardProps {
6
+ provider: ProviderInfo;
7
+ calendarKey: string;
8
+ providerName: string;
9
+ totalCount: number;
10
+ }
11
+
12
+ const OrganizationCard: React.FC<OrganizationCardProps> = ({
13
+ provider,
14
+ calendarKey,
15
+ providerName,
16
+ totalCount,
17
+ }) => {
18
+ return (
19
+ <TooltipProvider>
20
+ <div className="mb-4">
21
+ {/* Organization Name & Stats Badge */}
22
+ <div className="text-center bg-muted/20 rounded-lg p-3 border border-border/30">
23
+ {/* Avatar and Name Row */}
24
+ <div className="flex items-center justify-center gap-2 mb-2">
25
+ {/* Multi-author avatars and names */}
26
+ {provider.authorsData && provider.authorsData.length > 1 ? (
27
+ <div className="flex items-center gap-2 flex-wrap justify-center">
28
+ {provider.authorsData.map((authorData, index) => (
29
+ <React.Fragment key={authorData.author}>
30
+ {index > 0 && (
31
+ <span className="text-muted-foreground text-sm font-medium mx-1">+</span>
32
+ )}
33
+ <div className="flex items-center gap-1">
34
+ <div className="relative">
35
+ <img
36
+ src={authorData.avatarUrl || `https://huggingface.co/${authorData.author}/avatar.jpg`}
37
+ alt={`${authorData.fullName} logo`}
38
+ className="w-8 h-8 rounded-md shadow-sm border border-border/50"
39
+ onError={(e) => {
40
+ const target = e.target as HTMLImageElement;
41
+ target.src = `https://ui-avatars.com/api/?name=${encodeURIComponent(authorData.fullName)}&background=random`;
42
+ }}
43
+ />
44
+ {authorData.isVerified && (
45
+ <div className="absolute -bottom-0.5 -right-0.5 w-3 h-3 bg-blue-500 rounded-full flex items-center justify-center">
46
+ <svg className="w-2 h-2 text-white" fill="currentColor" viewBox="0 0 20 20">
47
+ <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
48
+ </svg>
49
+ </div>
50
+ )}
51
+ </div>
52
+ <span className="text-base font-bold text-foreground">
53
+ <a
54
+ href={`https://huggingface.co/${authorData.author}`}
55
+ target="_blank"
56
+ rel="noopener noreferrer"
57
+ className="hover:text-blue-500 hover:underline transition-colors duration-200"
58
+ >
59
+ {authorData.author}
60
+ </a>
61
+ </span>
62
+ </div>
63
+ </React.Fragment>
64
+ ))}
65
+ </div>
66
+ ) : (
67
+ <div className="flex items-center gap-2">
68
+ {provider.avatarUrl && (
69
+ <div className="relative">
70
+ <img
71
+ src={provider.avatarUrl}
72
+ alt={`${providerName} logo`}
73
+ className="w-8 h-8 rounded-md shadow-sm border border-border/50"
74
+ />
75
+ {provider.isVerified && (
76
+ <div className="absolute -bottom-0.5 -right-0.5 w-3 h-3 bg-blue-500 rounded-full flex items-center justify-center">
77
+ <svg className="w-2 h-2 text-white" fill="currentColor" viewBox="0 0 20 20">
78
+ <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
79
+ </svg>
80
+ </div>
81
+ )}
82
+ </div>
83
+ )}
84
+ <h3 className="text-base font-bold text-foreground">
85
+ <a
86
+ href={`https://huggingface.co/${calendarKey}`}
87
+ target="_blank"
88
+ rel="noopener noreferrer"
89
+ className="hover:text-blue-500 hover:underline transition-colors duration-200"
90
+ >
91
+ {providerName}
92
+ </a>
93
+ </h3>
94
+ </div>
95
+ )}
96
+ </div>
97
+
98
+ {/* Compact Organization Stats */}
99
+ <div className="flex flex-wrap justify-center gap-2 text-xs mb-3">
100
+ {provider.authorsData && provider.authorsData.length > 1 ? (
101
+ <Tooltip>
102
+ <TooltipTrigger asChild>
103
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40 cursor-pointer">
104
+ <span className="font-semibold text-foreground">{(provider.numModels || 0).toLocaleString()}</span>
105
+ <span className="text-muted-foreground ml-1">models</span>
106
+ </div>
107
+ </TooltipTrigger>
108
+ <TooltipContent side="bottom">
109
+ <div className="text-xs">
110
+ {provider.authorsData.map(author => (
111
+ <div key={`models-${author.author}`}>
112
+ {author.author}: {author.numModels.toLocaleString()}
113
+ </div>
114
+ ))}
115
+ </div>
116
+ </TooltipContent>
117
+ </Tooltip>
118
+ ) : (
119
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40">
120
+ <span className="font-semibold text-foreground">{(provider.numModels || 0).toLocaleString()}</span>
121
+ <span className="text-muted-foreground ml-1">models</span>
122
+ </div>
123
+ )}
124
+
125
+ {provider.authorsData && provider.authorsData.length > 1 ? (
126
+ <Tooltip>
127
+ <TooltipTrigger asChild>
128
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40 cursor-pointer">
129
+ <span className="font-semibold text-foreground">{(provider.numDatasets || 0).toLocaleString()}</span>
130
+ <span className="text-muted-foreground ml-1">datasets</span>
131
+ </div>
132
+ </TooltipTrigger>
133
+ <TooltipContent side="bottom">
134
+ <div className="text-xs">
135
+ {provider.authorsData.map(author => (
136
+ <div key={`datasets-${author.author}`}>
137
+ {author.author}: {author.numDatasets.toLocaleString()}
138
+ </div>
139
+ ))}
140
+ </div>
141
+ </TooltipContent>
142
+ </Tooltip>
143
+ ) : (
144
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40">
145
+ <span className="font-semibold text-foreground">{(provider.numDatasets || 0).toLocaleString()}</span>
146
+ <span className="text-muted-foreground ml-1">datasets</span>
147
+ </div>
148
+ )}
149
+
150
+ {provider.authorsData && provider.authorsData.length > 1 ? (
151
+ <Tooltip>
152
+ <TooltipTrigger asChild>
153
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40 cursor-pointer">
154
+ <span className="font-semibold text-foreground">{(provider.numSpaces || 0).toLocaleString()}</span>
155
+ <span className="text-muted-foreground ml-1">spaces</span>
156
+ </div>
157
+ </TooltipTrigger>
158
+ <TooltipContent side="bottom">
159
+ <div className="text-xs">
160
+ {provider.authorsData.map(author => (
161
+ <div key={`spaces-${author.author}`}>
162
+ {author.author}: {author.numSpaces.toLocaleString()}
163
+ </div>
164
+ ))}
165
+ </div>
166
+ </TooltipContent>
167
+ </Tooltip>
168
+ ) : (
169
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40">
170
+ <span className="font-semibold text-foreground">{(provider.numSpaces || 0).toLocaleString()}</span>
171
+ <span className="text-muted-foreground ml-1">spaces</span>
172
+ </div>
173
+ )}
174
+
175
+ {provider.authorsData && provider.authorsData.length > 1 ? (
176
+ <Tooltip>
177
+ <TooltipTrigger asChild>
178
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40 cursor-pointer">
179
+ <span className="font-semibold text-foreground">{(provider.numFollowers || 0).toLocaleString()}</span>
180
+ <span className="text-muted-foreground ml-1">followers</span>
181
+ </div>
182
+ </TooltipTrigger>
183
+ <TooltipContent side="bottom">
184
+ <div className="text-xs">
185
+ {provider.authorsData.map(author => (
186
+ <div key={`followers-${author.author}`}>
187
+ {author.author}: {author.numFollowers.toLocaleString()}
188
+ </div>
189
+ ))}
190
+ </div>
191
+ </TooltipContent>
192
+ </Tooltip>
193
+ ) : (
194
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40">
195
+ <span className="font-semibold text-foreground">{(provider.numFollowers || 0).toLocaleString()}</span>
196
+ <span className="text-muted-foreground ml-1">followers</span>
197
+ </div>
198
+ )}
199
+
200
+ <div className="bg-background/60 rounded px-2 py-1 border border-border/40">
201
+ <span className="text-muted-foreground mr-1">Total</span>
202
+ <span className="font-semibold text-foreground">{(provider.totalDownloads || 0).toLocaleString()}</span>
203
+ <span className="text-muted-foreground ml-1">downloads</span>
204
+ </div>
205
+ </div>
206
+
207
+ {/* Divider */}
208
+ <div className="border-t border-border/20 mb-3"></div>
209
+
210
+ {/* Releases Past Year */}
211
+ <div className="text-xs text-muted-foreground italic">
212
+ <span className="font-bold text-foreground">{totalCount.toLocaleString()}</span> in the last year
213
+ </div>
214
+ </div>
215
+ </div>
216
+ </TooltipProvider>
217
+ );
218
+ };
219
+
220
+ export default OrganizationCard;
src/components/ProviderSummary.tsx ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { ProviderInfo, CalendarData } from "../types/heatmap";
3
+
4
+ interface ProviderSummaryProps {
5
+ provider: ProviderInfo;
6
+ calendarData: CalendarData;
7
+ rank: number;
8
+ }
9
+
10
+ const ProviderSummary: React.FC<ProviderSummaryProps> = ({
11
+ provider,
12
+ calendarData,
13
+ rank
14
+ }) => {
15
+ const providerName = provider.fullName || provider.authors[0];
16
+ const calendarKey = provider.authors[0];
17
+ const totalCount = calendarData[calendarKey]?.reduce((sum, day) => sum + day.count, 0) || 0;
18
+
19
+ const handleClick = () => {
20
+ const element = document.getElementById(`provider-${calendarKey}`);
21
+ if (element) {
22
+ element.scrollIntoView({ behavior: 'smooth' });
23
+ }
24
+ };
25
+
26
+ const getRankBadgeClasses = () => {
27
+ if (rank === 1) {
28
+ return "bg-gradient-to-br from-yellow-400 to-yellow-600 text-yellow-900";
29
+ }
30
+ if (rank === 2) {
31
+ return "bg-gradient-to-br from-gray-300 to-gray-500 text-gray-900";
32
+ }
33
+ if (rank === 3) {
34
+ return "bg-gradient-to-br from-amber-600 to-amber-800 text-amber-100";
35
+ }
36
+ return "bg-gradient-to-br from-gray-800 to-gray-900 text-gray-100";
37
+ };
38
+
39
+ const formatCount = (num: number): string => {
40
+ if (num >= 1000) return `${(num / 1000).toFixed(1)}K`;
41
+ return num.toString();
42
+ };
43
+
44
+ return (
45
+ <div
46
+ className="flex flex-col items-center min-w-0 flex-shrink-0 cursor-pointer group px-1"
47
+ onClick={handleClick}
48
+ >
49
+ {/* Logo Circle */}
50
+ <div className="relative">
51
+ {/* Rank Badge */}
52
+ <div className={`absolute -top-2 -left-2 ${getRankBadgeClasses()} text-xs font-bold rounded-full min-w-[24px] h-6 flex items-center justify-center px-1.5 shadow-lg border-2 border-background z-10`}>
53
+ #{rank}
54
+ </div>
55
+
56
+ {provider.avatarUrl ? (
57
+ <img
58
+ src={provider.avatarUrl}
59
+ alt={`${providerName} logo`}
60
+ className="w-16 h-16 rounded-full shadow-lg border-2 border-border/50 hover:border-blue-500/50 transition-all duration-200"
61
+ />
62
+ ) : (
63
+ <div className="w-16 h-16 rounded-full bg-muted flex items-center justify-center text-xl font-bold text-muted-foreground hover:bg-muted/80 transition-all duration-200">
64
+ {providerName.charAt(0).toUpperCase()}
65
+ </div>
66
+ )}
67
+ </div>
68
+
69
+ {/* Activity Info */}
70
+ <div className="mt-1.5 text-center space-y-0.5">
71
+ {/* Provider Name */}
72
+ <div className="text-xs font-medium text-foreground truncate max-w-20 text-center">
73
+ {providerName}
74
+ </div>
75
+
76
+ {/* Release Count */}
77
+ <div className="text-[10px] text-muted-foreground">
78
+ {formatCount(totalCount)} in the last year
79
+ </div>
80
+
81
+
82
+ </div>
83
+ </div>
84
+ );
85
+ };
86
+
87
+ export default ProviderSummary;
src/components/UserSearchDialog.tsx ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useMemo } from "react";
2
+ import { Input } from "./ui/input";
3
+ import {
4
+ Dialog,
5
+ DialogContent,
6
+ DialogHeader,
7
+ DialogTitle,
8
+ DialogTrigger,
9
+ } from "./ui/dialog";
10
+ import { Button } from "./ui/button";
11
+ import { generateCalendarData } from "../utils/calendar";
12
+ import Heatmap from "./Heatmap";
13
+ import { ModelData } from "../types/heatmap";
14
+ import { fetchAuthorData, fetchOrganizationData } from "@/utils/authors";
15
+
16
+ const UserSearchDialog = () => {
17
+ const [isOpen, setIsOpen] = useState(false);
18
+ const [isLoading, setIsLoading] = useState(false);
19
+ const [searchInput, setSearchInput] = useState("");
20
+ const [searchedData, setSearchedData] = useState<ModelData[] | null>(null);
21
+ const [isCopied, setIsCopied] = useState(false);
22
+ const [currentSearchTerm, setCurrentSearchTerm] = useState("");
23
+ const [userInfo, setUserInfo] = useState<{ fullName: string; avatarUrl: string | null } | null>(null);
24
+
25
+ const handleSearch = async () => {
26
+ if (searchInput.trim()) {
27
+ setIsLoading(true);
28
+ try {
29
+ const authorData = await fetchAuthorData(searchInput.trim());
30
+ const authorInfo = await fetchOrganizationData([searchInput.trim()]);
31
+ setSearchedData(authorData);
32
+ setUserInfo(authorInfo);
33
+ setCurrentSearchTerm(searchInput.trim());
34
+ } catch (error) {
35
+ console.error("Error fetching data for searched user:", error);
36
+ setSearchedData(null);
37
+ setUserInfo(null);
38
+ setCurrentSearchTerm("");
39
+ }
40
+ setIsLoading(false);
41
+ } else {
42
+ setSearchedData(null);
43
+ setUserInfo(null);
44
+ setCurrentSearchTerm("");
45
+ }
46
+ };
47
+
48
+ const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
49
+ if (e.key === 'Enter') {
50
+ handleSearch();
51
+ }
52
+ };
53
+
54
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
55
+ setSearchInput(e.target.value);
56
+ };
57
+
58
+ const getIframeCode = (username: string) => {
59
+ return `<iframe
60
+ src="https://cfahlgren1-model-release-heatmap.hf.space/${username}"
61
+ class="w-full h-[300px]"
62
+ frameborder="0"
63
+ ></iframe>`;
64
+ };
65
+
66
+ const handleCopyCode = () => {
67
+ const iframeCode = getIframeCode(searchInput);
68
+ navigator.clipboard.writeText(iframeCode).then(() => {
69
+ setIsCopied(true);
70
+ setTimeout(() => setIsCopied(false), 2000);
71
+ });
72
+ };
73
+
74
+ const searchedHeatmapData = useMemo(() => {
75
+ if (searchedData && searchedData.length > 0 && userInfo) {
76
+ return generateCalendarData(searchedData, [{
77
+ authors: [currentSearchTerm],
78
+ color: "#0088cc",
79
+ fullName: userInfo.fullName,
80
+ avatarUrl: userInfo.avatarUrl
81
+ }])[currentSearchTerm];
82
+ }
83
+ return null;
84
+ }, [searchedData, currentSearchTerm, userInfo]);
85
+
86
+ const handleDialogOpenChange = (open: boolean) => {
87
+ setIsOpen(open);
88
+ if (!open) {
89
+ setSearchInput("");
90
+ setSearchedData(null);
91
+ setCurrentSearchTerm("");
92
+ setIsLoading(false);
93
+ setIsCopied(false);
94
+ setUserInfo(null);
95
+ }
96
+ };
97
+
98
+ return (
99
+ <Dialog open={isOpen} onOpenChange={handleDialogOpenChange}>
100
+ <DialogTrigger asChild>
101
+ <Button variant="outline">검색</Button>
102
+ </DialogTrigger>
103
+ <DialogContent className="w-full max-w-[95vw] sm:max-w-4xl p-4 sm:p-6 max-h-[90vh] flex flex-col">
104
+ <DialogHeader>
105
+ <DialogTitle className="text-lg sm:text-xl mb-4">Hugging Face 히트맵 생성하기</DialogTitle>
106
+ </DialogHeader>
107
+ <div className="flex-grow overflow-y-auto">
108
+ <div className="grid gap-4 py-4">
109
+ <div className="flex items-center space-x-2 p-2 bg-background rounded-md">
110
+ <Input
111
+ type="text"
112
+ placeholder="Enter username"
113
+ value={searchInput}
114
+ onChange={handleInputChange}
115
+ onKeyDown={handleKeyPress}
116
+ className="flex-grow"
117
+ />
118
+ </div>
119
+ {isLoading ? (
120
+ <p className="text-center">Loading...</p>
121
+ ) : searchedHeatmapData && userInfo ? (
122
+ <div className="mt-4 space-y-4">
123
+ <div className="overflow-x-auto pb-2">
124
+ <Heatmap
125
+ data={searchedHeatmapData}
126
+ color="#FF9D00"
127
+ providerName={currentSearchTerm}
128
+ fullName={userInfo.fullName}
129
+ avatarUrl={userInfo.avatarUrl || ''}
130
+ authorId={currentSearchTerm}
131
+ />
132
+ </div>
133
+ <div>
134
+ <div className="flex justify-between items-center mb-2">
135
+ <h3 className="font-semibold text-sm sm:text-base">Embed in iFrame</h3>
136
+ <Button onClick={handleCopyCode} variant="link" size="sm">
137
+ {isCopied ? "복사 완료!" : "복사"}
138
+ </Button>
139
+ </div>
140
+ <div className="overflow-x-auto">
141
+ <pre className="bg-secondary p-2 rounded text-xs whitespace-pre-wrap break-all">
142
+ <code>{getIframeCode(searchInput)}</code>
143
+ </pre>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ ) : searchedData !== null && searchedData.length === 0 ? (
148
+ <p className="text-center text-slate-500 text-sm italic">사용자 또는 조직을 찾을 수 없습니다</p>
149
+ ) : null}
150
+ </div>
151
+ </div>
152
+ </DialogContent>
153
+ </Dialog>
154
+ );
155
+ };
156
+
157
+ export default UserSearchDialog;
src/components/ui/avatar.tsx ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as AvatarPrimitive from "@radix-ui/react-avatar"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const Avatar = React.forwardRef<
7
+ React.ElementRef<typeof AvatarPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
9
+ >(({ className, ...props }, ref) => (
10
+ <AvatarPrimitive.Root
11
+ ref={ref}
12
+ className={cn(
13
+ "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
14
+ className
15
+ )}
16
+ {...props}
17
+ />
18
+ ))
19
+ Avatar.displayName = AvatarPrimitive.Root.displayName
20
+
21
+ const AvatarImage = React.forwardRef<
22
+ React.ElementRef<typeof AvatarPrimitive.Image>,
23
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
24
+ >(({ className, ...props }, ref) => (
25
+ <AvatarPrimitive.Image
26
+ ref={ref}
27
+ className={cn("aspect-square h-full w-full", className)}
28
+ {...props}
29
+ />
30
+ ))
31
+ AvatarImage.displayName = AvatarPrimitive.Image.displayName
32
+
33
+ const AvatarFallback = React.forwardRef<
34
+ React.ElementRef<typeof AvatarPrimitive.Fallback>,
35
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
36
+ >(({ className, ...props }, ref) => (
37
+ <AvatarPrimitive.Fallback
38
+ ref={ref}
39
+ className={cn(
40
+ "flex h-full w-full items-center justify-center rounded-full bg-muted",
41
+ className
42
+ )}
43
+ {...props}
44
+ />
45
+ ))
46
+ AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
47
+
48
+ export { Avatar, AvatarImage, AvatarFallback }
src/components/ui/button.tsx ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
+ destructive:
14
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15
+ outline:
16
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
17
+ secondary:
18
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19
+ ghost: "hover:bg-accent hover:text-accent-foreground",
20
+ link: "text-primary underline-offset-4 hover:underline",
21
+ },
22
+ size: {
23
+ default: "h-10 px-4 py-2",
24
+ sm: "h-9 rounded-md px-3",
25
+ lg: "h-11 rounded-md px-8",
26
+ icon: "h-10 w-10",
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ variant: "default",
31
+ size: "default",
32
+ },
33
+ }
34
+ )
35
+
36
+ export interface ButtonProps
37
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
38
+ VariantProps<typeof buttonVariants> {
39
+ asChild?: boolean
40
+ }
41
+
42
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
43
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
44
+ const Comp = asChild ? Slot : "button"
45
+ return (
46
+ <Comp
47
+ className={cn(buttonVariants({ variant, size, className }))}
48
+ ref={ref}
49
+ {...props}
50
+ />
51
+ )
52
+ }
53
+ )
54
+ Button.displayName = "Button"
55
+
56
+ export { Button, buttonVariants }
src/components/ui/dialog.tsx ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as DialogPrimitive from "@radix-ui/react-dialog"
3
+ import { X } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Dialog = DialogPrimitive.Root
8
+
9
+ const DialogTrigger = DialogPrimitive.Trigger
10
+
11
+ const DialogPortal = DialogPrimitive.Portal
12
+
13
+ const DialogClose = DialogPrimitive.Close
14
+
15
+ const DialogOverlay = React.forwardRef<
16
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
17
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
18
+ >(({ className, ...props }, ref) => (
19
+ <DialogPrimitive.Overlay
20
+ ref={ref}
21
+ className={cn(
22
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23
+ className
24
+ )}
25
+ {...props}
26
+ />
27
+ ))
28
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
29
+
30
+ const DialogContent = React.forwardRef<
31
+ React.ElementRef<typeof DialogPrimitive.Content>,
32
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
33
+ >(({ className, children, ...props }, ref) => (
34
+ <DialogPortal>
35
+ <DialogOverlay />
36
+ <DialogPrimitive.Content
37
+ ref={ref}
38
+ className={cn(
39
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
40
+ className
41
+ )}
42
+ {...props}
43
+ >
44
+ {children}
45
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
46
+ <X className="h-4 w-4" />
47
+ <span className="sr-only">Close</span>
48
+ </DialogPrimitive.Close>
49
+ </DialogPrimitive.Content>
50
+ </DialogPortal>
51
+ ))
52
+ DialogContent.displayName = DialogPrimitive.Content.displayName
53
+
54
+ const DialogHeader = ({
55
+ className,
56
+ ...props
57
+ }: React.HTMLAttributes<HTMLDivElement>) => (
58
+ <div
59
+ className={cn(
60
+ "flex flex-col space-y-1.5 text-center sm:text-left",
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ )
66
+ DialogHeader.displayName = "DialogHeader"
67
+
68
+ const DialogFooter = ({
69
+ className,
70
+ ...props
71
+ }: React.HTMLAttributes<HTMLDivElement>) => (
72
+ <div
73
+ className={cn(
74
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
75
+ className
76
+ )}
77
+ {...props}
78
+ />
79
+ )
80
+ DialogFooter.displayName = "DialogFooter"
81
+
82
+ const DialogTitle = React.forwardRef<
83
+ React.ElementRef<typeof DialogPrimitive.Title>,
84
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
85
+ >(({ className, ...props }, ref) => (
86
+ <DialogPrimitive.Title
87
+ ref={ref}
88
+ className={cn(
89
+ "text-lg font-semibold leading-none tracking-tight",
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ ))
95
+ DialogTitle.displayName = DialogPrimitive.Title.displayName
96
+
97
+ const DialogDescription = React.forwardRef<
98
+ React.ElementRef<typeof DialogPrimitive.Description>,
99
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
100
+ >(({ className, ...props }, ref) => (
101
+ <DialogPrimitive.Description
102
+ ref={ref}
103
+ className={cn("text-sm text-muted-foreground", className)}
104
+ {...props}
105
+ />
106
+ ))
107
+ DialogDescription.displayName = DialogPrimitive.Description.displayName
108
+
109
+ export {
110
+ Dialog,
111
+ DialogPortal,
112
+ DialogOverlay,
113
+ DialogClose,
114
+ DialogTrigger,
115
+ DialogContent,
116
+ DialogHeader,
117
+ DialogFooter,
118
+ DialogTitle,
119
+ DialogDescription,
120
+ }
src/components/ui/input.tsx ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ export interface InputProps
6
+ extends React.InputHTMLAttributes<HTMLInputElement> {}
7
+
8
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
9
+ ({ className, type, ...props }, ref) => {
10
+ return (
11
+ <input
12
+ type={type}
13
+ className={cn(
14
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
15
+ className
16
+ )}
17
+ ref={ref}
18
+ {...props}
19
+ />
20
+ )
21
+ }
22
+ )
23
+ Input.displayName = "Input"
24
+
25
+ export { Input }
src/components/ui/tooltip.tsx ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as React from "react"
2
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const TooltipProvider = TooltipPrimitive.Provider
7
+
8
+ const Tooltip = TooltipPrimitive.Root
9
+
10
+ const TooltipTrigger = TooltipPrimitive.Trigger
11
+
12
+ const TooltipContent = React.forwardRef<
13
+ React.ElementRef<typeof TooltipPrimitive.Content>,
14
+ React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
15
+ >(({ className, sideOffset = 4, ...props }, ref) => (
16
+ <TooltipPrimitive.Content
17
+ ref={ref}
18
+ sideOffset={sideOffset}
19
+ className={cn(
20
+ "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
21
+ className
22
+ )}
23
+ {...props}
24
+ />
25
+ ))
26
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName
27
+
28
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
src/lib/utils.ts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import { type ClassValue, clsx } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
src/pages/[author]/index.tsx ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from "react";
2
+ import { GetServerSidePropsContext } from "next";
3
+ import { OpenSourceHeatmapProps } from "../../types/heatmap";
4
+ import { generateCalendarData } from "../../utils/calendar";
5
+ import Heatmap from "../../components/Heatmap";
6
+ import { fetchOrganizationData, fetchAuthorData } from "../../utils/authors";
7
+
8
+ const DEFAULT_COLOR = "#FF9D00";
9
+
10
+ const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({
11
+ calendarData,
12
+ providers,
13
+ }) => {
14
+ const [isLoading, setIsLoading] = useState(true);
15
+
16
+ useEffect(() => {
17
+ if (calendarData && Object.keys(calendarData).length > 0) {
18
+ setIsLoading(false);
19
+ }
20
+ }, [calendarData]);
21
+
22
+ return (
23
+ <div className="w-full max-w-screen-lg mx-auto p-4">
24
+ {isLoading ? (
25
+ <p className="text-center">Loading...</p>
26
+ ) : (
27
+ <div>
28
+ {Object.entries(providers)
29
+ .sort(
30
+ ([keyA], [keyB]) =>
31
+ calendarData[keyB].reduce((sum, day) => sum + day.count, 0) -
32
+ calendarData[keyA].reduce((sum, day) => sum + day.count, 0)
33
+ )
34
+ .map(([providerName, { color, fullName, avatarUrl }]) => (
35
+ <Heatmap
36
+ key={providerName}
37
+ data={calendarData[providerName]}
38
+ color={color}
39
+ providerName={providerName}
40
+ fullName={fullName ?? providerName}
41
+ avatarUrl={avatarUrl ?? ''}
42
+ authorId={providerName}
43
+ />
44
+ ))}
45
+ </div>
46
+ )}
47
+ </div>
48
+ );
49
+ };
50
+
51
+ export async function getServerSideProps(context: GetServerSidePropsContext) {
52
+ const { author, color } = context.query;
53
+
54
+ const authorColor = color || DEFAULT_COLOR;
55
+
56
+ try {
57
+ const { fullName, avatarUrl } = await fetchOrganizationData([author as string]);
58
+
59
+ const flatData = await fetchAuthorData(author as string);
60
+ const totalDownloads = flatData.reduce((sum, model) => sum + (model.downloads || 0), 0);
61
+
62
+ const providers = {
63
+ [author as string]: {
64
+ color: authorColor as string,
65
+ authors: [author as string],
66
+ fullName,
67
+ avatarUrl,
68
+ totalDownloads,
69
+ },
70
+ };
71
+
72
+ const calendarData = generateCalendarData(flatData, [providers[author as string]]);
73
+
74
+ return {
75
+ props: {
76
+ calendarData,
77
+ color: authorColor,
78
+ providers,
79
+ },
80
+ };
81
+ } catch (error) {
82
+ console.error("Error fetching data:", error);
83
+ return {
84
+ props: {
85
+ calendarData: {},
86
+ color: authorColor,
87
+ providers: {
88
+ [author as string]: {
89
+ color: authorColor as string,
90
+ authors: [author as string],
91
+ fullName: author,
92
+ avatarUrl: null,
93
+ },
94
+ },
95
+ },
96
+ };
97
+ }
98
+ }
99
+
100
+ export default OpenSourceHeatmap;
src/pages/_app.tsx ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import "@/styles/globals.css";
2
+ import type { AppProps } from "next/app";
3
+
4
+ export default function App({ Component, pageProps }: AppProps) {
5
+ return <Component {...pageProps} />;
6
+ }
src/pages/_document.tsx ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Html, Head, Main, NextScript } from "next/document";
2
+
3
+ export default function Document() {
4
+ return (
5
+ <Html lang="en">
6
+ <Head />
7
+ <body>
8
+ <Main />
9
+ <NextScript />
10
+ </body>
11
+ </Html>
12
+ );
13
+ }
src/pages/index.tsx ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect, useMemo } from "react";
2
+ import { generateCalendarData } from "../utils/calendar";
3
+ import {
4
+ OpenSourceHeatmapProps,
5
+ ProviderInfo,
6
+ CalendarData,
7
+ } from "../types/heatmap";
8
+ import Heatmap from "../components/Heatmap";
9
+ import { fetchAllProvidersData, fetchAllAuthorsData } from "../utils/authors";
10
+ import UserSearchDialog from "../components/UserSearchDialog";
11
+ import ProviderSummary from "../components/ProviderSummary";
12
+ import OrganizationCard from "../components/OrganizationCard";
13
+
14
+ const PROVIDERS: ProviderInfo[] = [
15
+ { color: "#03C75A", authors: ["naver-hyperclovax", "naver-ellm", "naver", "navervision", "naver-clova-ix", "naver-clova-ocr"] }, // NAVER
16
+ { color: "#FFD200", authors: ["kakaocorp", "kakaobrain", "kakaobank"] }, // Kakao
17
+ { color: "#1428A0", authors: ["SamsungResearch", "SamsungSDS-Research"] }, // Samsung
18
+ { color: "#D70026", authors: ["skt"] }, // SK Telecom
19
+ { color: "#A50034", authors: ["LGAI-EXAONE"] }, // LG
20
+ { color: "#6366F1", authors: ["upstage"] }, // Upstage
21
+ { color: "#FF6B00", authors: ["NCSOFT", "nc-ai-consortium", "NC-AI-consortium-VAETKI"] }, // NCSOFT
22
+ { color: "#E11D48", authors: ["KRAFTON"] }, // Krafton
23
+ { color: "#F59E0B", authors: ["trillionlabs"] }, // Trillion Labs
24
+ ];
25
+
26
+ export async function getStaticProps() {
27
+ try {
28
+ const allAuthors = PROVIDERS.flatMap(({ authors }) => authors);
29
+ const uniqueAuthors = Array.from(new Set(allAuthors));
30
+
31
+ const { flatData, dataMap } = await fetchAllAuthorsData(uniqueAuthors);
32
+ const updatedProviders = await fetchAllProvidersData(PROVIDERS, dataMap);
33
+
34
+ const calendarData = generateCalendarData(flatData, updatedProviders);
35
+
36
+ return {
37
+ props: {
38
+ calendarData,
39
+ providers: updatedProviders,
40
+ },
41
+ revalidate: 3600, // regenerate every hour
42
+ };
43
+ } catch (error) {
44
+ console.error("Error fetching data:", error);
45
+ return {
46
+ props: {
47
+ calendarData: {},
48
+ providers: PROVIDERS,
49
+ },
50
+ revalidate: 60, // retry after 1 minute if there was an error
51
+ };
52
+ }
53
+ }
54
+
55
+ const ProviderHeatmap = React.memo(({ provider, calendarData }: { provider: ProviderInfo, calendarData: CalendarData }) => {
56
+ const providerName = provider.fullName || provider.authors[0];
57
+ const calendarKey = provider.authors[0]; // Use the same key as calendar generation
58
+ const totalCount = calendarData[calendarKey]?.reduce((sum, day) => sum + day.count, 0) || 0;
59
+
60
+ return (
61
+ <div id={`provider-${calendarKey}`} className="relative bg-gradient-to-br from-card to-card/95 rounded-2xl border border-border shadow-lg hover:shadow-xl transition-all duration-300 p-6 group">
62
+ {/* Organization Header */}
63
+ <OrganizationCard
64
+ provider={provider}
65
+ calendarKey={calendarKey}
66
+ providerName={providerName}
67
+ totalCount={totalCount}
68
+ />
69
+
70
+ {/* Heatmap Section */}
71
+ <div className="flex flex-col items-center bg-muted/30 rounded-xl p-3 group-hover:bg-muted/40 transition-colors duration-300">
72
+ <Heatmap
73
+ data={calendarData[calendarKey]}
74
+ color={provider.color}
75
+ providerName={providerName}
76
+ fullName={provider.fullName ?? providerName}
77
+ avatarUrl={provider.avatarUrl ?? ''}
78
+ authorId={calendarKey}
79
+ showHeader={false}
80
+ />
81
+ </div>
82
+ </div>
83
+ );
84
+ });
85
+
86
+ const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({
87
+ calendarData,
88
+ providers,
89
+ }) => {
90
+ const [isLoading, setIsLoading] = useState(true);
91
+
92
+ useEffect(() => {
93
+ if (calendarData && Object.keys(calendarData).length > 0) {
94
+ setIsLoading(false);
95
+ }
96
+ }, [calendarData]);
97
+
98
+ const sortedProviders = useMemo(() =>
99
+ providers.sort((a, b) => {
100
+ const calendarKeyA = a.authors[0];
101
+ const calendarKeyB = b.authors[0];
102
+ const countA = calendarData[calendarKeyA]?.reduce((sum, day) => sum + day.count, 0) || 0;
103
+ const countB = calendarData[calendarKeyB]?.reduce((sum, day) => sum + day.count, 0) || 0;
104
+ return countB - countA;
105
+ }),
106
+ [providers, calendarData]
107
+ );
108
+
109
+ return (
110
+ <div className="w-full p-4 py-16 relative">
111
+ <h1 className="text-3xl lg:text-5xl mt-16 font-bold text-center mb-2 text-foreground">
112
+ 🇰🇷 한국 AI 오픈소스 히트맵
113
+ <span className="block text-lg lg:text-xl mt-2 font-normal text-muted-foreground">
114
+ Korean AI Open Source Heatmap
115
+ </span>
116
+ </h1>
117
+ <div className="text-center text-sm my-8 space-y-4">
118
+ <p className="text-muted-foreground">
119
+ 지난 1년간 국내 주요 AI 연구소들이 공개한 모델, 데이터셋, 스페이스 통계
120
+ </p>
121
+ </div>
122
+
123
+ {/* Provider Summary List */}
124
+ <div className="mb-16 mx-auto">
125
+ <div className="overflow-x-auto scrollbar-hide">
126
+ <div className="flex gap-6 px-4 py-2 min-w-max justify-center">
127
+ {sortedProviders.map((provider, index) => (
128
+ <ProviderSummary
129
+ key={provider.fullName || provider.authors[0]}
130
+ provider={provider}
131
+ calendarData={calendarData}
132
+ rank={index + 1}
133
+ />
134
+ ))}
135
+ </div>
136
+ </div>
137
+ </div>
138
+
139
+ {isLoading ? (
140
+ <div className="flex items-center justify-center py-20">
141
+ <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500"></div>
142
+ <p className="ml-4 text-muted-foreground">Loading heatmaps...</p>
143
+ </div>
144
+ ) : (
145
+ <>
146
+ <div className="mb-16">
147
+ <div className="flex flex-col gap-8 max-w-4xl mx-auto">
148
+ {sortedProviders.slice(0, 3).map((provider) => (
149
+ <ProviderHeatmap
150
+ key={provider.fullName || provider.authors[0]}
151
+ provider={provider}
152
+ calendarData={calendarData}
153
+ />
154
+ ))}
155
+ </div>
156
+ </div>
157
+
158
+ {/* Rest of the providers */}
159
+ {sortedProviders.length > 3 && (
160
+ <div className="flex flex-col gap-8 max-w-4xl mx-auto">
161
+ {sortedProviders.slice(3).map((provider) => (
162
+ <ProviderHeatmap
163
+ key={provider.fullName || provider.authors[0]}
164
+ provider={provider}
165
+ calendarData={calendarData}
166
+ />
167
+ ))}
168
+ </div>
169
+ )}
170
+ </>
171
+ )}
172
+
173
+ {/* CTA Section */}
174
+ <div className="mt-24 mb-16 flex justify-center">
175
+ <div className="bg-gradient-to-br from-card to-card/95 rounded-2xl border border-border shadow-lg hover:shadow-xl transition-all duration-300 p-8 max-w-2xl w-full text-center space-y-6">
176
+ <div className="space-y-4">
177
+ <h2 className="text-2xl lg:text-3xl font-bold text-foreground">
178
+ Hugging Face 히트맵 만들기
179
+ </h2>
180
+ <p className="text-muted-foreground text-lg">
181
+ Hugging Face 조직이나 사용자를 검색해 오픈소스 활동을 확인하세요
182
+ </p>
183
+ </div>
184
+ <div className="flex justify-center">
185
+ <UserSearchDialog />
186
+ </div>
187
+ </div>
188
+ </div>
189
+
190
+ {/* Footer */}
191
+ <footer className="text-center py-8 text-sm text-muted-foreground">
192
+ <a
193
+ href="https://huggingface.co/spaces/zh-ai-community/model-release-heatmap-zh"
194
+ target="_blank"
195
+ rel="noopener noreferrer"
196
+ className="hover:text-foreground transition-colors"
197
+ >
198
+ Forked from <span className="underline">🤗 zh-ai-community/model-release-heatmap-zh</span>
199
+ </a>
200
+ </footer>
201
+ </div>
202
+ );
203
+ };
204
+
205
+ export default OpenSourceHeatmap;
src/styles/globals.css ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ :root {
7
+ --background: 0 0% 100%;
8
+ --foreground: 222.2 84% 4.9%;
9
+ --card: 0 0% 100%;
10
+ --card-foreground: 222.2 84% 4.9%;
11
+ --popover: 0 0% 100%;
12
+ --popover-foreground: 222.2 84% 4.9%;
13
+ --primary: 222.2 47.4% 11.2%;
14
+ --primary-foreground: 210 40% 98%;
15
+ --secondary: 210 40% 96.1%;
16
+ --secondary-foreground: 222.2 47.4% 11.2%;
17
+ --muted: 210 40% 96.1%;
18
+ --muted-foreground: 215.4 16.3% 46.9%;
19
+ --accent: 210 40% 96.1%;
20
+ --accent-foreground: 222.2 47.4% 11.2%;
21
+ --destructive: 0 84.2% 60.2%;
22
+ --destructive-foreground: 210 40% 98%;
23
+ --border: 214.3 31.8% 91.4%;
24
+ --input: 214.3 31.8% 91.4%;
25
+ --ring: 222.2 84% 4.9%;
26
+ --radius: 0.5rem;
27
+ --chart-1: 12 76% 61%;
28
+ --chart-2: 173 58% 39%;
29
+ --chart-3: 197 37% 24%;
30
+ --chart-4: 43 74% 66%;
31
+ --chart-5: 27 87% 67%;
32
+ --foreground-rgb: 75, 75, 75;
33
+ --background-rgb: 255, 255, 255;
34
+ }
35
+
36
+ @media (prefers-color-scheme: dark) {
37
+ :root {
38
+ --foreground-rgb: 255, 255, 255;
39
+ --background-rgb: 0, 0, 0;
40
+ --background: 222.2 84% 4.9%;
41
+ --foreground: 210 40% 98%;
42
+ --card: 222.2 84% 4.9%;
43
+ --card-foreground: 210 40% 98%;
44
+ --popover: 222.2 84% 4.9%;
45
+ --popover-foreground: 210 40% 98%;
46
+ --primary: 210 40% 98%;
47
+ --primary-foreground: 222.2 47.4% 11.2%;
48
+ --secondary: 217.2 32.6% 17.5%;
49
+ --secondary-foreground: 210 40% 98%;
50
+ --muted: 217.2 32.6% 17.5%;
51
+ --muted-foreground: 215 20.2% 65.1%;
52
+ --accent: 217.2 32.6% 17.5%;
53
+ --accent-foreground: 210 40% 98%;
54
+ --destructive: 0 62.8% 30.6%;
55
+ --destructive-foreground: 210 40% 98%;
56
+ --border: 217.2 32.6% 17.5%;
57
+ --input: 217.2 32.6% 17.5%;
58
+ --ring: 212.7 26.8% 83.9%;
59
+ --chart-1: 220 70% 50%;
60
+ --chart-2: 160 60% 45%;
61
+ --chart-3: 30 80% 55%;
62
+ --chart-4: 280 65% 60%;
63
+ --chart-5: 340 75% 55%;
64
+ }
65
+ }
66
+ }
67
+
68
+ @layer base {
69
+ * {
70
+ @apply border-border;
71
+ }
72
+ body {
73
+ color: rgb(var(--foreground-rgb));
74
+ background: rgb(var(--background-rgb));
75
+ @apply text-foreground;
76
+ }
77
+ }
78
+
79
+ @layer utilities {
80
+ .text-balance {
81
+ text-wrap: balance;
82
+ }
83
+
84
+ .scrollbar-hide {
85
+ -ms-overflow-style: none; /* Internet Explorer 10+ */
86
+ scrollbar-width: none; /* Firefox */
87
+ }
88
+
89
+ .scrollbar-hide::-webkit-scrollbar {
90
+ display: none; /* Safari and Chrome */
91
+ }
92
+ }
src/types/heatmap.ts ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface ProviderInfo {
2
+ color: string;
3
+ authors: string[];
4
+ fullName?: string;
5
+ avatarUrl?: string | null;
6
+ isVerified?: boolean;
7
+ isEnterprise?: boolean;
8
+ numModels?: number;
9
+ numSpaces?: number;
10
+ numDatasets?: number;
11
+ numFollowers?: number;
12
+ numUsers?: number;
13
+ totalDownloads?: number;
14
+ authorsData?: {
15
+ author: string;
16
+ fullName: string;
17
+ avatarUrl: string | null;
18
+ isVerified: boolean;
19
+ isEnterprise: boolean;
20
+ numModels: number;
21
+ numSpaces: number;
22
+ numDatasets: number;
23
+ numFollowers: number;
24
+ numUsers: number;
25
+ }[];
26
+ }
27
+
28
+ export interface ModelData {
29
+ createdAt: string;
30
+ id: string;
31
+ downloads?: number;
32
+ }
33
+
34
+ export interface Activity {
35
+ date: string;
36
+ count: number;
37
+ level: number;
38
+ }
39
+
40
+ export interface CalendarData {
41
+ [key: string]: Activity[];
42
+ }
43
+
44
+ export interface OpenSourceHeatmapProps {
45
+ calendarData: CalendarData;
46
+ author: string;
47
+ color: string;
48
+ providers: ProviderInfo[];
49
+ }
src/utils/authors.ts ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ProviderInfo, ModelData } from "../types/heatmap";
2
+
3
+ export async function fetchOrganizationData(authors: string[]) {
4
+ try {
5
+ // Fetch data for all authors
6
+ const authorsData = await Promise.all(
7
+ authors.map(async (author) => {
8
+ try {
9
+ // Try organizations API first
10
+ const orgResponse = await fetch(`https://huggingface.co/api/organizations/${author}/overview`);
11
+ if (orgResponse.ok) {
12
+ const data = await orgResponse.json();
13
+ return {
14
+ author,
15
+ fullName: data.fullname || author,
16
+ avatarUrl: data.avatarUrl || null,
17
+ isVerified: data.isVerified || false,
18
+ isEnterprise: data.isEnterprise || false,
19
+ numModels: data.numModels || 0,
20
+ numSpaces: data.numSpaces || 0,
21
+ numDatasets: data.numDatasets || 0,
22
+ numFollowers: data.numFollowers || 0,
23
+ numUsers: data.numUsers || 0,
24
+ };
25
+ }
26
+
27
+ // Fallback to users API if organization doesn't exist
28
+ const userResponse = await fetch(`https://huggingface.co/api/users/${author}/overview`);
29
+ if (userResponse.ok) {
30
+ const data = await userResponse.json();
31
+ return {
32
+ author,
33
+ fullName: data.fullname || author,
34
+ avatarUrl: data.avatarUrl || null,
35
+ isVerified: false,
36
+ isEnterprise: false,
37
+ numModels: data.numModels || 0,
38
+ numSpaces: data.numSpaces || 0,
39
+ numDatasets: data.numDatasets || 0,
40
+ numFollowers: data.numFollowers || 0,
41
+ numUsers: 0,
42
+ };
43
+ }
44
+
45
+ throw new Error('Neither organization nor user API returned valid data');
46
+ } catch (error) {
47
+ console.error(`Error fetching data for ${author}:`, error);
48
+ return {
49
+ author,
50
+ fullName: author,
51
+ avatarUrl: null,
52
+ isVerified: false,
53
+ isEnterprise: false,
54
+ numModels: 0,
55
+ numSpaces: 0,
56
+ numDatasets: 0,
57
+ numFollowers: 0,
58
+ numUsers: 0,
59
+ };
60
+ }
61
+ })
62
+ );
63
+
64
+ // Use the primary author for main display name and avatar
65
+ const primaryAuthor = authorsData[0];
66
+
67
+ // Aggregate stats from all authors
68
+ const aggregatedStats = authorsData.reduce(
69
+ (acc, authorData) => ({
70
+ numModels: acc.numModels + (authorData.numModels || 0),
71
+ numSpaces: acc.numSpaces + (authorData.numSpaces || 0),
72
+ numDatasets: acc.numDatasets + (authorData.numDatasets || 0),
73
+ numFollowers: acc.numFollowers + (authorData.numFollowers || 0),
74
+ numUsers: acc.numUsers + (authorData.numUsers || 0),
75
+ }),
76
+ { numModels: 0, numSpaces: 0, numDatasets: 0, numFollowers: 0, numUsers: 0 }
77
+ );
78
+
79
+ return {
80
+ fullName: primaryAuthor.fullName,
81
+ avatarUrl: primaryAuthor.avatarUrl,
82
+ isVerified: primaryAuthor.isVerified,
83
+ isEnterprise: primaryAuthor.isEnterprise,
84
+ authorsData, // Include all authors data for multi-logo display
85
+ ...aggregatedStats,
86
+ };
87
+ } catch (error) {
88
+ console.error(`Error fetching organization data for authors:`, error);
89
+ const primaryAuthor = authors[0];
90
+ return {
91
+ fullName: primaryAuthor,
92
+ avatarUrl: null,
93
+ isVerified: false,
94
+ isEnterprise: false,
95
+ authorsData: [{
96
+ author: primaryAuthor,
97
+ fullName: primaryAuthor,
98
+ avatarUrl: null,
99
+ isVerified: false,
100
+ isEnterprise: false,
101
+ numModels: 0,
102
+ numSpaces: 0,
103
+ numDatasets: 0,
104
+ numFollowers: 0,
105
+ numUsers: 0,
106
+ }],
107
+ numModels: 0,
108
+ numSpaces: 0,
109
+ numDatasets: 0,
110
+ numFollowers: 0,
111
+ numUsers: 0,
112
+ };
113
+ }
114
+ }
115
+
116
+ export async function fetchAllProvidersData(providers: ProviderInfo[], modelDataMap?: Map<string, ModelData[]>): Promise<ProviderInfo[]> {
117
+ return Promise.all(providers.map(async (providerInfo) => {
118
+ const orgData = await fetchOrganizationData(providerInfo.authors);
119
+
120
+ // Calculate total downloads from model data
121
+ let totalDownloads = 0;
122
+ if (modelDataMap) {
123
+ for (const author of providerInfo.authors) {
124
+ const authorModels = modelDataMap.get(author) || [];
125
+ totalDownloads += authorModels.reduce((sum, model) => sum + (model.downloads || 0), 0);
126
+ }
127
+ }
128
+
129
+ return {
130
+ ...providerInfo,
131
+ ...orgData,
132
+ totalDownloads,
133
+ };
134
+ }));
135
+ }
136
+
137
+ export async function fetchAuthorData(author: string): Promise<ModelData[]> {
138
+ const entityTypes = ["models", "datasets", "spaces"] as const;
139
+ try {
140
+ const allData = await Promise.all(
141
+ entityTypes.map(async (type) => {
142
+ const response = await fetch(
143
+ `https://huggingface.co/api/${type}?author=${author}&sort=createdAt&direction=-1`
144
+ );
145
+ if (!response.ok) {
146
+ throw new Error(`HTTP error! status: ${response.status}`);
147
+ }
148
+ const data = await response.json();
149
+ return data.map((item: any): ModelData => ({
150
+ createdAt: item.createdAt,
151
+ id: item.id,
152
+ downloads: item.downloads || 0,
153
+ }));
154
+ })
155
+ );
156
+
157
+ return allData.flat();
158
+ } catch (error) {
159
+ console.error(`Error fetching data for author ${author}:`, error);
160
+ return [];
161
+ }
162
+ }
163
+
164
+ export async function fetchAllAuthorsData(authors: string[]): Promise<{ flatData: ModelData[], dataMap: Map<string, ModelData[]> }> {
165
+ try {
166
+ const allData = await Promise.all(
167
+ authors.map(async (author) => ({ author, data: await fetchAuthorData(author) }))
168
+ );
169
+ const flatData = allData.flatMap(item => item.data);
170
+ const dataMap = new Map(allData.map(item => [item.author, item.data]));
171
+ return { flatData, dataMap };
172
+ } catch (error) {
173
+ console.error("Error fetching data for all authors:", error);
174
+ return { flatData: [], dataMap: new Map() };
175
+ }
176
+ }
src/utils/calendar.ts ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ ModelData,
3
+ ProviderInfo,
4
+ CalendarData,
5
+ Activity,
6
+ } from "../types/heatmap";
7
+
8
+ export const generateCalendarData = (
9
+ modelData: ModelData[],
10
+ providers: ProviderInfo[]
11
+ ): CalendarData => {
12
+ const data: Record<string, Activity[]> = Object.fromEntries(
13
+ providers.map((provider) => [provider.authors[0], []]),
14
+ );
15
+
16
+ const today = new Date();
17
+ const startDate = new Date(today);
18
+ startDate.setMonth(today.getMonth() - 11);
19
+ startDate.setDate(1);
20
+
21
+ // create a map to store counts for each provider and date
22
+ const countMap: Record<string, Record<string, number>> = {};
23
+
24
+ modelData.forEach((item) => {
25
+ const dateString = item.createdAt.split("T")[0];
26
+ providers.forEach(({ authors }) => {
27
+ if (authors.some((author) => item.id.startsWith(author))) {
28
+ countMap[authors[0]] = countMap[authors[0]] || {};
29
+ countMap[authors[0]][dateString] =
30
+ (countMap[authors[0]][dateString] || 0) + 1;
31
+ }
32
+ });
33
+ });
34
+
35
+ // fill in with 0s for days with no activity
36
+ for (let d = new Date(startDate); d <= today; d.setDate(d.getDate() + 1)) {
37
+ const dateString = d.toISOString().split("T")[0];
38
+
39
+ providers.forEach(({ authors }) => {
40
+ const count = countMap[authors[0]]?.[dateString] || 0;
41
+ data[authors[0]].push({ date: dateString, count, level: 0 });
42
+ });
43
+ }
44
+
45
+ // calculate average counts for each provider
46
+ const avgCounts = Object.fromEntries(
47
+ Object.entries(data).map(([provider, days]) => [
48
+ provider,
49
+ days.reduce((sum, day) => sum + day.count, 0) / days.length || 0,
50
+ ]),
51
+ );
52
+
53
+ // assign levels based on count relative to average
54
+ Object.entries(data).forEach(([provider, days]) => {
55
+ const avgCount = avgCounts[provider];
56
+ days.forEach((day) => {
57
+ day.level =
58
+ day.count === 0
59
+ ? 0
60
+ : day.count <= avgCount * 0.5
61
+ ? 1
62
+ : day.count <= avgCount
63
+ ? 2
64
+ : day.count <= avgCount * 1.5
65
+ ? 3
66
+ : 4;
67
+ });
68
+ });
69
+
70
+ return data;
71
+ };
src/utils/ranking.ts ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface RankingBadge {
2
+ className: string;
3
+ icon: string | null;
4
+ }
5
+
6
+ export const getRankingBadge = (rank: number): RankingBadge => {
7
+ if (rank === 1) {
8
+ return {
9
+ className: "absolute -top-4 -left-4 w-12 h-12 bg-gradient-to-br from-yellow-400 via-yellow-500 to-yellow-600 text-white rounded-full flex items-center justify-center text-lg font-bold shadow-2xl border-4 border-yellow-300",
10
+ icon: "👑"
11
+ };
12
+ } else if (rank === 2) {
13
+ return {
14
+ className: "absolute -top-4 -left-4 w-10 h-10 bg-gradient-to-br from-gray-300 via-gray-400 to-gray-500 text-white rounded-full flex items-center justify-center text-base font-bold shadow-xl border-3 border-gray-200",
15
+ icon: "🥈"
16
+ };
17
+ } else if (rank === 3) {
18
+ return {
19
+ className: "absolute -top-4 -left-4 w-10 h-10 bg-gradient-to-br from-amber-600 via-amber-700 to-amber-800 text-white rounded-full flex items-center justify-center text-base font-bold shadow-xl border-3 border-amber-400",
20
+ icon: "🥉"
21
+ };
22
+ } else {
23
+ return {
24
+ className: "absolute -top-3 -left-3 w-8 h-8 bg-gradient-to-br from-blue-500 to-blue-600 text-white rounded-full flex items-center justify-center text-sm font-bold shadow-lg",
25
+ icon: null
26
+ };
27
+ }
28
+ };
tailwind.config.ts ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { Config } from "tailwindcss"
2
+
3
+ const config = {
4
+ darkMode: ["class"],
5
+ content: [
6
+ './pages/**/*.{ts,tsx}',
7
+ './components/**/*.{ts,tsx}',
8
+ './app/**/*.{ts,tsx}',
9
+ './src/**/*.{ts,tsx}',
10
+ ],
11
+ prefix: "",
12
+ theme: {
13
+ container: {
14
+ center: true,
15
+ padding: "2rem",
16
+ screens: {
17
+ "2xl": "1400px",
18
+ },
19
+ },
20
+ extend: {
21
+ colors: {
22
+ border: "hsl(var(--border))",
23
+ input: "hsl(var(--input))",
24
+ ring: "hsl(var(--ring))",
25
+ background: "hsl(var(--background))",
26
+ foreground: "hsl(var(--foreground))",
27
+ primary: {
28
+ DEFAULT: "hsl(var(--primary))",
29
+ foreground: "hsl(var(--primary-foreground))",
30
+ },
31
+ secondary: {
32
+ DEFAULT: "hsl(var(--secondary))",
33
+ foreground: "hsl(var(--secondary-foreground))",
34
+ },
35
+ destructive: {
36
+ DEFAULT: "hsl(var(--destructive))",
37
+ foreground: "hsl(var(--destructive-foreground))",
38
+ },
39
+ muted: {
40
+ DEFAULT: "hsl(var(--muted))",
41
+ foreground: "hsl(var(--muted-foreground))",
42
+ },
43
+ accent: {
44
+ DEFAULT: "hsl(var(--accent))",
45
+ foreground: "hsl(var(--accent-foreground))",
46
+ },
47
+ popover: {
48
+ DEFAULT: "hsl(var(--popover))",
49
+ foreground: "hsl(var(--popover-foreground))",
50
+ },
51
+ card: {
52
+ DEFAULT: "hsl(var(--card))",
53
+ foreground: "hsl(var(--card-foreground))",
54
+ },
55
+ },
56
+ borderRadius: {
57
+ lg: "var(--radius)",
58
+ md: "calc(var(--radius) - 2px)",
59
+ sm: "calc(var(--radius) - 4px)",
60
+ },
61
+ keyframes: {
62
+ "accordion-down": {
63
+ from: { height: "0" },
64
+ to: { height: "var(--radix-accordion-content-height)" },
65
+ },
66
+ "accordion-up": {
67
+ from: { height: "var(--radix-accordion-content-height)" },
68
+ to: { height: "0" },
69
+ },
70
+ },
71
+ animation: {
72
+ "accordion-down": "accordion-down 0.2s ease-out",
73
+ "accordion-up": "accordion-up 0.2s ease-out",
74
+ },
75
+ },
76
+ },
77
+ plugins: [require("tailwindcss-animate")],
78
+ } satisfies Config
79
+
80
+ export default config
tsconfig.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "lib": [
4
+ "dom",
5
+ "dom.iterable",
6
+ "esnext"
7
+ ],
8
+ "allowJs": true,
9
+ "skipLibCheck": true,
10
+ "strict": true,
11
+ "noEmit": true,
12
+ "esModuleInterop": true,
13
+ "module": "esnext",
14
+ "moduleResolution": "bundler",
15
+ "resolveJsonModule": true,
16
+ "isolatedModules": true,
17
+ "jsx": "react-jsx",
18
+ "incremental": true,
19
+ "paths": {
20
+ "@/*": [
21
+ "./src/*"
22
+ ]
23
+ },
24
+ "target": "ES2017"
25
+ },
26
+ "include": [
27
+ "next-env.d.ts",
28
+ "**/*.ts",
29
+ "**/*.tsx"
30
+ ],
31
+ "exclude": [
32
+ "node_modules"
33
+ ]
34
+ }