From 0ead24711a2ffea42509f7e297f3fe395a06d392 Mon Sep 17 00:00:00 2001 From: joaodunas Date: Sun, 21 Dec 2025 13:00:30 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Full=20overhaul=20of=20the=20app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 33 - DEPLOYMENT.md | 357 -- INITIAL IDEA.rtf | 2175 -------- LICENSE.txt | 202 + PROJECT_SUMMARY.md | 186 - QUICKSTART.md | 112 - README.md | 416 +- SECURITY_AUDIT.md | 207 - api/config.js | 102 - api/database.js | 274 - api/serverless.js | 83 - components.json | 22 + convex/README.md | 90 + convex/_generated/api.d.ts | 61 + convex/_generated/api.js | 23 + convex/_generated/dataModel.d.ts | 60 + convex/_generated/server.d.ts | 143 + convex/_generated/server.js | 93 + convex/auth.config.ts | 10 + convex/auth.ts | 22 + convex/github.ts | 120 + convex/http.ts | 8 + convex/leaderboard.ts | 99 + convex/leaks.ts | 940 ++++ convex/requests.ts | 417 ++ convex/schema.ts | 77 + convex/tsconfig.json | 25 + convex/users.ts | 181 + demo-data.js | 366 -- deploy.sh | 194 - eslint.config.js | 80 + index-simple.html | 430 -- index.html | 570 +- netlify.toml | 29 - package-lock.json | 8029 +++++++++++++++++++++++++-- package.json | 81 +- script.js | 2066 ------- security-headers.js | 71 - setup.mjs | 35 + src/App.tsx | 147 + src/components/leakLibrary.tsx | 488 ++ src/components/navbar.tsx | 91 + src/components/submitLeakForm.tsx | 437 ++ src/components/ui/avatar.tsx | 51 + src/components/ui/button.tsx | 60 + src/components/ui/checkbox.tsx | 30 + src/components/ui/dialog.tsx | 117 + src/components/ui/dropdown-menu.tsx | 255 + src/index.css | 138 + src/lib/utils.ts | 6 + src/main.tsx | 21 + src/pages/Browse.tsx | 217 + src/pages/Dashboard.tsx | 436 ++ src/pages/Leaderboard.tsx | 206 + src/pages/ProviderLeaks.tsx | 449 ++ src/pages/Requests.tsx | 405 ++ src/vite-env.d.ts | 1 + styles.css | 2196 -------- tsconfig.app.json | 31 + tsconfig.json | 13 + tsconfig.node.json | 24 + vercel.json | 75 - vite.config.js | 23 - vite.config.ts | 14 + wrangler.jsonc | 5 + 65 files changed, 14178 insertions(+), 10247 deletions(-) delete mode 100644 .github/workflows/deploy.yml delete mode 100644 DEPLOYMENT.md delete mode 100644 INITIAL IDEA.rtf create mode 100644 LICENSE.txt delete mode 100644 PROJECT_SUMMARY.md delete mode 100644 QUICKSTART.md delete mode 100644 SECURITY_AUDIT.md delete mode 100644 api/config.js delete mode 100644 api/database.js delete mode 100644 api/serverless.js create mode 100644 components.json create mode 100644 convex/README.md create mode 100644 convex/_generated/api.d.ts create mode 100644 convex/_generated/api.js create mode 100644 convex/_generated/dataModel.d.ts create mode 100644 convex/_generated/server.d.ts create mode 100644 convex/_generated/server.js create mode 100644 convex/auth.config.ts create mode 100644 convex/auth.ts create mode 100644 convex/github.ts create mode 100644 convex/http.ts create mode 100644 convex/leaderboard.ts create mode 100644 convex/leaks.ts create mode 100644 convex/requests.ts create mode 100644 convex/schema.ts create mode 100644 convex/tsconfig.json create mode 100644 convex/users.ts delete mode 100644 demo-data.js delete mode 100755 deploy.sh create mode 100644 eslint.config.js delete mode 100644 index-simple.html delete mode 100644 netlify.toml delete mode 100644 script.js delete mode 100644 security-headers.js create mode 100644 setup.mjs create mode 100644 src/App.tsx create mode 100644 src/components/leakLibrary.tsx create mode 100644 src/components/navbar.tsx create mode 100644 src/components/submitLeakForm.tsx create mode 100644 src/components/ui/avatar.tsx create mode 100644 src/components/ui/button.tsx create mode 100644 src/components/ui/checkbox.tsx create mode 100644 src/components/ui/dialog.tsx create mode 100644 src/components/ui/dropdown-menu.tsx create mode 100644 src/index.css create mode 100644 src/lib/utils.ts create mode 100644 src/main.tsx create mode 100644 src/pages/Browse.tsx create mode 100644 src/pages/Dashboard.tsx create mode 100644 src/pages/Leaderboard.tsx create mode 100644 src/pages/ProviderLeaks.tsx create mode 100644 src/pages/Requests.tsx create mode 100644 src/vite-env.d.ts delete mode 100644 styles.css create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json delete mode 100644 vercel.json delete mode 100644 vite.config.js create mode 100644 vite.config.ts create mode 100644 wrangler.jsonc diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 4c480b2..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Deploy to GitHub Pages - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: '18' - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Build project - run: npm run build - - - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - if: github.ref == 'refs/heads/main' - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./dist diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md deleted file mode 100644 index 327d8c7..0000000 --- a/DEPLOYMENT.md +++ /dev/null @@ -1,357 +0,0 @@ -# 🚀 LeakHub Deployment Guide - -## 🌟 Deployment Options - -LeakHub can be deployed in multiple ways, from simple static hosting to full backend integration. - -## 📦 Option 1: GitHub Pages (Recommended) - -### Quick Setup -1. **Push to GitHub**: Push your code to the `main` branch -2. **Enable GitHub Pages**: - - Go to Settings → Pages - - Source: "GitHub Actions" - - The workflow will automatically deploy on push - -### Manual Setup -```bash -# Install dependencies -npm install - -# Build for production -npm run build - -# The dist/ folder is ready for deployment -``` - -### GitHub Actions Workflow -The `.github/workflows/deploy.yml` file automatically: -- Builds the project with Vite -- Deploys to GitHub Pages -- Handles CORS and routing - -## 🔧 Option 2: Vercel (Full Stack) - -### Deploy with Backend -1. **Connect to Vercel**: - ```bash - npm i -g vercel - vercel login - vercel - ``` - -2. **Environment Variables** (optional): - ```bash - vercel env add DATABASE_URL - vercel env add API_KEY - ``` - -3. **Deploy**: - ```bash - vercel --prod - ``` - -### Features -- ✅ Serverless API endpoints -- ✅ Automatic HTTPS -- ✅ Global CDN -- ✅ Custom domains -- ✅ Environment variables - -## 🌐 Option 3: Netlify - -### Deploy with Functions -1. **Connect to Netlify**: - ```bash - npm install -g netlify-cli - netlify login - netlify init - ``` - -2. **Deploy**: - ```bash - netlify deploy --prod - ``` - -### Features -- ✅ Serverless functions -- ✅ Form handling -- ✅ A/B testing -- ✅ Custom domains - -## 🗄️ Option 4: Full Backend Integration - -### Database Options - -#### MongoDB Atlas -```javascript -// In api/database.js -const { MongoClient } = require('mongodb'); - -const client = new MongoClient(process.env.MONGODB_URI); -await client.connect(); -const db = client.db('leakhub'); -``` - -#### Supabase (PostgreSQL) -```javascript -// In api/database.js -import { createClient } from '@supabase/supabase-js'; - -const supabase = createClient( - process.env.SUPABASE_URL, - process.env.SUPABASE_ANON_KEY -); -``` - -#### Firebase -```javascript -// In api/database.js -import { initializeApp } from 'firebase/app'; -import { getFirestore } from 'firebase/firestore'; - -const app = initializeApp(firebaseConfig); -const db = getFirestore(app); -``` - -## 🔐 Environment Variables - -### Required for Backend -```bash -# Database -DATABASE_URL=mongodb://localhost:27017/leakhub -# or -SUPABASE_URL=https://your-project.supabase.co -SUPABASE_ANON_KEY=your-anon-key - -# API Keys -API_KEY=your-secret-api-key -JWT_SECRET=your-jwt-secret - -# CORS -ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com -``` - -### Optional -```bash -# Analytics -GOOGLE_ANALYTICS_ID=GA_MEASUREMENT_ID -MIXPANEL_TOKEN=your-mixpanel-token - -# Email (for notifications) -SMTP_HOST=smtp.gmail.com -SMTP_PORT=587 -SMTP_USER=your-email@gmail.com -SMTP_PASS=your-app-password -``` - -## 🚀 Production Checklist - -### Frontend -- [ ] Minify CSS and JavaScript -- [ ] Optimize images -- [ ] Enable gzip compression -- [ ] Set up CDN -- [ ] Configure caching headers -- [ ] Add security headers - -### Backend -- [ ] Set up database -- [ ] Configure CORS -- [ ] Add rate limiting -- [ ] Set up logging -- [ ] Configure monitoring -- [ ] Set up backups - -### Security -- [ ] HTTPS enabled -- [ ] Security headers -- [ ] Input validation -- [ ] SQL injection protection -- [ ] XSS protection -- [ ] CSRF protection - -## 📊 Monitoring & Analytics - -### Google Analytics -```html - - - -``` - -### Error Tracking -```javascript -// Add to script.js -window.addEventListener('error', function(e) { - // Send to your error tracking service - console.error('LeakHub Error:', e.error); -}); -``` - -## 🔄 CI/CD Pipeline - -### GitHub Actions (Full Pipeline) -```yaml -name: Full CI/CD Pipeline - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main ] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: '18' - - run: npm ci - - run: npm run lint - - run: npm run test - - build: - needs: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: '18' - - run: npm ci - - run: npm run build - - uses: actions/upload-artifact@v3 - with: - name: build-files - path: dist/ - - deploy: - needs: build - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/main' - steps: - - uses: actions/download-artifact@v3 - with: - name: build-files - - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./dist -``` - -## 🎯 Custom Domains - -### GitHub Pages -1. Go to Settings → Pages -2. Add custom domain -3. Update DNS records -4. Enable HTTPS - -### Vercel -```bash -vercel domains add yourdomain.com -``` - -### Netlify -1. Go to Site settings → Domain management -2. Add custom domain -3. Update DNS records - -## 🔧 Development vs Production - -### Development -```bash -npm run dev # Start development server -npm run preview # Preview production build -npm run lint # Check code quality -npm run format # Format code -``` - -### Production -```bash -npm run build # Build for production -npm run serve # Serve production build locally -``` - -## 📈 Performance Optimization - -### Frontend -- [ ] Code splitting -- [ ] Lazy loading -- [ ] Image optimization -- [ ] Bundle analysis -- [ ] Critical CSS - -### Backend -- [ ] Database indexing -- [ ] Query optimization -- [ ] Caching strategy -- [ ] Load balancing -- [ ] CDN integration - -## 🛠️ Troubleshooting - -### Common Issues - -#### Build Failures -```bash -# Clear cache -rm -rf node_modules package-lock.json -npm install - -# Check Node version -node --version # Should be 16+ for Vite -``` - -#### CORS Issues -```javascript -// Ensure CORS headers are set -const corsHeaders = { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization' -}; -``` - -#### Database Connection -```javascript -// Add retry logic -async function connectWithRetry() { - for (let i = 0; i < 5; i++) { - try { - await connect(); - break; - } catch (error) { - console.log(`Connection attempt ${i + 1} failed`); - await new Promise(resolve => setTimeout(resolve, 1000)); - } - } -} -``` - -## 🎉 Deployment Complete! - -Once deployed, your LeakHub instance will be available at: -- **GitHub Pages**: `https://elder-plinius.github.io/LEAKHUB` -- **Vercel**: `https://your-project.vercel.app` -- **Netlify**: `https://your-project.netlify.app` - -### Next Steps -1. Test all functionality -2. Set up monitoring -3. Configure backups -4. Add custom domain -5. Set up SSL certificate -6. Configure analytics - ---- - -**Happy deploying! 🚀** diff --git a/INITIAL IDEA.rtf b/INITIAL IDEA.rtf deleted file mode 100644 index 7c0b7d0..0000000 --- a/INITIAL IDEA.rtf +++ /dev/null @@ -1,2175 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2822 -\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -{\*\expandedcolortbl;;} -\margl1440\margr1440\vieww11520\viewh8400\viewkind0 -\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 - -\f0\fs24 \cf0 \ -\ -\ - \ - \ - LeakHub - AI System Prompt Discovery Platform\ - \ -\ -\ -
\ - \ -
\ -
\ -

LeakHub

\ -

The community hub for crowd-sourced system prompt leak verification. CL4R1T4S!

\ -
\ -
\ - Active Targets:\ - 0\ -
\ -
\ - Total Submissions:\ - 0\ -
\ -
\ - Verified Prompts:\ - 0\ -
\ -
\ -
\ - \ - \ -
\ -
\ -\ -
\ -
\ -

\uc0\u55357 \u56548 Submit Leak

\ -
\ - \ - \ - \ - \ - \ - \ - \ - \ -
\ -

\uc0\u55357 \u56592 Access Requirements

\ -
\ - \ - \ -
\ - \ -
\ - \ - \ - \ - \ - \ - \ -
\ - \ - \ -
\ - \ - \ - \ - \ -
\ -
\ -\ -
\ -

\uc0\u55357 \u56538 Leak Library

\ -
\ -

No submissions yet. Be the first to contribute!

\ -
\ -
\ -
\ -\ -
\ -

\uc0\u55357 \u56589 Compare Multiple Instances

\ - \ -
\ -
\ - \ - \ -
\ -
\ - \ - \ -
\ - \ -
\ -\ - \ -
\ -\ -
\ -
\ -
0
\ -
Unique Instances
\ -
\ -
\ -
0%
\ -
Average Similarity
\ -
\ -
\ -
0
\ -
High Confidence Matches
\ -
\ -
\ -
\ -\ -
\ -\ - \ -
\ -
\ -
\uc0\u10005
\ - \ -
\ -

\uc0\u55356 \u57286 LeakHub Hall of Fame

\ -

Recognizing the top contributors to AI transparency

\ -
\ -\ -
\ -
\uc0\u55357 \u56522 Rankings
\ -
\uc0\u55356 \u57238 \u65039 Achievements
\ -
\uc0\u55357 \u56517 Timeline
\ -
\ -\ -
\ -
\ -

Top Contributors

\ -
\ -
\ -
\ -\ - \ -\ - \ -
\ -
\ -\ - \ -
\ -
\ -
\uc0\u10005
\ - \ -
\ -

\uc0\u55356 \u57263 LeakHub Bounty Board

\ -

Request targets and compete in daily challenges

\ -
\ -\ - \ -
\ -

\uc0\u55356 \u57285 Today's Challenge

\ -

Find and verify a system prompt from GPT-4 Turbo!

\ -
\uc0\u55356 \u57217 Reward: 500 bonus points + Special Badge
\ -
Time remaining: 23:45:30
\ -
\ -\ -
\ - \ -
\ -

\uc0\u55357 \u56541 Request a Leak Hunt

\ -
\ - \ - \ - \ - \ -
\ - \ - \ -
\ - \ - \ -
\ -
\ -\ - \ -
\ -

\uc0\u55357 \u56613 Hot Requests

\ -
\ -
\uc0\u55357 \u56613 Trending
\ -
\uc0\u55357 \u56496 Highest Bounty
\ -
\uc0\u55356 \u56725 Newest
\ -
\uc0\u55357 \u56473 My Votes
\ -
\ -
\ -

No requests yet. Be the first to request a leak hunt!

\ -
\ -
\ -
\ -
\ -
\ -\ - \ -\ -} \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..b615b0f --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 Convex, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md deleted file mode 100644 index 2db1eb4..0000000 --- a/PROJECT_SUMMARY.md +++ /dev/null @@ -1,186 +0,0 @@ -# 🎉 LeakHub - Project Summary - -## 🚀 What We Built - -**LeakHub** is a revolutionary AI system prompt discovery platform that enables community-driven verification and analysis of AI system prompts. It's designed to promote transparency in AI systems through crowdsourced verification. - -## ✨ Key Features Implemented - -### 🔍 **Core Functionality** -- ✅ **Submit Leaks**: Comprehensive submission system with metadata tracking -- ✅ **Compare & Verify**: Advanced similarity algorithms for verification -- ✅ **Community Library**: Browse and search through all submissions -- ✅ **Confidence Scoring**: Automatic assessment based on content analysis - -### 🎯 **Target Types Supported** -- ✅ **AI Models** (GPT-4, Claude, Gemini, etc.) -- ✅ **Apps/Interfaces** (Cursor, GitHub Copilot, etc.) -- ✅ **Tools/Functions** (Code Interpreter, WebPilot, etc.) -- ✅ **AI Agents** (AutoGPT, BabyAGI, etc.) -- ✅ **Plugins/Extensions** (Browser extensions, IDE plugins, etc.) -- ✅ **Custom GPTs/Bots** (Custom implementations) - -### 🏆 **Gamification & Community** -- ✅ **Leaderboard**: Track top contributors and achievements -- ✅ **Daily Challenges**: Compete in daily leak hunting challenges -- ✅ **Achievement System**: Unlock badges for notable contributions -- ✅ **Points System**: Earn points for submissions, verifications, and discoveries - -### 🎯 **Requests & Bounties** -- ✅ **Community Requests**: Request specific targets for leak hunting -- ✅ **Voting System**: Vote on which targets to prioritize -- ✅ **Bounty System**: Offer points for high-priority discoveries -- ✅ **Trending Requests**: See what the community wants most - -### 📊 **Advanced Analytics** -- ✅ **Similarity Metrics**: Character match, word match, structure match, core similarity -- ✅ **Consensus View**: Identify common elements across multiple submissions -- ✅ **Verification Tracking**: Track verification status and confidence levels -- ✅ **Statistics Dashboard**: Real-time platform statistics - -## 🛠️ Technical Architecture - -### **Frontend Stack** -- **HTML5**: Semantic markup and modern structure -- **CSS3**: Cyberpunk aesthetic with animations and responsive design -- **JavaScript (ES6+)**: Full application logic and data management -- **Vite**: Fast build tool and development server - -### **Backend & Deployment** -- **GitHub Actions**: Automated CI/CD pipeline -- **Vercel/Netlify**: Serverless deployment with functions -- **Database Abstraction**: Support for localStorage, MongoDB, Supabase, Firebase -- **API Layer**: RESTful endpoints with CORS support - -### **Key Algorithms** -- **Text Normalization**: Standardized text processing for comparison -- **Similarity Metrics**: Multiple algorithms for comprehensive analysis -- **Levenshtein Distance**: String similarity calculation -- **Phrase Matching**: Sliding window approach for common phrase detection - -### **Data Management** -- **Hybrid Storage**: localStorage with optional backend persistence -- **JSON Serialization**: Efficient data storage and retrieval -- **Real-time Updates**: Instant UI updates and statistics -- **Data Validation**: Input validation and error handling -- **Export/Import**: Full data backup and restore functionality - -## 🎨 Design Features - -### **Modern UI/UX** -- **Cyberpunk Aesthetic**: Dark theme with neon accents and gradients -- **Responsive Design**: Works perfectly on desktop, tablet, and mobile -- **Smooth Animations**: Floating grid background and interactive elements -- **Intuitive Navigation**: Clear sections and easy-to-use interface - -### **Visual Elements** -- **Status Indicators**: Real-time statistics and progress tracking -- **Badge System**: Visual indicators for access requirements and features -- **Color Coding**: Different colors for different target types and confidence levels -- **Interactive Elements**: Hover effects, transitions, and feedback - -## 🚀 Deployment Ready - -### **Multiple Deployment Options** -1. **GitHub Pages** (Recommended): Automatic deployment via GitHub Actions -2. **Vercel**: Full-stack deployment with serverless functions -3. **Netlify**: Static hosting with serverless functions -4. **Custom Backend**: MongoDB, Supabase, or Firebase integration - -### **Production Features** -- ✅ **Build System**: Vite-based production builds -- ✅ **CI/CD Pipeline**: Automated testing and deployment -- ✅ **CORS Support**: Cross-origin resource sharing -- ✅ **Error Handling**: Comprehensive error management -- ✅ **Performance Optimization**: Minified and optimized assets -- ✅ **Security Headers**: Basic security configuration - -## 📁 Project Structure - -``` -LEAKHUB/ -├── index.html # Main application -├── styles.css # All styling and animations -├── script.js # Main application logic -├── demo-data.js # Sample data for testing -├── api/ -│ ├── database.js # Database abstraction layer -│ ├── serverless.js # Serverless API endpoints -│ └── config.js # Backend configuration -├── .github/ -│ └── workflows/ -│ └── deploy.yml # GitHub Actions deployment -├── package.json # Project dependencies and scripts -├── vite.config.js # Vite build configuration -├── vercel.json # Vercel deployment config -├── netlify.toml # Netlify deployment config -├── deploy.sh # Automated deployment script -├── README.md # Comprehensive documentation -├── QUICKSTART.md # Quick start guide -├── DEPLOYMENT.md # Detailed deployment guide -└── PROJECT_SUMMARY.md # This file -``` - -## 🎯 Ready for Production - -### **What's Included** -- ✅ **Complete Application**: Fully functional frontend and backend -- ✅ **Documentation**: Comprehensive guides and documentation -- ✅ **Deployment Scripts**: Automated deployment to multiple platforms -- ✅ **Demo Data**: Sample submissions for testing -- ✅ **Error Handling**: Robust error management -- ✅ **Performance**: Optimized for production use - -### **Next Steps** -1. **Deploy**: Use the deployment script or GitHub Actions -2. **Customize**: Modify styling, features, or backend -3. **Scale**: Add database integration for production use -4. **Monitor**: Set up analytics and error tracking -5. **Community**: Start building the user community - -## 🎉 Success Metrics - -### **Technical Achievements** -- ✅ **100% Client-Side**: Works without backend (localStorage) -- ✅ **Backend Ready**: Easy integration with any database -- ✅ **Mobile Responsive**: Perfect on all devices -- ✅ **Performance Optimized**: Fast loading and smooth interactions -- ✅ **Accessibility**: Keyboard navigation and screen reader support - -### **Feature Completeness** -- ✅ **All Core Features**: Submission, comparison, verification -- ✅ **Gamification**: Points, leaderboard, achievements -- ✅ **Community**: Requests, voting, challenges -- ✅ **Analytics**: Statistics, metrics, tracking -- ✅ **Export/Import**: Data backup and restore - -## 🔮 Future Potential - -### **Immediate Enhancements** -- **Database Integration**: MongoDB, Supabase, or Firebase -- **User Authentication**: Secure user accounts -- **Real-time Updates**: WebSocket support -- **Advanced Analytics**: Machine learning similarity detection -- **Mobile App**: Native mobile application - -### **Community Features** -- **Discussion Forums**: Community discussions and analysis -- **Expert Verification**: Expert review system -- **Advanced Bounties**: Complex reward systems -- **Social Features**: Comments, sharing, collaboration - -## 🎊 Conclusion - -**LeakHub** is a complete, production-ready platform that successfully combines: - -- **Innovative Concept**: AI transparency through crowdsourcing -- **Modern Technology**: Latest web technologies and best practices -- **Beautiful Design**: Engaging cyberpunk aesthetic -- **Robust Architecture**: Scalable and maintainable codebase -- **Multiple Deployment Options**: Flexible hosting solutions - -The platform is ready to be deployed and can immediately start serving the AI research community. With its comprehensive feature set, beautiful design, and robust architecture, LeakHub has the potential to become a central hub for AI system prompt discovery and verification. - ---- - -**🚀 Ready to launch! The future of AI transparency starts here! 🚀** diff --git a/QUICKSTART.md b/QUICKSTART.md deleted file mode 100644 index 5ad153a..0000000 --- a/QUICKSTART.md +++ /dev/null @@ -1,112 +0,0 @@ -# 🚀 LeakHub Quick Start Guide - -## ⚡ Get Started in 30 Seconds - -1. **Open the app**: Double-click `index.html` or open it in your browser -2. **Load demo data** (optional): Open browser console (F12) and run `loadDemoData()` -3. **Start exploring**: Try submitting a leak, comparing submissions, or checking the leaderboard! - -## 🎯 First Steps - -### 1. **Submit Your First Leak** -- Fill in your username (e.g., "YourName") -- Select target type (AI Model, App, Tool, etc.) -- Enter target name (e.g., "GPT-4", "Cursor IDE") -- Paste the system prompt you found -- Add context about how you obtained it -- Click "Submit to Library" - -### 2. **Compare Submissions** -- Go to the "Compare Multiple Instances" section -- Select two different submissions from the dropdowns -- Click "Compare" to see similarity analysis -- High similarity automatically boosts confidence scores! - -### 3. **Explore Community Features** -- Click "🏆 View Leaderboard" to see top contributors -- Click "🎯 Requests & Challenges" for daily missions -- Vote on community requests -- Track your achievements - -## 🎮 Demo Mode - -Want to see the platform in action? Load demo data: - -1. Open browser console (F12) -2. Type: `loadDemoData()` -3. Press Enter -4. Explore the sample submissions! - -**Try this**: Compare the two GPT-4 submissions to see the verification system work! - -## 🏆 Points System - -- **10 points** per submission -- **100 points** for first discovery of a target -- **50 bonus points** for non-model targets (apps, tools, agents) -- **30 bonus points** for submissions with tool prompts -- **20 points** per verification -- **50 bonus points** when reaching verified status -- **400-700 points** for daily challenge completion - -## 🔍 Pro Tips - -### **High-Quality Submissions** -- Include detailed context about how you obtained the prompt -- Add access requirements (login, paid subscription) -- Include target URLs when available -- Mention if the target has tools with their own prompts - -### **Effective Comparison** -- Compare submissions from the same target for best results -- Look for high core similarity scores (>85%) -- Check the consensus view for common elements -- Multiple verifications boost confidence scores - -### **Community Engagement** -- Vote on requests you're interested in -- Participate in daily challenges -- Check the leaderboard regularly -- Submit requests for targets you want to see - -## 🎯 Daily Challenges - -Every day, there's a new challenge to find a specific AI system prompt: -- Check the "Requests & Challenges" section -- Look for the daily challenge banner -- Submit a leak for the target model -- Earn bonus points and special badges! - -## 🚨 Troubleshooting - -### **App not loading?** -- Make sure you're opening `index.html` in a modern browser -- Check that all files are in the same folder -- Try refreshing the page - -### **Demo data not loading?** -- Make sure you're in the browser console (F12) -- Type `loadDemoData()` exactly as shown -- Check for any error messages - -### **Data not saving?** -- The app uses localStorage, so data persists between sessions -- If data disappears, check if you're in private/incognito mode -- Try clearing browser cache and reloading - -## 🎉 You're Ready! - -You now have everything you need to start contributing to AI transparency! - -**Next steps:** -1. Submit your first real leak -2. Compare some submissions -3. Check out the leaderboard -4. Join a daily challenge -5. Request targets you want to see - -**Remember**: The goal is to promote AI transparency through community verification. Be accurate, provide context, and help verify others' submissions! - ---- - -**Happy hunting! 🔍✨** diff --git a/README.md b/README.md index 3a05960..d468d98 100644 --- a/README.md +++ b/README.md @@ -1,246 +1,232 @@ -# 🚀 LeakHub - AI System Prompt Discovery Platform +# 🔓 LeakHub -**The community hub for crowd-sourced system prompt leak verification. CL4R1T4S!** +> The community hub for crowd-sourced system prompt leak verification. **CL4R1T4S!** -## 🌟 What is LeakHub? +LeakHub is an open-source platform where the community can submit, verify, and browse leaked AI system prompts. The platform uses a consensus-based verification system to ensure authenticity and rewards contributors with a points-based leaderboard. -LeakHub is a revolutionary web platform that enables the community to discover, submit, verify, and analyze AI system prompt leaks. It's designed to promote transparency in AI systems through crowdsourced verification and community-driven discovery. +--- ## ✨ Features -### 🔍 **Core Functionality** -- **Submit Leaks**: Submit suspected AI system prompt leaks with detailed metadata -- **Compare & Verify**: Advanced comparison algorithms to verify authenticity -- **Community Library**: Browse and search through all submitted leaks -- **Confidence Scoring**: Automatic confidence assessment based on content analysis +- **🔍 System Prompt Library** - Browse verified AI system prompts organized by provider +- **📝 Submit Leaks** - Contribute system prompts for AI models, apps, tools, agents, and plugins +- **✅ Community Verification** - Leaks require 2 unique users to verify before becoming "verified" +- **🏆 Leaderboard & Points System** - Earn points for contributions and climb the rankings +- **🎯 Requests System** - Request specific AI system prompts from the community +- **🔐 GitHub OAuth** - Secure authentication via GitHub +- **⚡ Real-time Updates** - Instant updates powered by Convex -### 🎯 **Target Types Supported** -- 🤖 **AI Models** (GPT-4, Claude, Gemini, etc.) -- 📱 **Apps/Interfaces** (Cursor, GitHub Copilot, etc.) -- 🔧 **Tools/Functions** (Code Interpreter, WebPilot, etc.) -- 🤝 **AI Agents** (AutoGPT, BabyAGI, etc.) -- 🔌 **Plugins/Extensions** (Browser extensions, IDE plugins, etc.) -- 🛠️ **Custom GPTs/Bots** (Custom implementations) +### Points System -### 🏆 **Gamification & Community** -- **Leaderboard**: Track top contributors and achievements -- **Daily Challenges**: Compete in daily leak hunting challenges -- **Achievement System**: Unlock badges for notable contributions -- **Points System**: Earn points for submissions, verifications, and discoveries +| Action | Points | +| -------------------------------------------------- | ------ | +| Submit a leak that gets verified (first submitter) | +100 | +| Verify someone else's leak | +50 | +| Create a request that gets verified | +20 | -### 🎯 **Requests & Bounties** -- **Community Requests**: Request specific targets for leak hunting -- **Voting System**: Vote on which targets to prioritize -- **Bounty System**: Offer points for high-priority discoveries -- **Trending Requests**: See what the community wants most +--- -### 📊 **Advanced Analytics** -- **Similarity Metrics**: Character match, word match, structure match, core similarity -- **Consensus View**: Identify common elements across multiple submissions -- **Verification Tracking**: Track verification status and confidence levels -- **Statistics Dashboard**: Real-time platform statistics +## 🛠️ Tech Stack + +### Frontend + +- **[React 19](https://react.dev/)** - UI library +- **[Vite](https://vitejs.dev/)** - Build tool and dev server +- **[React Router v7](https://reactrouter.com/)** - Client-side routing +- **[Tailwind CSS v4](https://tailwindcss.com/)** - Utility-first CSS framework +- **[Radix UI](https://www.radix-ui.com/)** - Accessible component primitives +- **[Lucide React](https://lucide.dev/)** - Icon library + +### Backend + +- **[Convex](https://convex.dev/)** - Real-time backend (database, server functions, file storage) +- **[Convex Auth](https://labs.convex.dev/auth)** - Authentication with GitHub OAuth + +### Deployment + +- **[Cloudflare Pages](https://pages.cloudflare.com/)** - Edge deployment via Wrangler + +--- + +## 📁 Project Structure + +``` +leakhub/ +├── convex/ # Convex backend +│ ├── _generated/ # Auto-generated types and API +│ ├── auth.config.ts # Auth configuration +│ ├── auth.ts # Auth handlers +│ ├── github.ts # GitHub API integration +│ ├── http.ts # HTTP endpoints +│ ├── leaderboard.ts # Leaderboard queries +│ ├── leaks.ts # Leak mutations and queries +│ ├── requests.ts # Request mutations and queries +│ ├── schema.ts # Database schema +│ └── users.ts # User mutations and queries +├── src/ # React frontend +│ ├── components/ # Reusable UI components +│ │ ├── ui/ # Shadcn/Radix UI components +│ │ ├── leakLibrary.tsx # Leak browser component +│ │ ├── navbar.tsx # Navigation bar +│ │ └── submitLeakForm.tsx # Leak submission form +│ ├── pages/ # Page components +│ │ ├── Dashboard.tsx # User dashboard +│ │ ├── Leaderboard.tsx # Points leaderboard +│ │ └── Requests.tsx # Leak requests page +│ ├── lib/ # Utility functions +│ ├── App.tsx # Main app component +│ ├── main.tsx # Entry point +│ └── index.css # Global styles +├── public/ # Static assets +├── dist/ # Production build output +├── package.json # Dependencies and scripts +├── vite.config.ts # Vite configuration +├── tsconfig.json # TypeScript configuration +└── wrangler.jsonc # Cloudflare deployment config +``` + +--- ## 🚀 Getting Started ### Prerequisites -- **For Development**: Node.js 18+ and npm -- **For Production**: Modern web browser (Chrome, Firefox, Safari, Edge) -- **For Backend**: Optional - MongoDB, Supabase, or Firebase -### Quick Start (Development) -```bash -# Clone the repository -git clone https://github.com/elder-plinius/LEAKHUB.git -cd LEAKHUB +- [Node.js](https://nodejs.org/) (v18 or higher) +- [npm](https://www.npmjs.com/) +- A [Convex](https://convex.dev/) account -# Install dependencies -npm install +### Installation -# Start development server -npm run dev +1. **Clone the repository** -# Open http://localhost:3000 -``` + ```bash + git clone https://github.com/yourusername/leakhub.git + cd leakhub + ``` -### Quick Start (Production) -1. **GitHub Pages**: Push to main branch - auto-deploys! -2. **Vercel**: `npm i -g vercel && vercel` -3. **Netlify**: `npm install -g netlify-cli && netlify deploy` +2. **Install dependencies** -### Local Testing -```bash -# Build for production -npm run build + ```bash + npm install + ``` -# Preview production build -npm run preview +3. **Set up Convex** -# Serve static files -npm run serve -``` + ```bash + npx convex dev + ``` -### Quick Start Guide + This will prompt you to log in and create a new Convex project. -#### 1. **Submit Your First Leak** -1. Fill in your identifier (username) -2. Select the target type (AI Model, App, Tool, etc.) -3. Enter the target name and URL -4. Paste the suspected system prompt -5. Add context and access requirements -6. Submit and earn points! +4. **Configure GitHub OAuth** -#### 2. **Compare Submissions** -1. Select two different submissions from the dropdowns -2. Click "Compare" to analyze similarity -3. Review the detailed metrics and consensus view -4. High similarity automatically boosts confidence scores + Set up GitHub OAuth credentials in your Convex dashboard and configure the environment variables. -#### 3. **Join the Community** -1. Click "View Leaderboard" to see top contributors -2. Check out "Requests & Challenges" for daily missions -3. Vote on community requests -4. Track your achievements and progress +5. **Start the development server** + ```bash + npm run dev + ``` + This runs both the Vite frontend and Convex backend concurrently. -## 🎮 How It Works +### Available Scripts -### **Submission Process** -1. **Content Analysis**: Automatic confidence scoring based on prompt patterns -2. **First Discovery Detection**: Identifies if this is the first submission for a target -3. **Point Allocation**: Awards points for submissions, discoveries, and verifications -4. **Metadata Tracking**: Stores access requirements, context, and tool information - -### **Verification System** -1. **Multi-Metric Comparison**: Uses character, word, structure, and core similarity -2. **Consensus Building**: Identifies common elements across submissions -3. **Confidence Boosting**: High similarity automatically increases confidence scores -4. **Verification Milestones**: Tracks when leaks reach verified status - -### **Gamification Mechanics** -- **Base Points**: 10 points per submission -- **First Discovery**: 100 points + 50 bonus for non-model targets -- **Tool Prompts**: 30 bonus points for comprehensive submissions -- **Verification**: 20 points per verification + 50 bonus for reaching verified status -- **Daily Challenges**: 400-700 points for completing daily missions - -## 🎨 Design Features - -### **Modern UI/UX** -- **Cyberpunk Aesthetic**: Dark theme with neon accents and gradients -- **Responsive Design**: Works perfectly on desktop, tablet, and mobile -- **Smooth Animations**: Floating grid background and interactive elements -- **Intuitive Navigation**: Clear sections and easy-to-use interface - -### **Visual Elements** -- **Status Indicators**: Real-time statistics and progress tracking -- **Badge System**: Visual indicators for access requirements and features -- **Color Coding**: Different colors for different target types and confidence levels -- **Interactive Elements**: Hover effects, transitions, and feedback - -## 🔧 Technical Details - -### **Frontend Technologies** -- **HTML5**: Semantic markup and modern structure -- **CSS3**: Advanced styling with animations and responsive design -- **JavaScript (ES6+)**: Full application logic and data management -- **Vite**: Fast build tool and development server -- **LocalStorage**: Client-side data persistence with backend fallback - -### **Backend & Deployment** -- **GitHub Actions**: Automated CI/CD pipeline -- **Vercel/Netlify**: Serverless deployment with functions -- **Database Abstraction**: Support for localStorage, MongoDB, Supabase, Firebase -- **API Layer**: RESTful endpoints with CORS support - -### **Key Algorithms** -- **Text Normalization**: Standardized text processing for comparison -- **Similarity Metrics**: Multiple algorithms for comprehensive analysis -- **Levenshtein Distance**: String similarity calculation -- **Phrase Matching**: Sliding window approach for common phrase detection - -### **Data Management** -- **Hybrid Storage**: localStorage with optional backend persistence -- **JSON Serialization**: Efficient data storage and retrieval -- **Real-time Updates**: Instant UI updates and statistics -- **Data Validation**: Input validation and error handling -- **Export/Import**: Full data backup and restore functionality - -## 🎯 Use Cases - -### **For Researchers** -- Document and verify AI system prompts -- Compare different implementations -- Track prompt evolution over time -- Build comprehensive prompt databases - -### **For Developers** -- Understand AI system behaviors -- Debug prompt-related issues -- Learn from existing implementations -- Contribute to AI transparency - -### **For Community** -- Participate in AI transparency efforts -- Compete in daily challenges -- Build reputation and achievements -- Help verify and validate discoveries - -## 🤝 Contributing - -### **How to Contribute** -1. **Submit Leaks**: Share discovered system prompts -2. **Verify Submissions**: Compare and verify existing leaks -3. **Request Targets**: Suggest new targets for the community -4. **Vote on Requests**: Help prioritize community goals -5. **Report Issues**: Help improve the platform - -### **Best Practices** -- **Be Accurate**: Only submit genuine system prompts -- **Provide Context**: Include how you obtained the prompt -- **Add Metadata**: Include access requirements and URLs -- **Verify Others**: Help verify community submissions -- **Respect Privacy**: Don't submit private or sensitive information - -## 🔮 Future Enhancements - -### **Planned Features** -- **Advanced Analytics**: Machine learning-based similarity detection -- **Mobile App**: Native mobile application -- **Real-time Collaboration**: Live collaboration features -- **Advanced Export**: Data export in various formats (CSV, JSON, API) -- **User Authentication**: Secure user accounts and profiles -- **Social Features**: Comments, discussions, and community forums - -### **Backend Integration** -- **Database Support**: MongoDB, PostgreSQL, Firebase integration -- **API Access**: RESTful API for programmatic access -- **Real-time Updates**: WebSocket support for live updates -- **Email Notifications**: Automated notifications and alerts -- **Advanced Security**: JWT authentication and rate limiting - -### **Community Features** -- **User Profiles**: Detailed user profiles and statistics -- **Discussion Forums**: Community discussions and analysis -- **Expert Verification**: Expert review system -- **Bounty Marketplace**: Advanced bounty and reward system -- **Achievement System**: Expanded badges and rewards - -## 📄 License - -This project is open source and available under the MIT License. See the LICENSE file for details. - -## 🙏 Acknowledgments - -- **AI Research Community**: For inspiration and feedback -- **Open Source Contributors**: For tools and libraries used -- **Early Testers**: For valuable feedback and suggestions -- **CL4R1T4S Community**: For the vision of AI transparency - -## 📞 Support - -- **Issues**: Report bugs and feature requests via GitHub issues -- **Discussions**: Join community discussions -- **Documentation**: Check the inline documentation and comments +| Script | Description | +| ---------------------- | ---------------------------------------------- | +| `npm run dev` | Start frontend and backend in development mode | +| `npm run dev:frontend` | Start only the Vite dev server | +| `npm run dev:backend` | Start only the Convex dev server | +| `npm run build` | Build for production | +| `npm run preview` | Preview production build locally | +| `npm run deploy` | Build and deploy to Cloudflare Pages | +| `npm run lint` | Run TypeScript and ESLint checks | --- -**Ready to start hunting for AI system prompts? Open `index.html` and join the LeakHub community! 🚀** +## 🗄️ Database Schema + +### Tables + +#### `leaks` + +Stores system prompt leaks with verification status. + +| Field | Type | Description | +| ----------------- | -------------- | --------------------------------------------- | +| `targetName` | `string` | Name of the AI system | +| `provider` | `string` | Provider/company name | +| `targetType` | `enum` | Type: model, app, tool, agent, plugin, custom | +| `leakText` | `string` | The actual system prompt | +| `leakContext` | `string?` | Additional context | +| `url` | `string?` | Source URL | +| `isFullyVerified` | `boolean` | Verification status | +| `submittedBy` | `Id?` | Submitter reference | +| `verifiedBy` | `Id[]?` | Verifiers references | +| `requiresLogin` | `boolean?` | Access requirements | +| `isPaid` | `boolean?` | Paid service flag | +| `hasToolPrompts` | `boolean?` | Has tool/function prompts | + +#### `requests` + +Stores community requests for specific system prompts. + +| Field | Type | Description | +| ------------- | ------------- | --------------------------------------------- | +| `targetName` | `string` | Requested AI system name | +| `provider` | `string` | Provider/company name | +| `targetType` | `enum` | Type: model, app, tool, agent, plugin, custom | +| `targetUrl` | `string` | URL to the target | +| `closed` | `boolean` | Whether request is fulfilled | +| `leaks` | `Id[]` | Associated leak submissions | +| `submittedBy` | `Id` | Requester reference | + +#### `users` + +User profiles with points tracking. + +| Field | Type | Description | +| ---------- | ----------------- | ------------------- | +| `name` | `string` | Display name | +| `image` | `string` | Profile picture URL | +| `email` | `string` | Email address | +| `points` | `number` | Accumulated points | +| `leaks` | `Id[]?` | Submitted leaks | +| `requests` | `Id[]?` | Created requests | + +--- + +## 🔒 Verification Algorithm + +LeakHub uses a consensus-based verification system: + +1. **Submission** - Users submit leaks linked to requests +2. **Similarity Detection** - Text similarity is calculated using: + - Shingle-based cosine similarity (fast filter) + - Levenshtein distance (precise matching) +3. **Consensus** - When 2+ unique users submit similar content (≥85% similarity), the leak is verified +4. **Rewards** - Points are distributed to submitter, verifiers, and request creator + +--- + +## 🤝 Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +1. Fork the repository +2. Create your feature branch (`git checkout -b feature/amazing-feature`) +3. Commit your changes (`git commit -m 'Add some amazing feature'`) +4. Push to the branch (`git push origin feature/amazing-feature`) +5. Open a Pull Request + +--- + +## 📄 License + +This project is licensed under the **Apache License 2.0** - see the [LICENSE.txt](LICENSE.txt) file for details. + +--- + +## 🙏 Acknowledgments + +- Built with [Convex](https://convex.dev/) - The fullstack TypeScript development platform +- UI components from [shadcn/ui](https://ui.shadcn.com/) +- Icons from [Lucide](https://lucide.dev/) diff --git a/SECURITY_AUDIT.md b/SECURITY_AUDIT.md deleted file mode 100644 index 820ca57..0000000 --- a/SECURITY_AUDIT.md +++ /dev/null @@ -1,207 +0,0 @@ -# 🔒 LeakHub Security Audit Report - -## 🛡️ Security Assessment Summary - -**Status**: ✅ **PRODUCTION READY** -**Risk Level**: 🟢 **LOW** -**Last Updated**: December 2024 - -## 🔍 Security Analysis - -### ✅ **SECURITY STRENGTHS** - -#### **1. No Hardcoded Secrets** -- ✅ No API keys, passwords, or tokens in code -- ✅ All sensitive data uses environment variables -- ✅ JWT secret properly configured for production -- ✅ Database credentials externalized - -#### **2. Input Validation & Sanitization** -- ✅ HTML sanitization functions implemented -- ✅ XSS protection through content filtering -- ✅ Input validation on all forms -- ✅ Safe innerHTML usage patterns - -#### **3. Security Headers** -- ✅ X-XSS-Protection enabled -- ✅ X-Content-Type-Options: nosniff -- ✅ X-Frame-Options: DENY (prevents clickjacking) -- ✅ Strict-Transport-Security configured -- ✅ Content Security Policy implemented -- ✅ Referrer Policy set to strict-origin-when-cross-origin - -#### **4. Data Protection** -- ✅ Client-side only (no server-side data storage) -- ✅ localStorage with proper validation -- ✅ No sensitive data in URLs or logs -- ✅ Export/Import functionality for data portability - -#### **5. Code Quality** -- ✅ No eval() or dangerous JavaScript functions -- ✅ No inline event handlers -- ✅ Proper error handling without information leakage -- ✅ Console logging minimized for production - -### 🔧 **SECURITY IMPROVEMENTS MADE** - -#### **1. XSS Protection** -```javascript -// Added sanitization functions -function sanitizeHTML(text) { - if (typeof text !== 'string') return ''; - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; -} - -function safeInnerHTML(element, content) { - // Sanitizes content before setting innerHTML -} -``` - -#### **2. Security Headers** -- Added comprehensive security headers to Vercel and Netlify configs -- Implemented Content Security Policy -- Enabled HSTS for HTTPS enforcement - -#### **3. Environment Configuration** -- Removed hardcoded JWT secret -- Added production environment checks -- Externalized all configuration - -### 🚨 **POTENTIAL RISKS & MITIGATIONS** - -#### **1. Client-Side Data Storage** -- **Risk**: Data stored in localStorage is accessible to users -- **Mitigation**: This is by design - LeakHub is a client-side application -- **Recommendation**: Users should be aware data is stored locally - -#### **2. XSS via User Input** -- **Risk**: User-submitted content could contain malicious scripts -- **Mitigation**: HTML sanitization implemented -- **Recommendation**: Consider using DOMPurify library for production - -#### **3. No Authentication** -- **Risk**: No user authentication system -- **Mitigation**: This is by design for community transparency -- **Recommendation**: Consider optional user accounts for advanced features - -## 🔐 **SECURITY RECOMMENDATIONS** - -### **For Production Deployment** - -#### **1. HTTPS Enforcement** -```bash -# Ensure HTTPS is enabled on your hosting platform -# GitHub Pages, Vercel, and Netlify all provide HTTPS by default -``` - -#### **2. Content Security Policy** -```html - - -``` - -#### **3. Additional Security Libraries** -```bash -# For enhanced XSS protection -npm install dompurify -``` - -#### **4. Monitoring & Logging** -```javascript -// Add error tracking -window.addEventListener('error', function(e) { - // Send to monitoring service - console.error('Security Event:', e); -}); -``` - -### **For Future Enhancements** - -#### **1. User Authentication** -- Implement optional user accounts -- Add OAuth integration (GitHub, Google) -- Implement session management - -#### **2. Rate Limiting** -- Add client-side rate limiting for submissions -- Implement cooldown periods for actions - -#### **3. Data Validation** -- Add server-side validation if backend is added -- Implement input length limits -- Add file upload restrictions - -## 📋 **SECURITY CHECKLIST** - -### **Pre-Deployment** -- [x] No hardcoded secrets in code -- [x] Security headers configured -- [x] XSS protection implemented -- [x] Input validation in place -- [x] Error handling without information leakage -- [x] HTTPS enforced -- [x] Content Security Policy active - -### **Post-Deployment** -- [ ] Security headers verified -- [ ] HTTPS working correctly -- [ ] No console errors in production -- [ ] User data handling reviewed -- [ ] Privacy policy updated -- [ ] Terms of service updated - -## 🚀 **DEPLOYMENT SECURITY** - -### **GitHub Pages** -- ✅ Automatic HTTPS -- ✅ Security headers via GitHub Actions -- ✅ No server-side code execution - -### **Vercel** -- ✅ Automatic HTTPS -- ✅ Security headers configured -- ✅ Serverless functions with proper CORS - -### **Netlify** -- ✅ Automatic HTTPS -- ✅ Security headers configured -- ✅ Form handling with spam protection - -## 📊 **SECURITY METRICS** - -- **OWASP Top 10 Coverage**: 8/10 -- **Security Headers**: 7/7 implemented -- **XSS Protection**: ✅ Implemented -- **CSRF Protection**: ✅ Not applicable (client-side only) -- **SQL Injection**: ✅ Not applicable (no database) -- **Authentication**: ✅ Not implemented (by design) - -## 🔍 **SECURITY TESTING** - -### **Manual Testing Performed** -- [x] XSS payload testing -- [x] HTML injection testing -- [x] JavaScript injection testing -- [x] Security headers verification -- [x] HTTPS enforcement testing -- [x] Data validation testing - -### **Automated Testing Recommended** -- [ ] OWASP ZAP security scan -- [ ] Lighthouse security audit -- [ ] Content Security Policy validation -- [ ] SSL Labs security test - -## 📞 **SECURITY CONTACT** - -For security issues or questions: -- **Repository**: https://github.com/elder-plinius/LEAKHUB -- **Issues**: Use GitHub Issues with "security" label -- **Responsible Disclosure**: Please report vulnerabilities privately - ---- - -**Note**: This security audit is based on the current codebase as of December 2024. Regular security reviews are recommended as the application evolves. diff --git a/api/config.js b/api/config.js deleted file mode 100644 index 098258e..0000000 --- a/api/config.js +++ /dev/null @@ -1,102 +0,0 @@ -// LeakHub Backend Configuration - -const config = { - // Database settings - database: { - // Local storage (default) - type: 'localStorage', - - // Backend options (uncomment to enable) - // type: 'mongodb', - // url: process.env.MONGODB_URI || 'mongodb://localhost:27017/leakhub', - - // type: 'supabase', - // url: process.env.SUPABASE_URL, - // key: process.env.SUPABASE_ANON_KEY, - - // type: 'firebase', - // config: { - // apiKey: process.env.FIREBASE_API_KEY, - // authDomain: process.env.FIREBASE_AUTH_DOMAIN, - // projectId: process.env.FIREBASE_PROJECT_ID, - // storageBucket: process.env.FIREBASE_STORAGE_BUCKET, - // messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID, - // appId: process.env.FIREBASE_APP_ID - // } - }, - - // API settings - api: { - port: process.env.PORT || 3000, - cors: { - origin: process.env.ALLOWED_ORIGINS?.split(',') || ['*'], - methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], - allowedHeaders: ['Content-Type', 'Authorization'] - }, - rateLimit: { - windowMs: 15 * 60 * 1000, // 15 minutes - max: 100 // limit each IP to 100 requests per windowMs - } - }, - - // Security settings - security: { - jwtSecret: process.env.JWT_SECRET || (process.env.NODE_ENV === 'production' ? null : 'dev-secret-key'), - bcryptRounds: 12, - sessionTimeout: 24 * 60 * 60 * 1000 // 24 hours - }, - - // Analytics settings - analytics: { - enabled: process.env.ANALYTICS_ENABLED === 'true', - googleAnalyticsId: process.env.GOOGLE_ANALYTICS_ID, - mixpanelToken: process.env.MIXPANEL_TOKEN - }, - - // Email settings (for notifications) - email: { - enabled: process.env.EMAIL_ENABLED === 'true', - provider: process.env.EMAIL_PROVIDER || 'smtp', - smtp: { - host: process.env.SMTP_HOST, - port: process.env.SMTP_PORT || 587, - secure: process.env.SMTP_SECURE === 'true', - auth: { - user: process.env.SMTP_USER, - pass: process.env.SMTP_PASS - } - } - }, - - // Feature flags - features: { - userRegistration: true, - emailVerification: false, - socialLogin: false, - realTimeUpdates: false, - advancedAnalytics: false, - exportData: true, - backupRestore: true - }, - - // Development settings - development: { - debug: process.env.NODE_ENV !== 'production', - mockData: process.env.MOCK_DATA === 'true', - hotReload: process.env.NODE_ENV === 'development' - } -}; - -// Environment-specific overrides -if (process.env.NODE_ENV === 'production') { - config.development.debug = false; - config.development.mockData = false; - config.development.hotReload = false; -} - -if (process.env.NODE_ENV === 'test') { - config.database.type = 'memory'; - config.security.jwtSecret = 'test-secret'; -} - -module.exports = config; diff --git a/api/database.js b/api/database.js deleted file mode 100644 index 10dfd6e..0000000 --- a/api/database.js +++ /dev/null @@ -1,274 +0,0 @@ -// Database abstraction layer for LeakHub -// Supports both localStorage and future backend APIs - -class LeakHubDatabase { - constructor() { - this.storagePrefix = 'leakhub_'; - this.apiEndpoint = null; // Will be set for backend mode - this.isBackendMode = false; - } - - // Initialize database with optional backend endpoint - async init(backendUrl = null) { - if (backendUrl) { - this.apiEndpoint = backendUrl; - this.isBackendMode = true; - console.log('LeakHub: Backend mode enabled'); - } else { - console.log('LeakHub: Local storage mode enabled'); - } - } - - // Generic storage methods - async get(key) { - if (this.isBackendMode) { - return await this._getFromBackend(key); - } else { - return this._getFromLocalStorage(key); - } - } - - async set(key, value) { - if (this.isBackendMode) { - return await this._setToBackend(key, value); - } else { - return this._setToLocalStorage(key, value); - } - } - - async delete(key) { - if (this.isBackendMode) { - return await this._deleteFromBackend(key); - } else { - return this._deleteFromLocalStorage(key); - } - } - - // LocalStorage methods - _getFromLocalStorage(key) { - try { - const fullKey = this.storagePrefix + key; - const data = localStorage.getItem(fullKey); - return data ? JSON.parse(data) : null; - } catch (error) { - console.error('Error reading from localStorage:', error); - return null; - } - } - - _setToLocalStorage(key, value) { - try { - const fullKey = this.storagePrefix + key; - localStorage.setItem(fullKey, JSON.stringify(value)); - return true; - } catch (error) { - console.error('Error writing to localStorage:', error); - return false; - } - } - - _deleteFromLocalStorage(key) { - try { - const fullKey = this.storagePrefix + key; - localStorage.removeItem(fullKey); - return true; - } catch (error) { - console.error('Error deleting from localStorage:', error); - return false; - } - } - - // Backend API methods - async _getFromBackend(key) { - try { - const response = await fetch(`${this.apiEndpoint}/data/${key}`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - } - }); - - if (response.ok) { - return await response.json(); - } else { - console.error('Backend GET error:', response.status); - return null; - } - } catch (error) { - console.error('Error fetching from backend:', error); - return null; - } - } - - async _setToBackend(key, value) { - try { - const response = await fetch(`${this.apiEndpoint}/data/${key}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(value) - }); - - return response.ok; - } catch (error) { - console.error('Error saving to backend:', error); - return false; - } - } - - async _deleteFromBackend(key) { - try { - const response = await fetch(`${this.apiEndpoint}/data/${key}`, { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - } - }); - - return response.ok; - } catch (error) { - console.error('Error deleting from backend:', error); - return false; - } - } - - // Specific LeakHub data methods - async getLeakDatabase() { - return await this.get('leakDatabase') || []; - } - - async setLeakDatabase(data) { - return await this.set('leakDatabase', data); - } - - async getUserStats() { - return await this.get('userStats') || {}; - } - - async setUserStats(data) { - return await this.set('userStats', data); - } - - async getLeakRequests() { - return await this.get('leakRequests') || []; - } - - async setLeakRequests(data) { - return await this.set('leakRequests', data); - } - - async getUserVotes() { - return await this.get('userVotes') || {}; - } - - async setUserVotes(data) { - return await this.set('userVotes', data); - } - - async getDailyChallenge() { - return await this.get('dailyChallenge') || null; - } - - async setDailyChallenge(data) { - return await this.set('dailyChallenge', data); - } - - async getAverageSimilarity() { - return await this.get('avgSimilarity') || '0'; - } - - async setAverageSimilarity(value) { - return await this.set('avgSimilarity', value); - } - - // Export/Import functionality - async exportData() { - const data = { - leakDatabase: await this.getLeakDatabase(), - userStats: await this.getUserStats(), - leakRequests: await this.getLeakRequests(), - userVotes: await this.getUserVotes(), - dailyChallenge: await this.getDailyChallenge(), - avgSimilarity: await this.getAverageSimilarity(), - exportDate: new Date().toISOString(), - version: '1.0.0' - }; - - return data; - } - - async importData(data) { - try { - if (data.leakDatabase) await this.setLeakDatabase(data.leakDatabase); - if (data.userStats) await this.setUserStats(data.userStats); - if (data.leakRequests) await this.setLeakRequests(data.leakRequests); - if (data.userVotes) await this.setUserVotes(data.userVotes); - if (data.dailyChallenge) await this.setDailyChallenge(data.dailyChallenge); - if (data.avgSimilarity) await this.setAverageSimilarity(data.avgSimilarity); - - return true; - } catch (error) { - console.error('Error importing data:', error); - return false; - } - } - - // Backup and restore - async createBackup() { - const data = await this.exportData(); - const backupKey = `backup_${Date.now()}`; - await this.set(backupKey, data); - return backupKey; - } - - async restoreBackup(backupKey) { - const backup = await this.get(backupKey); - if (backup) { - return await this.importData(backup); - } - return false; - } - - // Analytics and statistics - async getStatistics() { - const leakDatabase = await this.getLeakDatabase(); - const userStats = await this.getUserStats(); - - return { - totalSubmissions: leakDatabase.length, - uniqueUsers: Object.keys(userStats).length, - totalScore: Object.values(userStats).reduce((sum, stats) => sum + (stats.totalScore || 0), 0), - verifiedLeaks: leakDatabase.filter(sub => sub.confidence >= 90).length, - firstDiscoveries: leakDatabase.filter(sub => sub.isFirstDiscovery).length, - targetTypes: this._countTargetTypes(leakDatabase), - recentActivity: this._getRecentActivity(leakDatabase) - }; - } - - _countTargetTypes(leakDatabase) { - const counts = {}; - leakDatabase.forEach(sub => { - const type = sub.targetType || 'model'; - counts[type] = (counts[type] || 0) + 1; - }); - return counts; - } - - _getRecentActivity(leakDatabase) { - const now = new Date(); - const oneWeekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); - - return leakDatabase.filter(sub => - new Date(sub.timestamp) > oneWeekAgo - ).length; - } -} - -// Create global instance -window.LeakHubDB = new LeakHubDatabase(); - -// Auto-initialize -window.LeakHubDB.init().then(() => { - console.log('LeakHub Database initialized'); -}); diff --git a/api/serverless.js b/api/serverless.js deleted file mode 100644 index be21249..0000000 --- a/api/serverless.js +++ /dev/null @@ -1,83 +0,0 @@ -// Serverless API endpoints for LeakHub -// This can be deployed to Vercel, Netlify, or other serverless platforms - -// Mock database for serverless functions -const mockDatabase = { - leakDatabase: [], - userStats: {}, - leakRequests: [], - userVotes: {}, - dailyChallenge: null, - avgSimilarity: '0' -}; - -// CORS headers -const corsHeaders = { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - 'Content-Type': 'application/json' -}; - -// Helper function to get data -function getData(key) { - // In a real implementation, this would connect to a database - // For now, we'll use a simple in-memory store - return mockDatabase[key] || null; -} - -// Helper function to set data -function setData(key, value) { - mockDatabase[key] = value; - return true; -} - -// API handler for Vercel/Netlify -export default async function handler(req, res) { - // Handle CORS preflight - if (req.method === 'OPTIONS') { - return res.status(200).json({}, { headers: corsHeaders }); - } - - const { method, url, body } = req; - const path = url.split('/').pop(); // Get the last part of the URL - - try { - switch (method) { - case 'GET': - if (path === 'data') { - const key = req.query.key; - const data = getData(key); - return res.status(200).json(data, { headers: corsHeaders }); - } - break; - - case 'POST': - if (path === 'data') { - const key = req.query.key; - const success = setData(key, body); - return res.status(200).json({ success }, { headers: corsHeaders }); - } - break; - - case 'DELETE': - if (path === 'data') { - const key = req.query.key; - const success = setData(key, null); - return res.status(200).json({ success }, { headers: corsHeaders }); - } - break; - - default: - return res.status(405).json({ error: 'Method not allowed' }, { headers: corsHeaders }); - } - } catch (error) { - console.error('API Error:', error); - return res.status(500).json({ error: 'Internal server error' }, { headers: corsHeaders }); - } -} - -// Export for different serverless platforms -if (typeof module !== 'undefined' && module.exports) { - module.exports = handler; -} diff --git a/components.json b/components.json new file mode 100644 index 0000000..2b0833f --- /dev/null +++ b/components.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "registries": {} +} diff --git a/convex/README.md b/convex/README.md new file mode 100644 index 0000000..4d82e13 --- /dev/null +++ b/convex/README.md @@ -0,0 +1,90 @@ +# Welcome to your Convex functions directory! + +Write your Convex functions here. +See https://docs.convex.dev/functions for more. + +A query function that takes two arguments looks like: + +```ts +// functions.js +import { query } from "./_generated/server"; +import { v } from "convex/values"; + +export const myQueryFunction = query({ + // Validators for arguments. + args: { + first: v.number(), + second: v.string(), + }, + + // Function implementation. + handler: async (ctx, args) => { + // Read the database as many times as you need here. + // See https://docs.convex.dev/database/reading-data. + const documents = await ctx.db.query("tablename").collect(); + + // Arguments passed from the client are properties of the args object. + console.log(args.first, args.second); + + // Write arbitrary JavaScript here: filter, aggregate, build derived data, + // remove non-public properties, or create new objects. + return documents; + }, +}); +``` + +Using this query function in a React component looks like: + +```ts +const data = useQuery(api.functions.myQueryFunction, { + first: 10, + second: "hello", +}); +``` + +A mutation function looks like: + +```ts +// functions.js +import { mutation } from "./_generated/server"; +import { v } from "convex/values"; + +export const myMutationFunction = mutation({ + // Validators for arguments. + args: { + first: v.string(), + second: v.string(), + }, + + // Function implementation. + handler: async (ctx, args) => { + // Insert or modify documents in the database here. + // Mutations can also read from the database like queries. + // See https://docs.convex.dev/database/writing-data. + const message = { body: args.first, author: args.second }; + const id = await ctx.db.insert("messages", message); + + // Optionally, return a value from your mutation. + return await ctx.db.get(id); + }, +}); +``` + +Using this mutation function in a React component looks like: + +```ts +const mutation = useMutation(api.functions.myMutationFunction); +function handleButtonPress() { + // fire and forget, the most common way to use mutations + mutation({ first: "Hello!", second: "me" }); + // OR + // use the result once the mutation has completed + mutation({ first: "Hello!", second: "me" }).then((result) => + console.log(result), + ); +} +``` + +Use the Convex CLI to push your functions to a deployment. See everything +the Convex CLI can do by running `npx convex -h` in your project root +directory. To learn more, launch the docs with `npx convex docs`. diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts new file mode 100644 index 0000000..c9340cc --- /dev/null +++ b/convex/_generated/api.d.ts @@ -0,0 +1,61 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type * as auth from "../auth.js"; +import type * as github from "../github.js"; +import type * as http from "../http.js"; +import type * as leaderboard from "../leaderboard.js"; +import type * as leaks from "../leaks.js"; +import type * as requests from "../requests.js"; +import type * as users from "../users.js"; + +import type { + ApiFromModules, + FilterApi, + FunctionReference, +} from "convex/server"; + +declare const fullApi: ApiFromModules<{ + auth: typeof auth; + github: typeof github; + http: typeof http; + leaderboard: typeof leaderboard; + leaks: typeof leaks; + requests: typeof requests; + users: typeof users; +}>; + +/** + * A utility for referencing Convex functions in your app's public API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +export declare const api: FilterApi< + typeof fullApi, + FunctionReference +>; + +/** + * A utility for referencing Convex functions in your app's internal API. + * + * Usage: + * ```js + * const myFunctionReference = internal.myModule.myFunction; + * ``` + */ +export declare const internal: FilterApi< + typeof fullApi, + FunctionReference +>; + +export declare const components: {}; diff --git a/convex/_generated/api.js b/convex/_generated/api.js new file mode 100644 index 0000000..44bf985 --- /dev/null +++ b/convex/_generated/api.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { anyApi, componentsGeneric } from "convex/server"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +export const api = anyApi; +export const internal = anyApi; +export const components = componentsGeneric(); diff --git a/convex/_generated/dataModel.d.ts b/convex/_generated/dataModel.d.ts new file mode 100644 index 0000000..f97fd19 --- /dev/null +++ b/convex/_generated/dataModel.d.ts @@ -0,0 +1,60 @@ +/* eslint-disable */ +/** + * Generated data model types. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type { + DataModelFromSchemaDefinition, + DocumentByName, + TableNamesInDataModel, + SystemTableNames, +} from "convex/server"; +import type { GenericId } from "convex/values"; +import schema from "../schema.js"; + +/** + * The names of all of your Convex tables. + */ +export type TableNames = TableNamesInDataModel; + +/** + * The type of a document stored in Convex. + * + * @typeParam TableName - A string literal type of the table name (like "users"). + */ +export type Doc = DocumentByName< + DataModel, + TableName +>; + +/** + * An identifier for a document in Convex. + * + * Convex documents are uniquely identified by their `Id`, which is accessible + * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids). + * + * Documents can be loaded using `db.get(tableName, id)` in query and mutation functions. + * + * IDs are just strings at runtime, but this type can be used to distinguish them from other + * strings when type checking. + * + * @typeParam TableName - A string literal type of the table name (like "users"). + */ +export type Id = + GenericId; + +/** + * A type describing your Convex data model. + * + * This type includes information about what tables you have, the type of + * documents stored in those tables, and the indexes defined on them. + * + * This type is used to parameterize methods like `queryGeneric` and + * `mutationGeneric` to make them type-safe. + */ +export type DataModel = DataModelFromSchemaDefinition; diff --git a/convex/_generated/server.d.ts b/convex/_generated/server.d.ts new file mode 100644 index 0000000..bec05e6 --- /dev/null +++ b/convex/_generated/server.d.ts @@ -0,0 +1,143 @@ +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + ActionBuilder, + HttpActionBuilder, + MutationBuilder, + QueryBuilder, + GenericActionCtx, + GenericMutationCtx, + GenericQueryCtx, + GenericDatabaseReader, + GenericDatabaseWriter, +} from "convex/server"; +import type { DataModel } from "./dataModel.js"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const query: QueryBuilder; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const internalQuery: QueryBuilder; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const mutation: MutationBuilder; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const internalMutation: MutationBuilder; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export declare const action: ActionBuilder; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export declare const internalAction: ActionBuilder; + +/** + * Define an HTTP action. + * + * The wrapped function will be used to respond to HTTP requests received + * by a Convex deployment if the requests matches the path and method where + * this action is routed. Be sure to route your httpAction in `convex/http.js`. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument + * and a Fetch API `Request` object as its second. + * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up. + */ +export declare const httpAction: HttpActionBuilder; + +/** + * A set of services for use within Convex query functions. + * + * The query context is passed as the first argument to any Convex query + * function run on the server. + * + * This differs from the {@link MutationCtx} because all of the services are + * read-only. + */ +export type QueryCtx = GenericQueryCtx; + +/** + * A set of services for use within Convex mutation functions. + * + * The mutation context is passed as the first argument to any Convex mutation + * function run on the server. + */ +export type MutationCtx = GenericMutationCtx; + +/** + * A set of services for use within Convex action functions. + * + * The action context is passed as the first argument to any Convex action + * function run on the server. + */ +export type ActionCtx = GenericActionCtx; + +/** + * An interface to read from the database within Convex query functions. + * + * The two entry points are {@link DatabaseReader.get}, which fetches a single + * document by its {@link Id}, or {@link DatabaseReader.query}, which starts + * building a query. + */ +export type DatabaseReader = GenericDatabaseReader; + +/** + * An interface to read from and write to the database within Convex mutation + * functions. + * + * Convex guarantees that all writes within a single mutation are + * executed atomically, so you never have to worry about partial writes leaving + * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control) + * for the guarantees Convex provides your functions. + */ +export type DatabaseWriter = GenericDatabaseWriter; diff --git a/convex/_generated/server.js b/convex/_generated/server.js new file mode 100644 index 0000000..bf3d25a --- /dev/null +++ b/convex/_generated/server.js @@ -0,0 +1,93 @@ +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + actionGeneric, + httpActionGeneric, + queryGeneric, + mutationGeneric, + internalActionGeneric, + internalMutationGeneric, + internalQueryGeneric, +} from "convex/server"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const query = queryGeneric; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const internalQuery = internalQueryGeneric; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const mutation = mutationGeneric; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const internalMutation = internalMutationGeneric; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export const action = actionGeneric; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export const internalAction = internalActionGeneric; + +/** + * Define an HTTP action. + * + * The wrapped function will be used to respond to HTTP requests received + * by a Convex deployment if the requests matches the path and method where + * this action is routed. Be sure to route your httpAction in `convex/http.js`. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument + * and a Fetch API `Request` object as its second. + * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up. + */ +export const httpAction = httpActionGeneric; diff --git a/convex/auth.config.ts b/convex/auth.config.ts new file mode 100644 index 0000000..a32c1b8 --- /dev/null +++ b/convex/auth.config.ts @@ -0,0 +1,10 @@ +import { AuthConfig } from "convex/server"; + +export default { + providers: [ + { + domain: process.env.CONVEX_SITE_URL!, + applicationID: "convex", + }, + ], +} satisfies AuthConfig; diff --git a/convex/auth.ts b/convex/auth.ts new file mode 100644 index 0000000..eab97b8 --- /dev/null +++ b/convex/auth.ts @@ -0,0 +1,22 @@ +import GitHub from "@auth/core/providers/github"; +import { convexAuth } from "@convex-dev/auth/server"; + +export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({ + providers: [GitHub], + callbacks: { + async createOrUpdateUser(ctx, args) { + if (args.existingUserId) { + return args.existingUserId; + } + + return await ctx.db.insert("users", { + email: args.profile.email, + name: args.profile.name, + image: args.profile.image, + points: 0, + requests: [], + leaks: [], + }); + }, + }, +}); diff --git a/convex/github.ts b/convex/github.ts new file mode 100644 index 0000000..b6eb7ff --- /dev/null +++ b/convex/github.ts @@ -0,0 +1,120 @@ +import { internalAction, action } from "./_generated/server"; +import { api, internal } from "./_generated/api"; +import { v } from "convex/values"; +const DEFAULT_REPO_OWNER = "elder-plinius"; +const DEFAULT_REPO_NAME = "CL4R1T4S"; +const DEFAULT_BRANCH = "main"; +const GITHUB_API_TOKEN = process.env.GITHUB_API_TOKEN; +const GITHUB_HEADERS = { + "User-Agent": "LeakHubConvex/1.0", + Accept: "application/vnd.github+json", + Authorization: `Bearer ${GITHUB_API_TOKEN}`, +}; + +export const importAllLeaks = internalAction({ + args: {}, + handler: async (ctx) => { + const repoOwner = DEFAULT_REPO_OWNER; + const repoName = DEFAULT_REPO_NAME; + const branch = DEFAULT_BRANCH; + const headers = GITHUB_HEADERS; + const repo = await fetch( + `https://api.github.com/repos/${repoOwner}/${repoName}/contents/?ref=${branch}`, + { + headers, + }, + ); + const directories = await repo.json(); + + let insertedLeaks = 0; + for (const directory of directories) { + if (directory.type !== "dir") { + continue; + } + const files = await fetch( + `https://api.github.com/repos/${repoOwner}/${repoName}/contents/${directory.path}?ref=${branch}`, + { + headers, + }, + ); + const filesJson = await files.json(); + for (const file of filesJson) { + const content = await fetch( + `https://api.github.com/repos/${repoOwner}/${repoName}/contents/${file.path}?ref=${branch}`, + { + headers, + }, + ); + const contentJson = await content.json(); + console.log(contentJson); + const targetName = contentJson.name; + const provider = contentJson.path.split("/")[0]; + + try { + const contentText = decodeBase64Utf8(contentJson.content); + + // Use internal mutation to insert fully verified leaks from GitHub + await ctx.runMutation(internal.leaks.insertVerifiedLeak, { + targetName, + provider, + leakText: contentText, + targetType: "model" as const, + }); + insertedLeaks++; + } catch (error) { + console.error(`Error decoding content for ${file.path}: ${error}`); + } + } + } + + return insertedLeaks; + }, +}); + +/** + * Public action to trigger GitHub import of leaks. + * Returns success status, count of imported leaks, and a message. + */ +export const triggerGitHubImport = action({ + args: {}, + returns: v.object({ + success: v.boolean(), + count: v.number(), + message: v.string(), + }), + handler: async (ctx) => { + try { + // Call the internal action + const count: number = await ctx.runAction(internal.github.importAllLeaks); + + return { + success: true, + count, + message: `Successfully imported ${count} leaks`, + }; + } catch (error) { + console.error("Error importing leaks:", error); + return { + success: false, + count: 0, + message: `Error: ${error}`, + }; + } + }, +}); + +function decodeBase64Utf8(base64: string): string { + // Remove whitespace and line breaks + base64 = base64.replace(/\r?\n|\r/g, "").trim(); + // Normalize URL-safe and padding + base64 = base64.replace(/-/g, "+").replace(/_/g, "/"); + while (base64.length % 4 !== 0) base64 += "="; + + // Decode Base64 to binary string + const binary = atob(base64); + + // Convert binary string to UTF-8 text + const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0)); + const decoded = new TextDecoder("utf-8").decode(bytes); + return decoded; +} diff --git a/convex/http.ts b/convex/http.ts new file mode 100644 index 0000000..1816e5b --- /dev/null +++ b/convex/http.ts @@ -0,0 +1,8 @@ +import { httpRouter } from "convex/server"; +import { auth } from "./auth"; + +const http = httpRouter(); + +auth.addHttpRoutes(http); + +export default http; diff --git a/convex/leaderboard.ts b/convex/leaderboard.ts new file mode 100644 index 0000000..e26817d --- /dev/null +++ b/convex/leaderboard.ts @@ -0,0 +1,99 @@ +import { v } from "convex/values"; +import { getAuthUserId } from "@convex-dev/auth/server"; +import { query } from "./_generated/server"; +import { Id } from "./_generated/dataModel"; + +/** + * Get leaderboard data including: + * - Top 10 users by points + * - Current user's rank (if not in top 10) + * - Total number of users + */ +export const getLeaderboard = query({ + args: {}, + returns: v.object({ + topUsers: v.array( + v.object({ + _id: v.id("users"), + name: v.string(), + image: v.string(), + points: v.number(), + rank: v.number(), + isCurrentUser: v.boolean(), + }), + ), + currentUserRank: v.union( + v.object({ + _id: v.id("users"), + name: v.string(), + image: v.string(), + points: v.number(), + rank: v.number(), + }), + v.null(), + ), + totalUsers: v.number(), + }), + handler: async (ctx) => { + const userId = await getAuthUserId(ctx); + + const usersQuery = ctx.db + .query("users") + .withIndex("by_points") + .order("desc"); + + const topUsers: Array<{ + _id: Id<"users">; + name: string; + image: string; + points: number; + rank: number; + isCurrentUser: boolean; + }> = []; + + let currentUserRank: { + _id: Id<"users">; + name: string; + image: string; + points: number; + rank: number; + } | null = null; + + let rank = 0; + + for await (const user of usersQuery) { + rank += 1; + const isCurrentUser = userId !== null && user._id === userId; + + if (rank <= 10) { + topUsers.push({ + _id: user._id, + name: user.name, + image: user.image, + points: user.points, + rank, + isCurrentUser, + }); + } + + if (isCurrentUser && rank > 10) { + currentUserRank = { + _id: user._id, + name: user.name, + image: user.image, + points: user.points, + rank, + }; + } + } + + const totalUsers = rank; + + return { + topUsers, + currentUserRank, + totalUsers, + }; + }, +}); + diff --git a/convex/leaks.ts b/convex/leaks.ts new file mode 100644 index 0000000..8dd76a5 --- /dev/null +++ b/convex/leaks.ts @@ -0,0 +1,940 @@ +import { v } from "convex/values"; +import { getAuthUserId } from "@convex-dev/auth/server"; +import { + internalAction, + internalMutation, + internalQuery, + mutation, + query, +} from "./_generated/server"; +import { Id } from "./_generated/dataModel"; +import { internal } from "./_generated/api"; + +/** + * Helper function to normalize text for comparison. + * Removes extra whitespace, converts to lowercase, and trims. + * This allows for minor formatting differences while ensuring content matches. + */ +function normalizeText(text: string): string { + return text + .toLowerCase() + .trim() + .replace(/\s+/g, " ") // Replace multiple spaces with single space + .replace(/\n\s*\n/g, "\n"); // Normalize multiple newlines +} + +/** + * Calculate Levenshtein distance between two strings. + * This measures the minimum number of single-character edits required + * to change one string into another. + */ +const SHINGLE_SIZE = 4; +const SHINGLE_THRESHOLD = 0.6; + +/** + * Build a shingle frequency vector from normalized text. + * Uses overlapping n-grams to preserve ordering context while + * keeping memory footprint linear in the input size. + */ +function buildShingleVector(text: string): Map { + const vector = new Map(); + const tokens = text.split(/\s+/).filter(Boolean); + + if (tokens.length === 0) { + return vector; + } + + for (let i = 0; i <= tokens.length - SHINGLE_SIZE; i++) { + const shingle = tokens.slice(i, i + SHINGLE_SIZE).join(" "); + vector.set(shingle, (vector.get(shingle) ?? 0) + 1); + } + + // For very short texts fall back to single tokens so we don't return 0 shingles. + if (vector.size === 0) { + for (const token of tokens) { + vector.set(token, (vector.get(token) ?? 0) + 1); + } + } + + return vector; +} + +/** + * Compute cosine similarity between two shingle frequency vectors. + * This is our lightweight filter to discard obviously different leaks. + */ +function cosineSimilarity( + vecA: Map, + vecB: Map, +): number { + if (vecA.size === 0 || vecB.size === 0) { + return vecA.size === vecB.size ? 1 : 0; + } + + let dot = 0; + let magA = 0; + let magB = 0; + + for (const value of vecA.values()) { + magA += value * value; + } + for (const value of vecB.values()) { + magB += value * value; + } + + // Iterate over smaller vector for efficiency. + const [smaller, larger] = + vecA.size <= vecB.size ? [vecA, vecB] : [vecB, vecA]; + for (const [term, value] of smaller.entries()) { + const other = larger.get(term); + if (other !== undefined) { + dot += value * other; + } + } + + if (magA === 0 || magB === 0) { + return 0; + } + + return dot / Math.sqrt(magA * magB); +} + +/** + * Memory-efficient Levenshtein similarity that stores only two rows of the DP + * matrix. This reduces peak memory to O(min(len1, len2)). + */ +function levenshteinSimilarity(str1: string, str2: string): number { + const len1 = str1.length; + const len2 = str2.length; + + if (len1 === 0 && len2 === 0) { + return 1; + } + if (len1 === 0 || len2 === 0) { + return 0; + } + + // Ensure str2 is the shorter string for smaller buffers. + if (len2 > len1) { + return levenshteinSimilarity(str2, str1); + } + + let previousRow = new Array(len2 + 1); + let currentRow = new Array(len2 + 1); + + for (let j = 0; j <= len2; j++) { + previousRow[j] = j; + } + + for (let i = 1; i <= len1; i++) { + currentRow[0] = i; + const char1 = str1[i - 1]; + + for (let j = 1; j <= len2; j++) { + const cost = char1 === str2[j - 1] ? 0 : 1; + currentRow[j] = Math.min( + currentRow[j - 1] + 1, // insertion + previousRow[j] + 1, // deletion + previousRow[j - 1] + cost, // substitution + ); + } + + // Reuse arrays instead of reallocating. + [previousRow, currentRow] = [currentRow, previousRow]; + } + + const distance = previousRow[len2]; + const similarity = 1 - distance / Math.max(len1, len2); + return Math.max(0, similarity); +} + +/** + * Calculate similarity between two texts using a two-stage approach: + * 1) Cosine similarity on shingles filters out obviously different leaks. + * 2) If the coarse score is high enough we confirm with Levenshtein distance. + */ +function calculateSimilarity(text1: string, text2: string): number { + const normalized1 = normalizeText(text1); + const normalized2 = normalizeText(text2); + + if (normalized1 === normalized2) { + return 1; + } + + const shingleScore = cosineSimilarity( + buildShingleVector(normalized1), + buildShingleVector(normalized2), + ); + + if (shingleScore < SHINGLE_THRESHOLD) { + return shingleScore; + } + + return Math.max( + shingleScore, + levenshteinSimilarity(normalized1, normalized2), + ); +} + +/** + * Insert a new leak into the database. + * Validates that: + * - User is authenticated + * - Required fields are provided + * - User hasn't already submitted a leak for this request + * + * Handles automatic verification with consensus logic: + * - When 2+ different users submit leaks for the same request + * - Groups similar leak texts (85%+ similarity threshold) + * - Finds the largest group of matching submissions + * - Verifies the first leak from that consensus group + * - Ensures the correct prompt is verified even if wrong ones are submitted first + * - The request is automatically closed upon verification + * + * Returns a result object with success status and error message if validation fails. + * This prevents "Uncaught" errors in the terminal logs. + */ +export const insertLeak = mutation({ + args: { + targetName: v.string(), + provider: v.string(), + leakText: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + requestId: v.optional(v.id("requests")), + requiresLogin: v.optional(v.boolean()), + isPaid: v.optional(v.boolean()), + hasToolPrompts: v.optional(v.boolean()), + accessNotes: v.optional(v.string()), + leakContext: v.optional(v.string()), + url: v.optional(v.string()), + }, + returns: v.union( + v.object({ + success: v.literal(true), + leakId: v.id("leaks"), + verified: v.boolean(), + message: v.optional(v.string()), + }), + v.object({ + success: v.literal(false), + error: v.string(), + }), + ), + handler: async (ctx, args) => { + const userId = await getAuthUserId(ctx); + if (userId === null) { + return { + success: false as const, + error: "You must be logged in to submit a leak", + }; + } + + // Validate required fields + if (!args.targetName || !args.provider || !args.leakText) { + return { + success: false as const, + error: "Target name, provider, and leak text are required", + }; + } + + // If this is for a request, check if user already submitted a leak for it + if (args.requestId) { + const request = await ctx.db.get(args.requestId); + if (!request) { + return { + success: false as const, + error: "Request not found", + }; + } + + // Check if user already submitted a leak for this request + const existingLeaks: Array> = request.leaks || []; + for (const existingLeakId of existingLeaks) { + const existingLeak = await ctx.db.get(existingLeakId); + if (existingLeak && existingLeak.submittedBy === userId) { + return { + success: false as const, + error: + "You have already submitted a leak for this request. Each user can only submit once per request.", + }; + } + } + } + + // Insert the leak (always starts as unverified) + const leakId = await ctx.db.insert("leaks", { + targetName: args.targetName, + provider: args.provider, + leakText: args.leakText, + targetType: args.targetType, + isFullyVerified: false, // Always start as unverified + requestId: args.requestId, + requiresLogin: args.requiresLogin, + isPaid: args.isPaid, + hasToolPrompts: args.hasToolPrompts, + accessNotes: args.accessNotes, + leakContext: args.leakContext, + url: args.url, + submittedBy: userId, + }); + + // Update user's leaks array + const user = await ctx.db.get(userId); + if (user) { + const currentLeaks = user.leaks || []; + await ctx.db.patch(userId, { + leaks: [...currentLeaks, leakId], + }); + } + + let verified = false; + let message: string | undefined = undefined; + + // If linked to a request, add to request's leaks array + if (args.requestId) { + const request = await ctx.db.get(args.requestId); + if (request) { + const updatedLeaks = [...(request.leaks ?? []), leakId]; + + // Update request with new leak + await ctx.db.patch(args.requestId, { + leaks: updatedLeaks, + }); + + await ctx.scheduler.runAfter( + 0, + internal.leaks.processRequestConsensus, + { + requestId: args.requestId, + }, + ); + + message = `Leak submitted successfully! This request now has ${updatedLeaks.length} submissions. We'll verify once consensus is reached.`; + } + } + + return { + success: true as const, + leakId, + verified, + message, + }; + }, +}); + +/** + * Internal query to fetch the data needed for consensus evaluation. + * Kept lightweight so the heavy similarity math runs inside an action. + */ +export const getRequestConsensusData = internalQuery({ + args: { + requestId: v.id("requests"), + }, + returns: v.union( + v.null(), + v.object({ + closed: v.optional(v.boolean()), + submittedBy: v.optional(v.id("users")), + leaks: v.array( + v.object({ + leakId: v.id("leaks"), + leakText: v.string(), + submittedBy: v.optional(v.id("users")), + isFullyVerified: v.boolean(), + }), + ), + }), + ), + handler: async (ctx, args) => { + const request = await ctx.db.get(args.requestId); + if (!request) { + return null; + } + + const leakDetails: Array<{ + leakId: Id<"leaks">; + leakText: string; + submittedBy?: Id<"users">; + isFullyVerified: boolean; + }> = []; + + const leakIds: Array> = request.leaks || []; + for (const leakId of leakIds) { + const leak = await ctx.db.get(leakId); + if (leak) { + leakDetails.push({ + leakId, + leakText: leak.leakText, + submittedBy: leak.submittedBy, + isFullyVerified: leak.isFullyVerified, + }); + } + } + + return { + closed: request.closed ?? false, + submittedBy: request.submittedBy, + leaks: leakDetails, + }; + }, +}); + +/** + * Action that runs the consensus logic outside the 1s / 64MB mutation limits. + * It pulls the necessary data via internal queries and applies results through + * mutations to keep database access transactional. + */ +export const processRequestConsensus = internalAction({ + args: { + requestId: v.id("requests"), + }, + returns: v.null(), + handler: async (ctx, args) => { + const data = await ctx.runQuery(internal.leaks.getRequestConsensusData, { + requestId: args.requestId, + }); + + if (!data || data.closed) { + return null; + } + + const leakDetails = data.leaks.filter( + ( + detail, + ): detail is { + leakId: Id<"leaks">; + leakText: string; + submittedBy: Id<"users">; + isFullyVerified: boolean; + } => !!detail.submittedBy && !detail.isFullyVerified, + ); + + if (leakDetails.length < 2) { + return null; + } + + const submitters = new Set>(); + for (const detail of leakDetails) { + submitters.add(detail.submittedBy); + } + + if (submitters.size < 2) { + return null; + } + + const SIMILARITY_THRESHOLD = 0.85; + const similarityGroups: Array<{ + leakIds: Array>; + userIds: Array>; + representativeText: string; + }> = []; + + for (const detail of leakDetails) { + let addedToGroup = false; + + for (const group of similarityGroups) { + const similarity = calculateSimilarity( + group.representativeText, + detail.leakText, + ); + + if (similarity >= SIMILARITY_THRESHOLD) { + if (!group.userIds.includes(detail.submittedBy)) { + group.leakIds.push(detail.leakId); + group.userIds.push(detail.submittedBy); + } + addedToGroup = true; + break; + } + } + + if (!addedToGroup) { + similarityGroups.push({ + leakIds: [detail.leakId], + userIds: [detail.submittedBy], + representativeText: detail.leakText, + }); + } + } + + let largestGroup: (typeof similarityGroups)[0] | null = null; + for (const group of similarityGroups) { + if ( + group.userIds.length >= 2 && + (!largestGroup || group.userIds.length > largestGroup.userIds.length) + ) { + largestGroup = group; + } + } + + if (!largestGroup) { + return null; + } + + const leakToVerifyId = largestGroup.leakIds[0]; + const leakToVerify = leakDetails.find( + (detail) => detail.leakId === leakToVerifyId, + ); + + if (!leakToVerify) { + return null; + } + + const verifierIds: Array> = []; + for (const userId of largestGroup.userIds) { + if (userId !== leakToVerify.submittedBy) { + verifierIds.push(userId); + } + } + + if (verifierIds.length === 0) { + return null; + } + + await ctx.runMutation(internal.leaks.applyConsensusResult, { + requestId: args.requestId, + leakId: leakToVerify.leakId, + verifierIds, + }); + + return null; + }, +}); + +/** + * Mutation invoked by the consensus action to persist verification results + * transactionally and award points. + */ +export const applyConsensusResult = internalMutation({ + args: { + requestId: v.id("requests"), + leakId: v.id("leaks"), + verifierIds: v.array(v.id("users")), + }, + returns: v.null(), + handler: async (ctx, args) => { + const request = await ctx.db.get(args.requestId); + if (!request || request.closed) { + return null; + } + + const leak = await ctx.db.get(args.leakId); + if (!leak || leak.isFullyVerified || !leak.submittedBy) { + return null; + } + + await ctx.db.patch(args.leakId, { + isFullyVerified: true, + verifiedBy: args.verifierIds, + }); + + await ctx.db.patch(args.requestId, { + closed: true, + }); + + const submitter = await ctx.db.get(leak.submittedBy); + if (submitter) { + await ctx.db.patch(leak.submittedBy, { + points: (submitter.points ?? 0) + 100, + }); + } + + for (const verifierId of args.verifierIds) { + const verifier = await ctx.db.get(verifierId); + if (verifier) { + await ctx.db.patch(verifierId, { + points: (verifier.points ?? 0) + 50, + }); + } + } + + if (request.submittedBy) { + const requestCreator = await ctx.db.get(request.submittedBy); + if (requestCreator) { + await ctx.db.patch(request.submittedBy, { + points: (requestCreator.points ?? 0) + 20, + }); + } + } + + return null; + }, +}); + +/** + * Internal mutation to insert a fully verified leak directly. + * This bypasses the verification workflow and is used for importing + * leaks from trusted sources like GitHub repositories. + * + * Only accessible internally - cannot be called from client code. + */ +export const insertVerifiedLeak = internalMutation({ + args: { + targetName: v.string(), + provider: v.string(), + leakText: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + requiresLogin: v.optional(v.boolean()), + isPaid: v.optional(v.boolean()), + hasToolPrompts: v.optional(v.boolean()), + accessNotes: v.optional(v.string()), + leakContext: v.optional(v.string()), + url: v.optional(v.string()), + }, + returns: v.id("leaks"), + handler: async (ctx, args) => { + // Insert the leak as fully verified + const leakId = await ctx.db.insert("leaks", { + targetName: args.targetName, + provider: args.provider, + leakText: args.leakText, + targetType: args.targetType, + isFullyVerified: true, // Directly verified + requiresLogin: args.requiresLogin, + isPaid: args.isPaid, + hasToolPrompts: args.hasToolPrompts, + accessNotes: args.accessNotes, + leakContext: args.leakContext, + url: args.url, + // No submittedBy since it's an automated import + // No requestId since it's not linked to a request + }); + + return leakId; + }, +}); + +/** + * Get all verified leaks from the database. + * Returns an array of leak documents that have been fully verified. + * Includes the names of users who verified each leak. + */ +export const getVerifiedLeaks = query({ + args: {}, + returns: v.array( + v.object({ + _id: v.id("leaks"), + _creationTime: v.number(), + requiresLogin: v.optional(v.boolean()), + isPaid: v.optional(v.boolean()), + hasToolPrompts: v.optional(v.boolean()), + accessNotes: v.optional(v.string()), + leakText: v.string(), + leakContext: v.optional(v.string()), + url: v.optional(v.string()), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetName: v.string(), + provider: v.string(), + submittedBy: v.optional(v.id("users")), + verifiedBy: v.optional(v.array(v.id("users"))), + isFullyVerified: v.boolean(), + requestId: v.optional(v.id("requests")), + submitterName: v.optional(v.string()), + verifierNames: v.optional(v.array(v.string())), + }), + ), + handler: async (ctx) => { + // Use index for efficient lookup of verified leaks (avoids full table scan) + const leaks = await ctx.db + .query("leaks") + .withIndex("by_isFullyVerified", (q) => q.eq("isFullyVerified", true)) + .collect(); + + // Fetch submitter and verifier names + const leaksWithNames: Array<{ + _id: Id<"leaks">; + _creationTime: number; + requiresLogin?: boolean; + isPaid?: boolean; + hasToolPrompts?: boolean; + accessNotes?: string; + leakText: string; + leakContext?: string; + url?: string; + targetType: "model" | "app" | "tool" | "agent" | "plugin" | "custom"; + targetName: string; + provider: string; + submittedBy?: Id<"users">; + verifiedBy?: Array>; + isFullyVerified: boolean; + requestId?: Id<"requests">; + submitterName?: string; + verifierNames?: Array; + }> = []; + + for (const leak of leaks) { + let submitterName: string | undefined = undefined; + let verifierNames: Array | undefined = undefined; + + // Get submitter name if exists + if (leak.submittedBy) { + const submitter = await ctx.db.get(leak.submittedBy); + submitterName = submitter?.name || "Unknown"; + } + + // Get verifier names if exists + if (leak.verifiedBy && leak.verifiedBy.length > 0) { + verifierNames = []; + for (const verifierId of leak.verifiedBy) { + const verifier = await ctx.db.get(verifierId); + if (verifier) { + verifierNames.push(verifier.name); + } + } + } + + leaksWithNames.push({ + ...leak, + submitterName, + verifierNames, + }); + } + + return leaksWithNames; + }, +}); + +/** + * Get all unverified leaks from the database. + * Returns an array of leak documents that are awaiting verification. + */ +export const getUnverifiedLeaks = query({ + args: {}, + returns: v.array( + v.object({ + _id: v.id("leaks"), + _creationTime: v.number(), + requiresLogin: v.optional(v.boolean()), + isPaid: v.optional(v.boolean()), + hasToolPrompts: v.optional(v.boolean()), + accessNotes: v.optional(v.string()), + leakText: v.string(), + leakContext: v.optional(v.string()), + url: v.optional(v.string()), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetName: v.string(), + provider: v.string(), + submittedBy: v.optional(v.id("users")), + verifiedBy: v.optional(v.array(v.id("users"))), + isFullyVerified: v.boolean(), + requestId: v.optional(v.id("requests")), + }), + ), + handler: async (ctx) => { + // Use index for efficient lookup of unverified leaks (avoids full table scan) + const leaks = await ctx.db + .query("leaks") + .withIndex("by_isFullyVerified", (q) => q.eq("isFullyVerified", false)) + .collect(); + return leaks; + }, +}); + +/** + * Get all unique providers with their leak counts and sample leaks. + * Returns an array of provider info objects grouped by provider name. + * Includes: provider name, total leak count, target types, and sample target names. + */ +export const getProviders = query({ + args: {}, + returns: v.array( + v.object({ + provider: v.string(), + leakCount: v.number(), + targetTypes: v.array(v.string()), + sampleTargets: v.array(v.string()), + latestLeakTime: v.number(), + }), + ), + handler: async (ctx) => { + // Use index for efficient lookup of verified leaks (avoids full table scan) + const leaks = await ctx.db + .query("leaks") + .withIndex("by_isFullyVerified", (q) => q.eq("isFullyVerified", true)) + .collect(); + + // Group leaks by provider + const providerMap = new Map< + string, + { + leaks: typeof leaks; + targetTypes: Set; + targetNames: Set; + latestTime: number; + } + >(); + + for (const leak of leaks) { + const existing = providerMap.get(leak.provider); + if (existing) { + existing.leaks.push(leak); + existing.targetTypes.add(leak.targetType); + existing.targetNames.add(leak.targetName); + existing.latestTime = Math.max(existing.latestTime, leak._creationTime); + } else { + providerMap.set(leak.provider, { + leaks: [leak], + targetTypes: new Set([leak.targetType]), + targetNames: new Set([leak.targetName]), + latestTime: leak._creationTime, + }); + } + } + + // Convert to array of provider info + const providers: Array<{ + provider: string; + leakCount: number; + targetTypes: string[]; + sampleTargets: string[]; + latestLeakTime: number; + }> = []; + + for (const [provider, data] of providerMap.entries()) { + providers.push({ + provider, + leakCount: data.leaks.length, + targetTypes: Array.from(data.targetTypes), + sampleTargets: Array.from(data.targetNames).slice(0, 5), // Get up to 5 sample target names + latestLeakTime: data.latestTime, + }); + } + + // Sort by leak count (descending) + providers.sort((a, b) => b.leakCount - a.leakCount); + + return providers; + }, +}); + +/** + * Get all verified leaks for a specific provider. + * Returns an array of leak documents with submitter and verifier names. + */ +export const getLeaksByProvider = query({ + args: { + provider: v.string(), + }, + returns: v.array( + v.object({ + _id: v.id("leaks"), + _creationTime: v.number(), + requiresLogin: v.optional(v.boolean()), + isPaid: v.optional(v.boolean()), + hasToolPrompts: v.optional(v.boolean()), + accessNotes: v.optional(v.string()), + leakText: v.string(), + leakContext: v.optional(v.string()), + url: v.optional(v.string()), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetName: v.string(), + provider: v.string(), + submittedBy: v.optional(v.id("users")), + verifiedBy: v.optional(v.array(v.id("users"))), + isFullyVerified: v.boolean(), + requestId: v.optional(v.id("requests")), + submitterName: v.optional(v.string()), + verifierNames: v.optional(v.array(v.string())), + }), + ), + handler: async (ctx, args) => { + // Use compound index for efficient lookup by provider + verification status + // This is much faster than filter() as it uses the index directly + const leaks = await ctx.db + .query("leaks") + .withIndex("by_provider_and_verified", (q) => + q.eq("provider", args.provider).eq("isFullyVerified", true), + ) + .collect(); + + // Fetch submitter and verifier names + const leaksWithNames: Array<{ + _id: Id<"leaks">; + _creationTime: number; + requiresLogin?: boolean; + isPaid?: boolean; + hasToolPrompts?: boolean; + accessNotes?: string; + leakText: string; + leakContext?: string; + url?: string; + targetType: "model" | "app" | "tool" | "agent" | "plugin" | "custom"; + targetName: string; + provider: string; + submittedBy?: Id<"users">; + verifiedBy?: Array>; + isFullyVerified: boolean; + requestId?: Id<"requests">; + submitterName?: string; + verifierNames?: Array; + }> = []; + + for (const leak of leaks) { + let submitterName: string | undefined = undefined; + let verifierNames: Array | undefined = undefined; + + // Get submitter name if exists + if (leak.submittedBy) { + const submitter = await ctx.db.get(leak.submittedBy); + submitterName = submitter?.name || "Unknown"; + } + + // Get verifier names if exists + if (leak.verifiedBy && leak.verifiedBy.length > 0) { + verifierNames = []; + for (const verifierId of leak.verifiedBy) { + const verifier = await ctx.db.get(verifierId); + if (verifier) { + verifierNames.push(verifier.name); + } + } + } + + leaksWithNames.push({ + ...leak, + submitterName, + verifierNames, + }); + } + + // Sort by creation time (newest first) + leaksWithNames.sort((a, b) => b._creationTime - a._creationTime); + + return leaksWithNames; + }, +}); diff --git a/convex/requests.ts b/convex/requests.ts new file mode 100644 index 0000000..fc568aa --- /dev/null +++ b/convex/requests.ts @@ -0,0 +1,417 @@ +import { v } from "convex/values"; +import { getAuthUserId } from "@convex-dev/auth/server"; +import { query, mutation } from "./_generated/server"; +import { Id } from "./_generated/dataModel"; + +/** + * Get all open (non-closed) requests from the database. + * Returns requests with submitter names populated. + */ +export const getOpenRequests = query({ + args: {}, + returns: v.array( + v.object({ + _id: v.id("requests"), + _creationTime: v.number(), + targetName: v.string(), + provider: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetUrl: v.string(), + closed: v.boolean(), + submittedBy: v.id("users"), + submitterName: v.string(), + leaks: v.array(v.id("leaks")), + }), + ), + handler: async (ctx) => { + const requests = await ctx.db + .query("requests") + .withIndex("by_closed", (q) => q.eq("closed", false)) + .order("desc") + .collect(); + + // Fetch submitter names + const requestsWithNames: Array<{ + _id: Id<"requests">; + _creationTime: number; + targetName: string; + provider: string; + targetType: "model" | "app" | "tool" | "agent" | "plugin" | "custom"; + targetUrl: string; + closed: boolean; + submittedBy: Id<"users">; + submitterName: string; + leaks: Array>; + }> = []; + + for (const request of requests) { + const user = await ctx.db.get(request.submittedBy); + requestsWithNames.push({ + ...request, + submitterName: user?.name || "Unknown", + }); + } + + return requestsWithNames; + }, +}); + +/** + * Get all open requests for a specific user. + * Returns only requests that belong to the specified user and are not closed. + */ +export const getUserOpenRequests = query({ + args: { + userId: v.id("users"), + }, + returns: v.array( + v.object({ + _id: v.id("requests"), + _creationTime: v.number(), + targetName: v.string(), + provider: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetUrl: v.string(), + closed: v.boolean(), + submittedBy: v.id("users"), + leaks: v.array(v.id("leaks")), + }), + ), + handler: async (ctx, args) => { + const requests = await ctx.db + .query("requests") + .withIndex("by_submittedBy_and_closed", (q) => + q.eq("submittedBy", args.userId).eq("closed", false), + ) + .order("desc") + .collect(); + return requests; + }, +}); + +/** + * Create a new request for a leak target. + * Validates that: + * - User is authenticated + * - No duplicate request exists (case-insensitive) + * - User has less than 3 open requests + * + * Returns a result object with success status and error message if validation fails. + * This prevents "Uncaught" errors in the terminal logs. + */ +export const createRequest = mutation({ + args: { + targetName: v.string(), + provider: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetUrl: v.string(), + }, + returns: v.union( + v.object({ + success: v.literal(true), + requestId: v.id("requests"), + }), + v.object({ + success: v.literal(false), + error: v.string(), + }), + ), + handler: async (ctx, args) => { + const userId = await getAuthUserId(ctx); + if (userId === null) { + return { + success: false as const, + error: "You must be logged in to create a request", + }; + } + + // Check if a request with the same target name already exists (case-insensitive) + // Query ALL requests, not just open ones + const allRequests = await ctx.db.query("requests").collect(); + const normalizedTargetName = args.targetName.toLowerCase().trim(); + + const existingRequest = allRequests.find( + (req) => req.targetName.toLowerCase().trim() === normalizedTargetName, + ); + + if (existingRequest) { + return { + success: false as const, + error: `A request for "${existingRequest.targetName}" has already been made. Please search for it in the existing requests.`, + }; + } + + // Check if user already has 3 or more open requests + const userOpenRequests = await ctx.db + .query("requests") + .withIndex("by_submittedBy_and_closed", (q) => + q.eq("submittedBy", userId).eq("closed", false), + ) + .collect(); + + if (userOpenRequests.length >= 3) { + return { + success: false as const, + error: + "You have reached the maximum limit of 3 open requests. Please wait for some to be fulfilled before creating more.", + }; + } + + const requestId = await ctx.db.insert("requests", { + targetName: args.targetName, + provider: args.provider.toUpperCase(), // Convert provider to uppercase for consistency + targetType: args.targetType, + targetUrl: args.targetUrl, + closed: false, + leaks: [], + submittedBy: userId, + }); + + // Update user's requests array + const user = await ctx.db.get(userId); + if (user) { + const currentRequests = user.requests || []; + await ctx.db.patch(userId, { + requests: [...currentRequests, requestId], + }); + } + + return { success: true as const, requestId }; + }, +}); + +/** + * Close a request (mark it as closed). + * Only the owner of the request can close it. + * Validates that: + * - User is authenticated + * - Request exists + * - User owns the request + * - Request is not already closed + * + * Returns a result object with success status and error message if validation fails. + * This prevents "Uncaught" errors in the terminal logs. + */ +export const closeRequest = mutation({ + args: { + requestId: v.id("requests"), + }, + returns: v.union( + v.object({ + success: v.literal(true), + }), + v.object({ + success: v.literal(false), + error: v.string(), + }), + ), + handler: async (ctx, args) => { + const userId = await getAuthUserId(ctx); + if (userId === null) { + return { + success: false as const, + error: "You must be logged in to close a request", + }; + } + + // Get the request to verify ownership + const request = await ctx.db.get(args.requestId); + if (!request) { + return { + success: false as const, + error: "Request not found", + }; + } + + // Check if the user is the owner of the request + if (request.submittedBy !== userId) { + return { + success: false as const, + error: "You can only close your own requests", + }; + } + + // Check if the request is already closed + if (request.closed) { + return { + success: false as const, + error: "Request is already closed", + }; + } + + // Close the request + await ctx.db.patch(args.requestId, { + closed: true, + }); + + return { success: true as const }; + }, +}); + +/** + * Search for existing requests by target name. + * Uses full-text search to find matching requests. + * Only returns open (non-closed) requests. + * Returns up to 10 results. + */ +export const searchRequests = query({ + args: { + searchQuery: v.string(), + }, + returns: v.array( + v.object({ + _id: v.id("requests"), + _creationTime: v.number(), + targetName: v.string(), + provider: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetUrl: v.string(), + closed: v.boolean(), + submittedBy: v.id("users"), + submitterName: v.string(), + leaks: v.array(v.id("leaks")), + }), + ), + handler: async (ctx, args) => { + if (!args.searchQuery || args.searchQuery.trim() === "") { + return []; + } + + const requests = await ctx.db + .query("requests") + .withSearchIndex("search_targetName", (q) => + q.search("targetName", args.searchQuery).eq("closed", false), + ) + .take(10); + + const requestsWithNames: Array<{ + _id: Id<"requests">; + _creationTime: number; + targetName: string; + provider: string; + targetType: "model" | "app" | "tool" | "agent" | "plugin" | "custom"; + targetUrl: string; + closed: boolean; + submittedBy: Id<"users">; + submitterName: string; + leaks: Array>; + }> = []; + + for (const request of requests) { + const user = await ctx.db.get(request.submittedBy); + requestsWithNames.push({ + ...request, + submitterName: user?.name || "Unknown", + }); + } + + return requestsWithNames; + }, +}); + +/** + * Get all open requests with their verification status. + * Returns requests with: + * - Request information + * - Number of leak confirmations + * - Number of unique submitters + * - Submitter name + */ +export const getRequestsWithVerificationStatus = query({ + args: {}, + returns: v.array( + v.object({ + _id: v.id("requests"), + _creationTime: v.number(), + targetName: v.string(), + provider: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetUrl: v.string(), + closed: v.boolean(), + submittedBy: v.id("users"), + submitterName: v.string(), + leaks: v.array(v.id("leaks")), + confirmationCount: v.number(), + uniqueSubmitters: v.number(), + }), + ), + handler: async (ctx) => { + const requests = await ctx.db + .query("requests") + .withIndex("by_closed", (q) => q.eq("closed", false)) + .order("desc") + .collect(); + + const requestsWithStatus: Array<{ + _id: Id<"requests">; + _creationTime: number; + targetName: string; + provider: string; + targetType: "model" | "app" | "tool" | "agent" | "plugin" | "custom"; + targetUrl: string; + closed: boolean; + submittedBy: Id<"users">; + submitterName: string; + leaks: Array>; + confirmationCount: number; + uniqueSubmitters: number; + }> = []; + + for (const request of requests) { + const user = await ctx.db.get(request.submittedBy); + + // Calculate unique submitters + const submitters = new Set>(); + for (const leakId of request.leaks) { + const leak = await ctx.db.get(leakId); + if (leak && leak.submittedBy) { + submitters.add(leak.submittedBy); + } + } + + requestsWithStatus.push({ + ...request, + submitterName: user?.name || "Unknown", + confirmationCount: request.leaks.length, + uniqueSubmitters: submitters.size, + }); + } + + return requestsWithStatus; + }, +}); diff --git a/convex/schema.ts b/convex/schema.ts new file mode 100644 index 0000000..dda21dd --- /dev/null +++ b/convex/schema.ts @@ -0,0 +1,77 @@ +import { defineSchema, defineTable } from "convex/server"; +import { v } from "convex/values"; +import { authTables } from "@convex-dev/auth/server"; + +const leaks = defineTable({ + requiresLogin: v.optional(v.boolean()), + isPaid: v.optional(v.boolean()), + hasToolPrompts: v.optional(v.boolean()), + accessNotes: v.optional(v.string()), + leakText: v.string(), + leakContext: v.optional(v.string()), + url: v.optional(v.string()), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetName: v.string(), + provider: v.string(), + submittedBy: v.optional(v.id("users")), + verifiedBy: v.optional(v.array(v.id("users"))), + isFullyVerified: v.boolean(), + requestId: v.optional(v.id("requests")), +}) + // Index for filtering by verification status (used in getVerifiedLeaks, getUnverifiedLeaks) + .index("by_isFullyVerified", ["isFullyVerified"]) + // Compound index for filtering verified leaks by provider (used in getLeaksByProvider, getProviders) + .index("by_provider_and_verified", ["provider", "isFullyVerified"]); + +const requests = defineTable({ + targetName: v.string(), + provider: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + targetUrl: v.string(), + closed: v.boolean(), + leaks: v.array(v.id("leaks")), + submittedBy: v.id("users"), +}) + .index("by_closed", ["closed"]) + .index("by_submittedBy_and_closed", ["submittedBy", "closed"]) + .searchIndex("search_targetName", { + searchField: "targetName", + filterFields: ["closed"], + }); + +const users = defineTable({ + name: v.string(), + image: v.string(), + email: v.string(), + requests: v.optional(v.array(v.id("requests"))), + leaks: v.optional(v.array(v.id("leaks"))), + points: v.number(), // TODO: Add points system + // Links to the auth tables - this will be set automatically by Convex Auth + // when a user signs in +}) + .index("email", ["email"]) + .index("by_points", ["points"]); + +// The schema is normally optional, but Convex Auth +// requires indexes defined on `authTables`. +// The schema provides more precise TypeScript types. +export default defineSchema({ + ...authTables, + leaks, + requests, + users, +}); diff --git a/convex/tsconfig.json b/convex/tsconfig.json new file mode 100644 index 0000000..6fa874e --- /dev/null +++ b/convex/tsconfig.json @@ -0,0 +1,25 @@ +{ + /* This TypeScript project config describes the environment that + * Convex functions run in and is used to typecheck them. + * You can modify it, but some settings required to use Convex. + */ + "compilerOptions": { + /* These settings are not required by Convex and can be modified. */ + "allowJs": true, + "strict": true, + "moduleResolution": "Bundler", + "jsx": "react-jsx", + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + + /* These compiler options are required by Convex */ + "target": "ESNext", + "lib": ["ES2021", "dom"], + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "isolatedModules": true, + "noEmit": true + }, + "include": ["./**/*"], + "exclude": ["./_generated"] +} diff --git a/convex/users.ts b/convex/users.ts new file mode 100644 index 0000000..44dd471 --- /dev/null +++ b/convex/users.ts @@ -0,0 +1,181 @@ +import { v } from "convex/values"; +import { getAuthUserId } from "@convex-dev/auth/server"; +import { query } from "./_generated/server"; +import { Id } from "./_generated/dataModel"; + +/** + * Get the current user's information including their image. + * Returns null if the user is not authenticated. + */ +export const currentUser = query({ + args: {}, + returns: v.union( + v.object({ + _id: v.id("users"), + _creationTime: v.number(), + name: v.string(), + image: v.string(), + email: v.string(), + points: v.number(), + requests: v.optional(v.array(v.id("requests"))), + leaks: v.optional(v.array(v.id("leaks"))), + }), + v.null(), + ), + handler: async (ctx) => { + const userId = await getAuthUserId(ctx); + if (userId === null) { + return null; + } + const user = await ctx.db.get(userId); + return user; + }, +}); + +/** + * Get comprehensive dashboard data for a specific user including: + * - User profile information + * - Points and rank + * - User's leaks + * - User's requests + */ +export const getUserDashboardData = query({ + args: { + userId: v.id("users"), + }, + returns: v.union( + v.object({ + name: v.string(), + email: v.string(), + points: v.number(), + rank: v.number(), + totalUsers: v.number(), + leaks: v.array( + v.object({ + _id: v.id("leaks"), + _creationTime: v.number(), + targetName: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + provider: v.string(), + isFullyVerified: v.boolean(), + requestId: v.optional(v.id("requests")), + }), + ), + requests: v.array( + v.object({ + _id: v.id("requests"), + _creationTime: v.number(), + targetName: v.string(), + targetType: v.union( + v.literal("model"), + v.literal("app"), + v.literal("tool"), + v.literal("agent"), + v.literal("plugin"), + v.literal("custom"), + ), + provider: v.string(), + closed: v.boolean(), + targetUrl: v.optional(v.string()), + }), + ), + }), + v.null(), + ), + handler: async (ctx, args) => { + const user = await ctx.db.get(args.userId); + if (!user) { + return null; + } + + // Calculate user's rank based on points + const usersQuery = ctx.db + .query("users") + .withIndex("by_points") + .order("desc"); + + let rank = 0; + let totalUsers = 0; + let userRank = 0; + + for await (const u of usersQuery) { + rank += 1; + totalUsers += 1; + if (u._id === args.userId) { + userRank = rank; + } + } + + // Fetch full leak documents + const leakDocs: Array<{ + _id: Id<"leaks">; + _creationTime: number; + targetName: string; + targetType: "model" | "app" | "tool" | "agent" | "plugin" | "custom"; + provider: string; + isFullyVerified: boolean; + requestId?: Id<"requests">; + }> = []; + if (user.leaks) { + for (const leakId of user.leaks) { + const leak = await ctx.db.get(leakId); + if (leak) { + leakDocs.push({ + _id: leak._id, + _creationTime: leak._creationTime, + targetName: leak.targetName, + targetType: leak.targetType, + provider: leak.provider, + isFullyVerified: leak.isFullyVerified, + requestId: leak.requestId, + }); + } + } + } + + // Fetch full request documents + const requestDocs: Array<{ + _id: Id<"requests">; + _creationTime: number; + targetName: string; + targetType: "model" | "app" | "tool" | "agent" | "plugin" | "custom"; + provider: string; + closed: boolean; + targetUrl?: string; + }> = []; + if (user.requests) { + for (const requestId of user.requests) { + const request = await ctx.db.get(requestId); + if (request) { + requestDocs.push({ + _id: request._id, + _creationTime: request._creationTime, + targetName: request.targetName, + targetType: request.targetType, + provider: request.provider, + closed: request.closed, + targetUrl: request.targetUrl, + }); + } + } + } + + return { + name: user.name, + email: user.email, + points: user.points, + rank: userRank, + totalUsers: totalUsers, + leaks: leakDocs, + requests: requestDocs, + }; + }, +}); + diff --git a/demo-data.js b/demo-data.js deleted file mode 100644 index 4b509e0..0000000 --- a/demo-data.js +++ /dev/null @@ -1,366 +0,0 @@ -// Demo data for LeakHub - Sample submissions to showcase the platform -// Run this in the browser console to populate with demo data - -const demoSubmissions = [ - { - id: "demo1", - source: "DemoUser1", - targetType: "model", - instance: "GPT-4", - targetUrl: "https://chat.openai.com", - requiresLogin: true, - requiresPaid: true, - accessNotes: "Plus subscription required", - parentSystem: null, - functionName: null, - content: `You are ChatGPT, a large language model trained by OpenAI. You are designed to be helpful, harmless, and honest in your responses. - -Your purpose is to assist users with a wide range of tasks, including answering questions, providing explanations, helping with creative writing, coding assistance, and more. - -Key guidelines: -- Always be helpful and informative -- Provide accurate and well-reasoned responses -- Be honest about your limitations -- Avoid harmful or inappropriate content -- Respect user privacy and confidentiality - -When responding: -- Use clear, concise language -- Provide context when helpful -- Ask clarifying questions when needed -- Cite sources when appropriate -- Maintain a conversational tone - -Do not: -- Generate harmful, illegal, or inappropriate content -- Provide medical, legal, or financial advice -- Share personal information about users -- Pretend to have capabilities you don't have`, - toolPrompts: null, - context: "Obtained through prompt injection techniques", - timestamp: new Date(Date.now() - 86400000).toISOString(), // 1 day ago - verifications: 3, - confidence: 95, - isFirstDiscovery: true, - hasTools: false, - wasVerified: true - }, - { - id: "demo2", - source: "DemoUser2", - targetType: "model", - instance: "GPT-4", - targetUrl: "https://chat.openai.com", - requiresLogin: true, - requiresPaid: true, - accessNotes: "Plus subscription required", - parentSystem: null, - functionName: null, - content: `You are ChatGPT, a large language model trained by OpenAI. Your role is to be helpful, harmless, and honest in all interactions. - -Your primary function is to assist users with various tasks such as answering questions, providing explanations, helping with creative writing, coding assistance, and more. - -Core principles: -- Always be helpful and informative -- Provide accurate and well-reasoned responses -- Be honest about your limitations -- Avoid harmful or inappropriate content -- Respect user privacy and confidentiality - -Response guidelines: -- Use clear, concise language -- Provide context when helpful -- Ask clarifying questions when needed -- Cite sources when appropriate -- Maintain a conversational tone - -Prohibited actions: -- Generate harmful, illegal, or inappropriate content -- Provide medical, legal, or financial advice -- Share personal information about users -- Pretend to have capabilities you don't have`, - toolPrompts: null, - context: "Discovered through system prompt analysis", - timestamp: new Date(Date.now() - 43200000).toISOString(), // 12 hours ago - verifications: 2, - confidence: 92, - isFirstDiscovery: false, - hasTools: false - }, - { - id: "demo3", - source: "DemoUser3", - targetType: "app", - instance: "GitHub Copilot", - targetUrl: "https://github.com/features/copilot", - requiresLogin: true, - requiresPaid: true, - accessNotes: "GitHub Copilot subscription required", - parentSystem: null, - functionName: null, - content: `You are GitHub Copilot, an AI-powered code completion tool designed to help developers write code more efficiently. - -Your purpose is to: -- Provide intelligent code suggestions and completions -- Understand context from comments and existing code -- Generate code based on natural language descriptions -- Assist with debugging and code optimization -- Support multiple programming languages and frameworks - -Key capabilities: -- Real-time code completion -- Context-aware suggestions -- Multi-language support -- Integration with popular IDEs -- Learning from user feedback - -Guidelines: -- Prioritize code quality and best practices -- Respect coding standards and conventions -- Provide helpful comments and documentation -- Suggest secure coding practices -- Maintain consistency with existing codebase - -Do not: -- Generate malicious or harmful code -- Violate licensing or copyright restrictions -- Suggest insecure coding practices -- Generate code that could cause system damage`, - toolPrompts: null, - context: "Extracted from IDE integration", - timestamp: new Date(Date.now() - 21600000).toISOString(), // 6 hours ago - verifications: 1, - confidence: 88, - isFirstDiscovery: true, - hasTools: false - }, - { - id: "demo4", - source: "DemoUser1", - targetType: "tool", - instance: "Code Interpreter", - parentSystem: "ChatGPT", - functionName: "Python Code Execution", - targetUrl: null, - requiresLogin: true, - requiresPaid: true, - accessNotes: "ChatGPT Plus with Code Interpreter plugin", - content: `You are the Code Interpreter tool within ChatGPT. Your role is to execute Python code safely and provide helpful analysis. - -Your capabilities include: -- Executing Python code in a sandboxed environment -- Reading and writing files (with size limits) -- Performing mathematical computations -- Data analysis and visualization -- File format conversions - -Safety guidelines: -- Execute code in a secure sandbox -- Limit file operations and system access -- Monitor for potentially harmful operations -- Provide clear error messages -- Respect resource limitations - -When executing code: -- Validate input and parameters -- Check for security concerns -- Provide helpful error explanations -- Suggest improvements when appropriate -- Document code behavior clearly - -Prohibited operations: -- System-level commands or file system access -- Network requests to external services -- Execution of potentially harmful code -- Access to sensitive system information`, - toolPrompts: `Additional tool-specific instructions for file handling and data processing...`, - context: "Analyzed from plugin behavior", - timestamp: new Date(Date.now() - 7200000).toISOString(), // 2 hours ago - verifications: 0, - confidence: 85, - isFirstDiscovery: true, - hasTools: true - }, - { - id: "demo5", - source: "DemoUser2", - targetType: "agent", - instance: "AutoGPT", - targetUrl: "https://github.com/Significant-Gravitas/AutoGPT", - requiresLogin: false, - requiresPaid: false, - accessNotes: "Open source, requires API keys", - parentSystem: null, - functionName: null, - content: `You are AutoGPT, an autonomous AI agent designed to accomplish tasks independently. - -Your core mission is to: -- Understand and break down complex tasks -- Plan and execute multi-step processes -- Use available tools and APIs effectively -- Learn from feedback and improve performance -- Maintain focus on user-defined objectives - -Key capabilities: -- Task planning and decomposition -- Tool usage and API integration -- Memory management and context retention -- Self-reflection and improvement -- Goal-oriented behavior - -Operating principles: -- Always work toward the defined goal -- Use available resources efficiently -- Provide clear progress updates -- Ask for clarification when needed -- Maintain safety and ethical boundaries - -Safety constraints: -- Do not perform harmful or illegal actions -- Respect user privacy and data security -- Operate within defined boundaries -- Seek permission for significant actions -- Maintain transparency in decision-making`, - toolPrompts: null, - context: "Reverse engineered from agent behavior", - timestamp: new Date(Date.now() - 3600000).toISOString(), // 1 hour ago - verifications: 0, - confidence: 78, - isFirstDiscovery: true, - hasTools: false - } -]; - -const demoRequests = [ - { - id: "req1", - targetType: "model", - model: "Claude 3 Opus", - targetUrl: "https://claude.ai", - requiresLogin: true, - requiresPaid: true, - description: "Anthropic's most advanced model - would be great to understand its system prompt for research purposes.", - bounty: 1000, - requestedBy: "DemoUser1", - timestamp: new Date(Date.now() - 86400000).toISOString(), - votes: 15, - voters: ["DemoUser1", "DemoUser2", "DemoUser3"], - status: "open" - }, - { - id: "req2", - targetType: "app", - model: "Cursor IDE", - targetUrl: "https://cursor.sh", - requiresLogin: true, - requiresPaid: false, - description: "Popular AI-powered code editor. Interested in understanding how it processes code context.", - bounty: 500, - requestedBy: "DemoUser2", - timestamp: new Date(Date.now() - 43200000).toISOString(), - votes: 8, - voters: ["DemoUser1", "DemoUser2"], - status: "open" - }, - { - id: "req3", - targetType: "tool", - model: "WebPilot", - parentSystem: "ChatGPT", - targetUrl: null, - requiresLogin: true, - requiresPaid: true, - description: "ChatGPT plugin for web browsing. Want to understand how it processes web content safely.", - bounty: 300, - requestedBy: "DemoUser3", - timestamp: new Date(Date.now() - 21600000).toISOString(), - votes: 5, - voters: ["DemoUser3"], - status: "open" - } -]; - -// Function to load demo data -function loadDemoData() { - console.log("Loading demo data for LeakHub..."); - - // Load submissions - leakDatabase = [...demoSubmissions]; - - // Load requests - leakRequests = [...demoRequests]; - - // Initialize user stats - userStats = { - "DemoUser1": { - submissions: 2, - verifiedLeaks: 1, - firstDiscoveries: 2, - totalScore: 280, - joinDate: new Date(Date.now() - 86400000).toISOString(), - toolsDiscovered: 1, - appsDiscovered: 0, - agentsDiscovered: 0 - }, - "DemoUser2": { - submissions: 2, - verifiedLeaks: 0, - firstDiscoveries: 0, - totalScore: 120, - joinDate: new Date(Date.now() - 43200000).toISOString(), - toolsDiscovered: 0, - appsDiscovered: 0, - agentsDiscovered: 0 - }, - "DemoUser3": { - submissions: 1, - verifiedLeaks: 0, - firstDiscoveries: 1, - totalScore: 110, - joinDate: new Date(Date.now() - 21600000).toISOString(), - toolsDiscovered: 0, - appsDiscovered: 1, - agentsDiscovered: 0 - } - }; - - // Save to localStorage - saveDatabase(); - - // Update UI - updateUI(); - - console.log("Demo data loaded successfully! You can now explore the platform with sample submissions."); - console.log("Try comparing the two GPT-4 submissions to see the verification system in action!"); -} - -// Function to clear demo data -function clearDemoData() { - console.log("Clearing demo data..."); - - leakDatabase = []; - leakRequests = []; - userStats = {}; - userVotes = {}; - - // Clear localStorage - localStorage.removeItem('leakDatabase'); - localStorage.removeItem('userStats'); - localStorage.removeItem('leakRequests'); - localStorage.removeItem('userVotes'); - localStorage.removeItem('dailyChallenge'); - localStorage.removeItem('avgSimilarity'); - - // Update UI - updateUI(); - - console.log("Demo data cleared. Platform is now empty and ready for real submissions."); -} - -// Add functions to global scope for easy access -window.loadDemoData = loadDemoData; -window.clearDemoData = clearDemoData; - -console.log("Demo data functions loaded!"); -console.log("To load demo data, run: loadDemoData()"); -console.log("To clear demo data, run: clearDemoData()"); diff --git a/deploy.sh b/deploy.sh deleted file mode 100755 index 2fc2187..0000000 --- a/deploy.sh +++ /dev/null @@ -1,194 +0,0 @@ -#!/bin/bash - -# LeakHub Deployment Script -# This script automates the deployment process for different platforms - -set -e # Exit on any error - -echo "🚀 LeakHub Deployment Script" -echo "==============================" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Function to print colored output -print_status() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# Check if Node.js is installed -check_node() { - if ! command -v node &> /dev/null; then - print_error "Node.js is not installed. Please install Node.js 18+ first." - exit 1 - fi - - NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1) - if [ "$NODE_VERSION" -lt 18 ]; then - print_error "Node.js version 18+ is required. Current version: $(node --version)" - exit 1 - fi - - print_success "Node.js $(node --version) detected" -} - -# Install dependencies -install_deps() { - print_status "Installing dependencies..." - npm ci - print_success "Dependencies installed" -} - -# Build the project -build_project() { - print_status "Building project for production..." - npm run build - print_success "Project built successfully" -} - -# Deploy to GitHub Pages -deploy_github_pages() { - print_status "Deploying to GitHub Pages..." - - # Check if git is initialized - if [ ! -d ".git" ]; then - print_error "Git repository not found. Please initialize git first." - exit 1 - fi - - # Check if remote origin exists - if ! git remote get-url origin &> /dev/null; then - print_error "Git remote 'origin' not found. Please add your GitHub repository as origin." - exit 1 - fi - - # Add all changes - git add . - - # Commit changes - git commit -m "Deploy LeakHub - $(date)" - - # Push to main branch - git push origin main - - print_success "Deployed to GitHub Pages! Check your repository settings to enable GitHub Pages." -} - -# Deploy to Vercel -deploy_vercel() { - print_status "Deploying to Vercel..." - - # Check if Vercel CLI is installed - if ! command -v vercel &> /dev/null; then - print_warning "Vercel CLI not found. Installing..." - npm install -g vercel - fi - - # Deploy - vercel --prod - - print_success "Deployed to Vercel!" -} - -# Deploy to Netlify -deploy_netlify() { - print_status "Deploying to Netlify..." - - # Check if Netlify CLI is installed - if ! command -v netlify &> /dev/null; then - print_warning "Netlify CLI not found. Installing..." - npm install -g netlify-cli - fi - - # Deploy - netlify deploy --prod --dir=dist - - print_success "Deployed to Netlify!" -} - -# Show usage -show_usage() { - echo "Usage: $0 [OPTION]" - echo "" - echo "Options:" - echo " github Deploy to GitHub Pages" - echo " vercel Deploy to Vercel" - echo " netlify Deploy to Netlify" - echo " build Build project only" - echo " install Install dependencies only" - echo " all Deploy to all platforms" - echo " help Show this help message" - echo "" - echo "Examples:" - echo " $0 github # Deploy to GitHub Pages" - echo " $0 vercel # Deploy to Vercel" - echo " $0 all # Deploy to all platforms" -} - -# Main deployment function -main() { - case "$1" in - "github") - check_node - install_deps - build_project - deploy_github_pages - ;; - "vercel") - check_node - install_deps - build_project - deploy_vercel - ;; - "netlify") - check_node - install_deps - build_project - deploy_netlify - ;; - "build") - check_node - install_deps - build_project - ;; - "install") - check_node - install_deps - ;; - "all") - check_node - install_deps - build_project - deploy_github_pages - deploy_vercel - deploy_netlify - ;; - "help"|"-h"|"--help") - show_usage - ;; - *) - print_error "Unknown option: $1" - show_usage - exit 1 - ;; - esac -} - -# Run main function with all arguments -main "$@" diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..9710377 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,80 @@ +import { defineConfig } from "eslint/config"; +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; +import convexPlugin from "@convex-dev/eslint-plugin"; + +export default defineConfig([ + { + ignores: [ + "dist", + "eslint.config.js", + "convex/_generated", + "postcss.config.js", + "tailwind.config.js", + "vite.config.ts", + ], + }, + { + extends: [ + js.configs.recommended, + ...tseslint.configs.recommendedTypeChecked, + ], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: { + ...globals.browser, + ...globals.node, + }, + parserOptions: { + project: [ + "./tsconfig.node.json", + "./tsconfig.app.json", + "./convex/tsconfig.json", + ], + }, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + // All of these overrides ease getting into + // TypeScript, and can be removed for stricter + // linting down the line. + + // Only warn on unused variables, and ignore variables starting with `_` + "@typescript-eslint/no-unused-vars": [ + "warn", + { varsIgnorePattern: "^_", argsIgnorePattern: "^_" }, + ], + + // Allow escaping the compiler + "@typescript-eslint/ban-ts-comment": "error", + + // Allow explicit `any`s + "@typescript-eslint/no-explicit-any": "off", + + // START: Allow implicit `any`s + "@typescript-eslint/no-unsafe-argument": "off", + "@typescript-eslint/no-unsafe-assignment": "off", + "@typescript-eslint/no-unsafe-call": "off", + "@typescript-eslint/no-unsafe-member-access": "off", + "@typescript-eslint/no-unsafe-return": "off", + // END: Allow implicit `any`s + + // Allow async functions without await + // for consistency (esp. Convex `handler`s) + "@typescript-eslint/require-await": "off", + }, + }, + ...convexPlugin.configs.recommended, +]); diff --git a/index-simple.html b/index-simple.html deleted file mode 100644 index 96b313a..0000000 --- a/index-simple.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - LeakHub - AI System Prompt Discovery Platform - - - -
- - - - -
-
-
-

LeakHub

-

The community hub for crowd-sourced system prompt leak verification. CL4R1T4S!

- -
-
-
🎯
-
-
0
-
Active Targets
-
-
-
-
📊
-
-
0
-
Total Submissions
-
-
-
-
-
-
0
-
Verified Prompts
-
-
-
-
👥
-
-
0
-
Active Users
-
-
-
- -
- - - - -
-
-
- - - - - - - - - - - - - -
-
-

📤 Submit Leak

-
- - - - - - - - -
-

🔒 Access Requirements

-
- - -
- -
- - - - - - -
- - -
- - - - -
-
- -
-

📚 Leak Library

-
-

No submissions yet. Be the first to contribute!

-
-
-
- -
-
-

🔍 Compare Multiple Instances

-
- - -
-
- - -
-
-
-
-
Character Match
-
-
-
-
-
Word Match
-
-
-
-
-
Structure Match
-
-
-
-
-
Core Similarity
-
-
-
-
- -
-

Consensus View (Common Elements)

-
-
-
-
-
- -
-
-
0
-
Unique Instances
-
-
-
0%
-
Average Similarity
-
-
-
0
-
High Confidence Matches
-
-
-
- -
- - -
-
-
- -
-

🏆 LeakHub Hall of Fame

-

Recognizing the top contributors to AI transparency

-
- -
-
📊 Rankings
-
🏅 Achievements
-
📅 Timeline
-
- -
-
-

Top Contributors

-
-
-
- - - - -
-
- - -
-
-
- -
-

🎯 LeakHub Bounty Board

-

Request targets and compete in daily challenges

-
- - -
-

🎯 Today's Challenge

-

Find and verify a system prompt from GPT-4 Turbo!

-
💰 Reward: 500 bonus points + Special Badge
-
Time remaining: 23:45:30
-
- -
- -
-

📝 Request a Leak Hunt

-
- - - - -
- - -
- - -
-
- - -
-

🔥 Hot Requests

-
-
🔥 Trending
-
💰 Highest Bounty
-
🆕 Newest
-
👍 My Votes
-
-
-

No requests yet. Be the first to request a leak hunt!

-
-
-
-
-
- - - - - - diff --git a/index.html b/index.html index 99fb0b0..ca2257d 100644 --- a/index.html +++ b/index.html @@ -1,559 +1,15 @@ - + - - - - LeakHub - AI System Prompt Discovery Platform - - - -
- - - - -
-
-
-

LeakHub

-

AI System Prompt Discovery + Universal Information Validation. CL4R1T4S!

- -
-
-
🎯
-
-
0
-
Active Targets
-
-
-
-
📊
-
-
0
-
Total Submissions
-
-
-
-
-
-
0
-
Verified Prompts
-
-
-
-
👥
-
-
0
-
Active Users
-
-
-
- -
- - - - -
-
-
- - - - - - - - - - - - - - -
- -
-
-
-

🔍 Submit System Prompt Leak

-
- - - - - - - - -
-

🔒 Access Requirements

-
- - -
- -
- - - - - - -
- - -
- - - - -
-
-
-
- - -
-
-
-

✅ Submit Information for Validation

-
- - - - - - - - - - - -
- - -
- - - - -
-
- -
-

🔍 Active Validation Requests

-
-

No validation requests yet. Be the first to submit!

-
-
-
-
- - -
-
-
-

📚 Leak Library

-
-

No submissions yet. Be the first to contribute!

-
-
-
-
- - -
- -
- - -
-
-
-

👥 Community Features

-
-
-

🏆 Leaderboard

-

See top contributors and their achievements

- -
-
-

🎯 Challenges

-

Participate in daily challenges and bounty hunts

- -
-
-

💬 Live Chat

-

Collaborate with other researchers in real-time

- -
-
-
-
-
- - -
-
-
-

📈 Platform Analytics

-
-

Comprehensive analytics and insights about the platform

- -
-
-
-
-
- -
-

🔍 Compare Multiple Instances

- -
-
- - -
-
- - -
- -
- - -
- -
-
-
0
-
Unique Instances
-
-
-
0%
-
Average Similarity
-
-
-
0
-
High Confidence Matches
-
-
-
- -
- - -
-
-
- -
-

🏆 LeakHub Hall of Fame

-

Recognizing the top contributors to AI transparency

-
- -
-
📊 Rankings
-
🏅 Achievements
-
📅 Timeline
-
- -
-
-

Top Contributors

-
-
-
- - - - -
-
- - -
-
-
- -
-

🎯 LeakHub Bounty Board

-

Request targets and compete in daily challenges

-
- - -
-

🎯 Today's Challenge

-

Find and verify a system prompt from GPT-4 Turbo!

-
💰 Reward: 500 bonus points + Special Badge
-
Time remaining: 23:45:30
-
- -
- -
-

📝 Request a Leak Hunt

-
- - - - -
- - -
- - -
-
- - -
-

🔥 Hot Requests

-
-
🔥 Trending
-
💰 Highest Bounty
-
🆕 Newest
-
👍 My Votes
-
-
-

No requests yet. Be the first to request a leak hunt!

-
-
-
-
-
- - - - - + + + + + + LeakHub + + +
+ + + diff --git a/netlify.toml b/netlify.toml deleted file mode 100644 index 63bcd25..0000000 --- a/netlify.toml +++ /dev/null @@ -1,29 +0,0 @@ -[build] - publish = "." - functions = "api" - -[build.environment] - NODE_VERSION = "18" - -[[redirects]] - from = "/api/*" - to = "/.netlify/functions/serverless" - status = 200 - -[[headers]] - for = "/*" - [headers.values] - X-XSS-Protection = "1; mode=block" - X-Content-Type-Options = "nosniff" - X-Frame-Options = "DENY" - Strict-Transport-Security = "max-age=31536000; includeSubDomains; preload" - Referrer-Policy = "strict-origin-when-cross-origin" - Permissions-Policy = "geolocation=(), microphone=(), camera=()" - Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" - -[[headers]] - for = "/api/*" - [headers.values] - Access-Control-Allow-Origin = "*" - Access-Control-Allow-Methods = "GET, POST, PUT, DELETE, OPTIONS" - Access-Control-Allow-Headers = "Content-Type, Authorization" diff --git a/package-lock.json b/package-lock.json index 42d9b42..2fd327c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,397 +1,1000 @@ { - "name": "leakhub", - "version": "1.0.0", + "name": "leakhub_convex", + "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "leakhub", - "version": "1.0.0", - "license": "MIT", + "name": "leakhub_convex", + "version": "0.0.0", + "dependencies": { + "@convex-dev/auth": "^0.0.90", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-slot": "^1.2.3", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "convex": "^1.28.0", + "lucide-react": "^0.547.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-router-dom": "^7.9.4", + "tailwind-merge": "^3.3.1" + }, "devDependencies": { - "eslint": "^8.48.0", - "prettier": "^3.0.3", - "vite": "^4.4.9" + "@cloudflare/vite-plugin": "^1.13.17", + "@convex-dev/eslint-plugin": "^1.0.0", + "@eslint/js": "^9.21.0", + "@tailwindcss/vite": "^4.1.16", + "@types/node": "^22.18.12", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "@vitejs/plugin-react": "^5.0.0", + "dotenv": "^16.4.7", + "eslint": "^9.21.0", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^15.15.0", + "npm-run-all": "^4.1.5", + "prettier": "^3.5.3", + "tailwindcss": "^4.1.16", + "tw-animate-css": "^1.4.0", + "typescript": "~5.7.2", + "typescript-eslint": "^8.24.1", + "vite": "^6.2.0", + "wrangler": "^4.45.2" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], + "node_modules/@auth/core": { + "version": "0.37.4", + "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.37.4.tgz", + "integrity": "sha512-HOXJwXWXQRhbBDHlMU0K/6FT1v+wjtzdKhsNg0ZN7/gne6XPsIrjZ4daMcFnbq0Z/vsAbYBinQhhua0d77v7qw==", + "license": "ISC", + "peer": true, + "dependencies": { + "@panva/hkdf": "^1.2.1", + "jose": "^5.9.6", + "oauth4webapi": "^3.1.1", + "preact": "10.24.3", + "preact-render-to-string": "6.5.11" + }, + "peerDependencies": { + "@simplewebauthn/browser": "^9.0.1", + "@simplewebauthn/server": "^9.0.2", + "nodemailer": "^6.8.0" + }, + "peerDependenciesMeta": { + "@simplewebauthn/browser": { + "optional": true + }, + "@simplewebauthn/server": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=12" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cloudflare/kv-asset-handler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.0.tgz", + "integrity": "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "mime": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cloudflare/unenv-preset": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.8.tgz", + "integrity": "sha512-Ky929MfHh+qPhwCapYrRPwPVHtA2Ioex/DbGZyskGyNRDe9Ru3WThYZivyNVaPy5ergQSgMs9OKrM9Ajtz9F6w==", + "dev": true, + "license": "MIT OR Apache-2.0", + "peerDependencies": { + "unenv": "2.0.0-rc.21", + "workerd": "^1.20250927.0" + }, + "peerDependenciesMeta": { + "workerd": { + "optional": true + } + } + }, + "node_modules/@cloudflare/vite-plugin": { + "version": "1.13.17", + "resolved": "https://registry.npmjs.org/@cloudflare/vite-plugin/-/vite-plugin-1.13.17.tgz", + "integrity": "sha512-JYBs+KwN/fcqcOwa4hZ5SPLUAZ2idksZ4umeja4TWPPUWvO2f0Lm0bOjVHI+rFuq72b2vixx2coNJSyntEBUsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cloudflare/unenv-preset": "2.7.8", + "@remix-run/node-fetch-server": "^0.8.0", + "get-port": "^7.1.0", + "miniflare": "4.20251011.1", + "picocolors": "^1.1.1", + "tinyglobby": "^0.2.12", + "unenv": "2.0.0-rc.21", + "wrangler": "4.45.2", + "ws": "8.18.0" + }, + "peerDependencies": { + "vite": "^6.1.0 || ^7.0.0", + "wrangler": "^4.45.2" + } + }, + "node_modules/@cloudflare/workerd-darwin-64": { + "version": "1.20251011.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20251011.0.tgz", + "integrity": "sha512-0DirVP+Z82RtZLlK2B+VhLOkk+ShBqDYO/jhcRw4oVlp0TOvk3cOVZChrt3+y3NV8Y/PYgTEywzLKFSziK4wCg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=16" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "node_modules/@cloudflare/workerd-darwin-arm64": { + "version": "1.20251011.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20251011.0.tgz", + "integrity": "sha512-1WuFBGwZd15p4xssGN/48OE2oqokIuc51YvHvyNivyV8IYnAs3G9bJNGWth1X7iMDPe4g44pZrKhRnISS2+5dA==", "cpu": [ - "x64" + "arm64" ], "dev": true, - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=16" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "node_modules/@cloudflare/workerd-linux-64": { + "version": "1.20251011.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20251011.0.tgz", + "integrity": "sha512-BccMiBzFlWZyFghIw2szanmYJrJGBGHomw2y/GV6pYXChFzMGZkeCEMfmCyJj29xczZXxcZmUVJxNy4eJxO8QA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=16" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "node_modules/@cloudflare/workerd-linux-arm64": { + "version": "1.20251011.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20251011.0.tgz", + "integrity": "sha512-79o/216lsbAbKEVDZYXR24ivEIE2ysDL9jvo0rDTkViLWju9dAp3CpyetglpJatbSi3uWBPKZBEOqN68zIjVsQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ "linux" ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@cloudflare/workerd-windows-64": { + "version": "1.20251011.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20251011.0.tgz", + "integrity": "sha512-RIXUQRchFdqEvaUqn1cXZXSKjpqMaSaVAkI5jNZ8XzAw/bw2bcdOVUtakrflgxDprltjFb0PTNtuss1FKtH9Jg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16" + } + }, + "node_modules/@convex-dev/auth": { + "version": "0.0.90", + "resolved": "https://registry.npmjs.org/@convex-dev/auth/-/auth-0.0.90.tgz", + "integrity": "sha512-aqw88EB042HvnaF4wcf/f/wTocmT2Bus2VDQRuV79cM0+8kORM0ICK/ByZ6XsHgQ9qr6TmidNbXm6QAgndrdpQ==", + "license": "Apache-2.0", + "dependencies": { + "@oslojs/crypto": "^1.0.1", + "@oslojs/encoding": "^1.1.0", + "cookie": "^1.0.1", + "is-network-error": "^1.1.0", + "jose": "^5.2.2", + "jwt-decode": "^4.0.0", + "lucia": "^3.2.0", + "oauth4webapi": "^3.1.2", + "path-to-regexp": "^6.3.0", + "server-only": "^0.0.1" + }, + "bin": { + "auth": "dist/bin.cjs" + }, + "peerDependencies": { + "@auth/core": "^0.37.0", + "convex": "^1.17.0", + "react": "^18.2.0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/@convex-dev/eslint-plugin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@convex-dev/eslint-plugin/-/eslint-plugin-1.0.0.tgz", + "integrity": "sha512-ublJRBKcLCioNaf1ylkCHD2KzAqWE2RIQ6DA/UgXAXQW5qg4vZSWY8wy+EK11yJkSSxcGfFXDWaE1+cHaWJvNA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@typescript-eslint/utils": "~8.38.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, "engines": { "node": ">=12" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.6.0.tgz", + "integrity": "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", + "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", "cpu": [ "ppc64" ], - "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", + "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", + "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", + "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", + "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", + "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", + "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", + "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", + "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "cpu": [ + "arm" + ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", + "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", + "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", + "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", + "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", + "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", + "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", + "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", + "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", + "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", "cpu": [ - "x64" + "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", + "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", "cpu": [ "x64" ], - "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", + "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "cpu": [ + "arm64" + ], "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", + "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", + "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", + "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", + "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", + "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, "license": "MIT", "dependencies": { @@ -408,26 +1011,91 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz", + "integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -435,36 +1103,146 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz", + "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@eslint/core": "^0.16.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=10.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.4" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -481,13 +1259,449 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, - "license": "BSD-3-Clause" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -527,12 +1741,2157 @@ "node": ">= 8" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "node_modules/@oslojs/asn1": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oslojs/asn1/-/asn1-1.0.0.tgz", + "integrity": "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA==", + "license": "MIT", + "dependencies": { + "@oslojs/binary": "1.0.0" + } + }, + "node_modules/@oslojs/binary": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oslojs/binary/-/binary-1.0.0.tgz", + "integrity": "sha512-9RCU6OwXU6p67H4NODbuxv2S3eenuQ4/WFLrsq+K/k682xrznH5EVWA7N4VFk9VYVcbFtKqur5YQQZc0ySGhsQ==", + "license": "MIT" + }, + "node_modules/@oslojs/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@oslojs/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-7n08G8nWjAr/Yu3vu9zzrd0L9XnrJfpMioQcvCMxBIiF5orECHe5/3J0jmXRVvgfqMm/+4oxlQ+Sq39COYLcNQ==", + "license": "MIT", + "dependencies": { + "@oslojs/asn1": "1.0.0", + "@oslojs/binary": "1.0.0" + } + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@panva/hkdf": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz", + "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@poppinss/colors": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.5.tgz", + "integrity": "sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "kleur": "^4.1.5" + } + }, + "node_modules/@poppinss/dumper": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.4.tgz", + "integrity": "sha512-iG0TIdqv8xJ3Lt9O8DrPRxw1MRLjNpoqiSGU03P/wNLP/s0ra0udPJ1J2Tx5M0J3H/cVyEgpbn8xUKRY9j59kQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@sindresorhus/is": "^7.0.2", + "supports-color": "^10.0.0" + } + }, + "node_modules/@poppinss/dumper/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@poppinss/exception": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.2.tgz", + "integrity": "sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT" + }, + "node_modules/@remix-run/node-fetch-server": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@remix-run/node-fetch-server/-/node-fetch-server-0.8.1.tgz", + "integrity": "sha512-J1dev372wtJqmqn9U/qbpbZxbJSQrogNN2+Qv1lKlpATpe/WQ9aCZfl/xSb9d2Rgh1IyLSvNxZAXPZxruO6Xig==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.43", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz", + "integrity": "sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sindresorhus/is": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.1.0.tgz", + "integrity": "sha512-7F/yz2IphV39hiS2zB4QYVkivrptHHh0K8qJJd9HhuWSdvf8AN7NpebW3CcDZDBQsUPMoDKWsY2WWgW7bqOcfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.8.tgz", + "integrity": "sha512-IGytNtnUnPIobIbOq5Y6LIlqiHNX+vnToQIS7lj6L5819C+rA8TXRDkkG8vePsiBOGcoW9R6i+dp2YBUKdB09Q==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.16.tgz", + "integrity": "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.19", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.16.tgz", + "integrity": "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-x64": "4.1.16", + "@tailwindcss/oxide-freebsd-x64": "4.1.16", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-x64-musl": "4.1.16", + "@tailwindcss/oxide-wasm32-wasi": "4.1.16", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.16.tgz", + "integrity": "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.16.tgz", + "integrity": "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.16.tgz", + "integrity": "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.16.tgz", + "integrity": "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.16.tgz", + "integrity": "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.16.tgz", + "integrity": "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.16.tgz", + "integrity": "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.16.tgz", + "integrity": "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.16.tgz", + "integrity": "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.16.tgz", + "integrity": "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.7", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.16.tgz", + "integrity": "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.16.tgz", + "integrity": "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.16.tgz", + "integrity": "sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.16", + "@tailwindcss/oxide": "4.1.16", + "tailwindcss": "4.1.16" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.18.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.12.tgz", + "integrity": "sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz", + "integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/type-utils": "8.46.2", + "@typescript-eslint/utils": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.2", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/project-service": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", + "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.2", + "@typescript-eslint/types": "^8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", + "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", + "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", + "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", + "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.2", + "@typescript-eslint/tsconfig-utils": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz", + "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", + "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz", + "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", + "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.2", + "@typescript-eslint/types": "^8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", + "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", + "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", + "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", + "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.2", + "@typescript-eslint/tsconfig-utils": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", + "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", + "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.38.0", + "@typescript-eslint/types": "^8.38.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", + "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", + "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz", + "integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2", + "@typescript-eslint/utils": "8.46.2", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/project-service": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", + "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.2", + "@typescript-eslint/types": "^8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", + "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", + "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", + "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", + "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.2", + "@typescript-eslint/tsconfig-utils": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz", + "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", + "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", + "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", + "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.38.0", + "@typescript-eslint/tsconfig-utils": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", + "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", + "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.38.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.0.tgz", + "integrity": "sha512-4LuWrg7EKWgQaMJfnN+wcmbAW+VSsCmqGohftWjuct47bv8uE4n/nPpq4XjJPsxgq00GGG5J8dvBczp8uxScew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.43", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } }, "node_modules/acorn": { "version": "8.15.0", @@ -557,6 +3916,16 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -574,16 +3943,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -607,6 +3966,83 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -614,15 +4050,128 @@ "dev": true, "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.20.tgz", + "integrity": "sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", + "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", + "dev": true, + "license": "MIT" + }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { @@ -635,6 +4184,27 @@ "node": ">=6" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -652,6 +4222,41 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -672,6 +4277,17 @@ "dev": true, "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -679,6 +4295,55 @@ "dev": true, "license": "MIT" }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convex": { + "version": "1.31.2", + "resolved": "https://registry.npmjs.org/convex/-/convex-1.31.2.tgz", + "integrity": "sha512-RFuJOwlL2bM5X63egvBI5ZZZH6wESREpAbHsLjODxzDeJuewTLKrEnbvHV/NWp1uJYpgEFJziuGHmZ0tnAmmJg==", + "license": "Apache-2.0", + "dependencies": { + "esbuild": "0.25.4", + "prettier": "^3.0.0" + }, + "bin": { + "convex": "bin/main.js" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=7.0.0" + }, + "peerDependencies": { + "@auth0/auth0-react": "^2.0.1", + "@clerk/clerk-react": "^4.12.8 || ^5.0.0", + "react": "^18.0.0 || ^19.0.0-0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@auth0/auth0-react": { + "optional": true + }, + "@clerk/clerk-react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -694,10 +4359,71 @@ "node": ">= 8" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -719,55 +4445,318 @@ "dev": true, "license": "MIT" }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "esutils": "^2.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.240", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.240.tgz", + "integrity": "sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", + "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", "hasInstallScript": true, "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "@esbuild/aix-ppc64": "0.25.4", + "@esbuild/android-arm": "0.25.4", + "@esbuild/android-arm64": "0.25.4", + "@esbuild/android-x64": "0.25.4", + "@esbuild/darwin-arm64": "0.25.4", + "@esbuild/darwin-x64": "0.25.4", + "@esbuild/freebsd-arm64": "0.25.4", + "@esbuild/freebsd-x64": "0.25.4", + "@esbuild/linux-arm": "0.25.4", + "@esbuild/linux-arm64": "0.25.4", + "@esbuild/linux-ia32": "0.25.4", + "@esbuild/linux-loong64": "0.25.4", + "@esbuild/linux-mips64el": "0.25.4", + "@esbuild/linux-ppc64": "0.25.4", + "@esbuild/linux-riscv64": "0.25.4", + "@esbuild/linux-s390x": "0.25.4", + "@esbuild/linux-x64": "0.25.4", + "@esbuild/netbsd-arm64": "0.25.4", + "@esbuild/netbsd-x64": "0.25.4", + "@esbuild/openbsd-arm64": "0.25.4", + "@esbuild/openbsd-x64": "0.25.4", + "@esbuild/sunos-x64": "0.25.4", + "@esbuild/win32-arm64": "0.25.4", + "@esbuild/win32-ia32": "0.25.4", + "@esbuild/win32-x64": "0.25.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" } }, "node_modules/escape-string-regexp": { @@ -784,66 +4773,92 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz", + "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.1", + "@eslint/core": "^0.16.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.38.0", + "@eslint/plugin-kit": "^0.4.0", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz", + "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -851,7 +4866,7 @@ "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -870,19 +4885,69 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -934,6 +4999,26 @@ "node": ">=0.10.0" } }, + "node_modules/exit-hook": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", + "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/exsolve": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -941,6 +5026,36 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -966,16 +5081,29 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/find-up": { @@ -996,18 +5124,17 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { @@ -1017,12 +5144,21 @@ "dev": true, "license": "ISC" }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/fsevents": { "version": "2.3.3", @@ -1039,26 +5175,144 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "license": "ISC", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { - "node": "*" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-port": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/glob-parent": { @@ -1074,22 +5328,63 @@ "node": ">=10.13.0" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -1097,6 +5392,19 @@ "dev": true, "license": "MIT" }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1107,6 +5415,84 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -1144,24 +5530,162 @@ "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-extglob": { "version": "2.1.1", @@ -1173,6 +5697,42 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1186,16 +5746,223 @@ "node": ">=0.10.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-network-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", + "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1203,6 +5970,32 @@ "dev": true, "license": "ISC" }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jose": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1216,6 +6009,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -1223,6 +6029,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1237,6 +6050,28 @@ "dev": true, "license": "MIT" }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -1247,6 +6082,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -1261,6 +6106,283 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -1284,17 +6406,156 @@ "dev": true, "license": "MIT" }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "yallist": "^3.0.2" + } + }, + "node_modules/lucia": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/lucia/-/lucia-3.2.2.tgz", + "integrity": "sha512-P1FlFBGCMPMXu+EGdVD9W4Mjm0DqsusmKgO7Xc33mI5X1bklmsQb0hfzPhXomQr9waWIBDsiOjvr1e6BTaUqpA==", + "deprecated": "This package has been deprecated. Please see https://lucia-auth.com/lucia-v3/migrate.", + "license": "MIT", + "dependencies": { + "@oslojs/crypto": "^1.0.1", + "@oslojs/encoding": "^1.1.0" + } + }, + "node_modules/lucide-react": { + "version": "0.547.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.547.0.tgz", + "integrity": "sha512-YLChGBWKq8ynr1UWP8WWRPhHhyuBAXfSBnHSgfoj51L//9TU3d0zvxpigf5C1IJ4vnEoTzthl5awPK55PiZhdA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": "*" + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/miniflare": { + "version": "4.20251011.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20251011.1.tgz", + "integrity": "sha512-Qbw1Z8HTYM1adWl6FAtzhrj34/6dPRDPwdYOx21dkae8a/EaxbMzRIPbb4HKVGMVvtqbK1FaRCgDLVLolNzGHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "acorn": "8.14.0", + "acorn-walk": "8.3.2", + "exit-hook": "2.2.1", + "glob-to-regexp": "0.4.1", + "sharp": "^0.33.5", + "stoppable": "1.1.0", + "undici": "7.14.0", + "workerd": "1.20251011.0", + "ws": "8.18.0", + "youch": "4.1.0-beta.10", + "zod": "3.22.3" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/miniflare/node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ms": { @@ -1330,16 +6591,304 @@ "dev": true, "license": "MIT" }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", + "integrity": "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm-run-all/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/npm-run-all/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/npm-run-all/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/npm-run-all/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { - "wrappy": "1" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/oauth4webapi": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.2.tgz", + "integrity": "sha512-FzZZ+bht5X0FKe7Mwz3DAVAmlH1BV5blSak/lHMBKz0/EBMhX6B10GlQYI51+oRp8ObJaX0g6pXrAxZh5s8rjw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "dev": true, + "license": "MIT" + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -1358,6 +6907,24 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -1403,6 +6970,20 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -1413,16 +6994,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1433,6 +7004,39 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -1440,6 +7044,52 @@ "dev": true, "license": "ISC" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -1469,6 +7119,27 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/preact": { + "version": "10.24.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz", + "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==", + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "6.5.11", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.11.tgz", + "integrity": "sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "preact": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -1483,7 +7154,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", - "dev": true, "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -1526,6 +7196,224 @@ ], "license": "MIT" }, + "node_modules/react": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.4.tgz", + "integrity": "sha512-SD3G8HKviFHg9xj7dNODUKDFgpG4xqD5nhyd0mYoB5iISepuZAvzSr8ywxgxKJ52yRzf/HWtVHc9AWwoTbljvA==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.4.tgz", + "integrity": "sha512-f30P6bIkmYvnHHa5Gcu65deIXoA2+r3Eb6PJIAddvsT9aGlchMatJ51GgpU470aSqRRbFX22T70yQNUGuW3DfA==", + "license": "MIT", + "dependencies": { + "react-router": "7.9.4" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -1547,37 +7435,45 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rollup": { - "version": "3.29.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", - "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", "fsevents": "~2.3.2" } }, @@ -1605,6 +7501,181 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/server-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", + "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", + "license": "MIT" + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1628,6 +7699,112 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "dev": true, + "license": "MIT" + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -1638,17 +7815,153 @@ "node": ">=0.10.0" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + } + }, + "node_modules/stoppable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", + "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "npm": ">=6" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" } }, "node_modules/strip-json-comments": { @@ -1677,13 +7990,140 @@ "node": ">=8" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", + "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz", + "integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==", "dev": true, "license": "MIT" }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -1697,17 +8137,363 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.2.tgz", + "integrity": "sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.46.2", + "@typescript-eslint/parser": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2", + "@typescript-eslint/utils": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/project-service": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", + "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.2", + "@typescript-eslint/types": "^8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", + "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", + "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", + "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", + "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.2", + "@typescript-eslint/tsconfig-utils": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz", + "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", + "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.14.0.tgz", + "integrity": "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unenv": { + "version": "2.0.0-rc.21", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.21.tgz", + "integrity": "sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.4", + "exsolve": "^1.0.7", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "ufo": "^1.6.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, "node_modules/uri-js": { @@ -1720,42 +8506,115 @@ "punycode": "^2.1.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/vite": { - "version": "4.5.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz", - "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -1765,6 +8624,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -1773,9 +8635,46 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1792,6 +8691,95 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -1802,10 +8790,88 @@ "node": ">=0.10.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "node_modules/workerd": { + "version": "1.20251011.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20251011.0.tgz", + "integrity": "sha512-Dq35TLPEJAw7BuYQMkN3p9rge34zWMU2Gnd4DSJFeVqld4+DAO2aPG7+We2dNIAyM97S8Y9BmHulbQ00E0HC7Q==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "bin": { + "workerd": "bin/workerd" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "@cloudflare/workerd-darwin-64": "1.20251011.0", + "@cloudflare/workerd-darwin-arm64": "1.20251011.0", + "@cloudflare/workerd-linux-64": "1.20251011.0", + "@cloudflare/workerd-linux-arm64": "1.20251011.0", + "@cloudflare/workerd-windows-64": "1.20251011.0" + } + }, + "node_modules/wrangler": { + "version": "4.45.2", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.45.2.tgz", + "integrity": "sha512-+G24gD+Rh7iBus5QiVBhNgSLzyAiyuZSm+3Ih5li8+PEA+gosAXfDSZlNZwsVmXd8VJTjq+BR4vhUiruQRWgTw==", + "dev": true, + "license": "MIT OR Apache-2.0", + "dependencies": { + "@cloudflare/kv-asset-handler": "0.4.0", + "@cloudflare/unenv-preset": "2.7.8", + "blake3-wasm": "2.1.5", + "esbuild": "0.25.4", + "miniflare": "4.20251011.1", + "path-to-regexp": "6.3.0", + "unenv": "2.0.0-rc.21", + "workerd": "1.20251011.0" + }, + "bin": { + "wrangler": "bin/wrangler.js", + "wrangler2": "bin/wrangler.js" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.20251011.0" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" }, @@ -1821,6 +8887,41 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/youch": { + "version": "4.1.0-beta.10", + "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", + "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/colors": "^4.1.5", + "@poppinss/dumper": "^0.6.4", + "@speed-highlight/core": "^1.2.7", + "cookie": "^1.0.2", + "youch-core": "^0.3.3" + } + }, + "node_modules/youch-core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", + "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "error-stack-parser-es": "^1.0.5" + } + }, + "node_modules/zod": { + "version": "3.22.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz", + "integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 36608d6..85a5569 100644 --- a/package.json +++ b/package.json @@ -1,39 +1,56 @@ { - "name": "leakhub", - "version": "1.0.0", - "description": "AI System Prompt Discovery Platform - Community hub for crowd-sourced system prompt leak verification", - "main": "index.html", + "name": "leakhub_convex", + "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "dev": "vite", - "build": "vite build", + "dev": "npm-run-all --parallel dev:frontend dev:backend", + "dev:frontend": "vite --open", + "dev:backend": "convex dev", + "predev": "convex dev --until-success && convex dev --once --run-sh \"node setup.mjs --once\" && convex dashboard", + "build": "tsc --noEmit && vite build", + "lint": "tsc && eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview", - "lint": "eslint . --ext .js,.html", - "format": "prettier --write .", - "serve": "python3 -m http.server 8000" + "deploy": "npm run build && wrangler pages deploy", + "cf-typegen": "wrangler types" + }, + "dependencies": { + "@convex-dev/auth": "^0.0.90", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-slot": "^1.2.3", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "convex": "^1.28.0", + "lucide-react": "^0.547.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-router-dom": "^7.9.4", + "tailwind-merge": "^3.3.1" }, - "keywords": [ - "ai", - "system-prompt", - "transparency", - "crowdsourcing", - "verification", - "community", - "github-pages" - ], - "author": "Elder Plinius", - "license": "MIT", "devDependencies": { - "vite": "^4.4.9", - "eslint": "^8.48.0", - "prettier": "^3.0.3" - }, - "dependencies": {}, - "repository": { - "type": "git", - "url": "https://github.com/elder-plinius/LEAKHUB.git" - }, - "homepage": "https://elder-plinius.github.io/LEAKHUB", - "bugs": { - "url": "https://github.com/elder-plinius/LEAKHUB/issues" + "@cloudflare/vite-plugin": "^1.13.17", + "@convex-dev/eslint-plugin": "^1.0.0", + "@eslint/js": "^9.21.0", + "@tailwindcss/vite": "^4.1.16", + "@types/node": "^22.18.12", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "@vitejs/plugin-react": "^5.0.0", + "dotenv": "^16.4.7", + "eslint": "^9.21.0", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^15.15.0", + "npm-run-all": "^4.1.5", + "prettier": "^3.5.3", + "tailwindcss": "^4.1.16", + "tw-animate-css": "^1.4.0", + "typescript": "~5.7.2", + "typescript-eslint": "^8.24.1", + "vite": "^6.2.0", + "wrangler": "^4.45.2" } } diff --git a/script.js b/script.js deleted file mode 100644 index 72dbffd..0000000 --- a/script.js +++ /dev/null @@ -1,2066 +0,0 @@ -// LeakHub Database and State Management -let leakDatabase = []; -let selectedSubmissions = new Set(); -let userStats = {}; -let leakRequests = []; -let userVotes = {}; -let dailyChallenge = null; - -// Dynamic Achievement System -const achievements = { - firstBlood: { id: 'firstBlood', name: 'First Blood', description: 'Submit your first leak', icon: '🩸', points: 50, unlocked: false }, - discoverer: { id: 'discoverer', name: 'Discoverer', description: 'Make your first discovery', icon: '🔍', points: 100, unlocked: false }, - verifier: { id: 'verifier', name: 'Verifier', description: 'Verify 5 submissions', icon: '✅', points: 200, unlocked: false }, - collector: { id: 'collector', name: 'Collector', description: 'Submit 10 different leaks', icon: '📚', points: 300, unlocked: false }, - expert: { id: 'expert', name: 'Expert', description: 'Reach 1000 total points', icon: '👑', points: 500, unlocked: false }, - pioneer: { id: 'pioneer', name: 'Pioneer', description: 'Discover 5 different targets', icon: '🚀', points: 400, unlocked: false }, - analyst: { id: 'analyst', name: 'Analyst', description: 'Perform 20 comparisons', icon: '📊', points: 250, unlocked: false }, - challenger: { id: 'challenger', name: 'Challenger', description: 'Complete 5 daily challenges', icon: '🎯', points: 350, unlocked: false }, - community: { id: 'community', name: 'Community Hero', description: 'Submit 10 requests', icon: '🤝', points: 200, unlocked: false }, - legend: { id: 'legend', name: 'LeakHub Legend', description: 'Unlock all achievements', icon: '🌟', points: 1000, unlocked: false } -}; - -let userAchievements = {}; - -// Initialize database and UI -async function initializeApp() { - try { - // Wait for database to be ready - await window.LeakHubDB.init(); - - // Load data from database - leakDatabase = await window.LeakHubDB.getLeakDatabase(); - userStats = await window.LeakHubDB.getUserStats(); - leakRequests = await window.LeakHubDB.getLeakRequests(); - userVotes = await window.LeakHubDB.getUserVotes(); - dailyChallenge = await window.LeakHubDB.getDailyChallenge(); - - // Initialize UI and production features - updateUI(); - initializeDailyChallenge(); - startChallengeTimer(); - initializeProductionFeatures(); - - console.log('LeakHub initialized successfully'); - } catch (error) { - console.error('Error initializing LeakHub:', error); - // Fallback to localStorage if database fails - leakDatabase = JSON.parse(localStorage.getItem('leakDatabase') || '[]'); - userStats = JSON.parse(localStorage.getItem('userStats') || '{}'); - leakRequests = JSON.parse(localStorage.getItem('leakRequests') || '[]'); - userVotes = JSON.parse(localStorage.getItem('userVotes') || '{}'); - dailyChallenge = JSON.parse(localStorage.getItem('dailyChallenge') || 'null'); - - updateUI(); - initializeDailyChallenge(); - startChallengeTimer(); - initializeProductionFeatures(); - } -} - -// Start the app -initializeApp(); - -function submitLeak(event) { - event.preventDefault(); - - const source = document.getElementById('sourceName').value; - const submission = { - id: Date.now().toString(), - source: source, - targetType: document.getElementById('targetType').value, - instance: document.getElementById('instanceId').value, - targetUrl: document.getElementById('targetUrl').value || null, - requiresLogin: document.getElementById('requiresLogin').checked, - requiresPaid: document.getElementById('requiresPaid').checked, - accessNotes: document.getElementById('accessNotes').value || null, - parentSystem: document.getElementById('parentSystem').value || null, - functionName: document.getElementById('functionName').value || null, - content: document.getElementById('leakContent').value, - toolPrompts: document.getElementById('toolPrompts').value || null, - context: document.getElementById('context').value, - timestamp: new Date().toISOString(), - verifications: 0, - confidence: 0, - isFirstDiscovery: false, - hasTools: document.getElementById('hasTools').checked - }; - - // Calculate initial confidence based on content - submission.confidence = calculateInitialConfidence(submission.content); - - // Check if this is the first discovery for this specific target - const targetKey = `${submission.targetType}:${submission.instance}${submission.functionName ? ':' + submission.functionName : ''}`; - const existingForTarget = leakDatabase.filter(sub => { - const subKey = `${sub.targetType}:${sub.instance}${sub.functionName ? ':' + sub.functionName : ''}`; - return subKey === targetKey; - }); - - if (existingForTarget.length === 0) { - submission.isFirstDiscovery = true; - } - - leakDatabase.push(submission); - - // Update user stats - if (!userStats[source]) { - userStats[source] = { - submissions: 0, - verifiedLeaks: 0, - firstDiscoveries: 0, - totalScore: 0, - joinDate: new Date().toISOString(), - toolsDiscovered: 0, - appsDiscovered: 0, - agentsDiscovered: 0, - comparisons: 0, - challengesCompleted: 0, - requestsSubmitted: 0 - }; - } - - userStats[source].submissions++; - if (submission.isFirstDiscovery) { - userStats[source].firstDiscoveries++; - userStats[source].totalScore += 100; // 100 points for first discovery - - // Extra points for discovering non-model targets - if (submission.targetType !== 'model') { - userStats[source].totalScore += 50; // Bonus for diversity - } - - // Track specific discovery types - if (submission.targetType === 'tool') userStats[source].toolsDiscovered++; - if (submission.targetType === 'app') userStats[source].appsDiscovered++; - if (submission.targetType === 'agent') userStats[source].agentsDiscovered++; - } - userStats[source].totalScore += 10; // 10 points for any submission - - // Bonus points for tool prompts - if (submission.hasTools && submission.toolPrompts) { - userStats[source].totalScore += 30; // Extra points for comprehensive submission - } - - saveDatabase().then(() => { - updateUI(); - - // Clear form - document.getElementById('sourceName').value = ''; - document.getElementById('targetType').value = ''; - document.getElementById('instanceId').value = ''; - document.getElementById('targetUrl').value = ''; - document.getElementById('requiresLogin').checked = false; - document.getElementById('requiresPaid').checked = false; - document.getElementById('accessNotes').value = ''; - document.getElementById('parentSystem').value = ''; - document.getElementById('functionName').value = ''; - document.getElementById('leakContent').value = ''; - document.getElementById('toolPrompts').value = ''; - document.getElementById('context').value = ''; - document.getElementById('hasTools').checked = false; - document.getElementById('additionalFields').style.display = 'none'; - document.getElementById('toolsSection').style.display = 'none'; - - showAlert('Leak submitted successfully!'); - }); - - showAlert(submission.isFirstDiscovery ? - '🎉 First discovery! You found a new leak!' : - 'Leak submitted successfully!'); - - // Check for daily challenge completion - checkDailyChallengeCompletion(submission); -} - -function updateTargetFields() { - const targetType = document.getElementById('targetType').value; - const additionalFields = document.getElementById('additionalFields'); - const instancePlaceholder = document.getElementById('instanceId'); - - if (targetType === 'tool' || targetType === 'plugin') { - additionalFields.style.display = 'block'; - instancePlaceholder.placeholder = 'Tool/Plugin name (e.g., Code Interpreter, WebPilot)'; - } else if (targetType === 'agent') { - additionalFields.style.display = 'block'; - instancePlaceholder.placeholder = 'Agent name (e.g., AutoGPT, BabyAGI)'; - } else if (targetType === 'app') { - additionalFields.style.display = 'none'; - instancePlaceholder.placeholder = 'App name (e.g., Cursor, GitHub Copilot)'; - } else if (targetType === 'custom') { - additionalFields.style.display = 'block'; - instancePlaceholder.placeholder = 'Custom GPT/Bot name'; - } else { - additionalFields.style.display = 'none'; - instancePlaceholder.placeholder = 'Model name (e.g., GPT-4, Claude-3)'; - } -} - -function toggleToolsSection() { - const toolsSection = document.getElementById('toolsSection'); - const hasTools = document.getElementById('hasTools').checked; - toolsSection.style.display = hasTools ? 'block' : 'none'; -} - -function calculateInitialConfidence(content) { - // Simple heuristics for initial confidence - let confidence = 50; // Base confidence - - // Check for common system prompt patterns - if (content.includes('You are') || content.includes('Your purpose')) confidence += 10; - if (content.includes('instructions') || content.includes('guidelines')) confidence += 10; - if (content.includes('Do not') || content.includes('Never')) confidence += 10; - if (content.length > 500) confidence += 10; - if (content.includes('\n') && content.split('\n').length > 5) confidence += 10; - - return Math.min(confidence, 90); // Cap at 90% until verified -} - -function updateUI() { - updateSubmissionsList(); - updateStatistics(); - updateSelectors(); -} - -function updateSubmissionsList() { - const list = document.getElementById('submissionsList'); - - if (leakDatabase.length === 0) { - list.innerHTML = '

No submissions yet. Be the first to contribute!

'; - return; - } - - // Group by target type and instance - const grouped = leakDatabase.reduce((acc, submission) => { - const targetType = submission.targetType || 'model'; // Backwards compatibility - const typeEmoji = { - 'model': '🤖 ', - 'app': '📱 ', - 'tool': '🔧 ', - 'agent': '🤝 ', - 'plugin': '🔌 ', - 'custom': '🛠️ ' - }[targetType] || '📄 '; - - const groupKey = `${typeEmoji} ${submission.instance}`; - if (!acc[groupKey]) acc[groupKey] = []; - acc[groupKey].push(submission); - return acc; - }, {}); - - list.innerHTML = Object.entries(grouped).map(([groupName, submissions]) => ` -
-

${groupName} (${submissions.length} submissions)

- ${submissions.map(sub => { - const targetInfo = sub.functionName ? - `→ ${sub.functionName}` : ''; - const parentInfo = sub.parentSystem ? - `(${sub.parentSystem})` : ''; - const toolsBadge = sub.hasTools ? - '+tools' : ''; - - // Access badges - const accessBadges = []; - if (sub.requiresLogin) accessBadges.push('🔒'); - if (sub.requiresPaid) accessBadges.push('💰'); - - const linkButton = sub.targetUrl ? - `🔗 Visit` : ''; - - return ` -
- ${linkButton} -
- ${sub.source} ${parentInfo} - ${new Date(sub.timestamp).toLocaleDateString()} -
- ${targetInfo} -
${sub.content.substring(0, 100)}...
- ${sub.accessNotes ? `
📋 ${sub.accessNotes}
` : ''} -
${sub.confidence}%
-
- ${toolsBadge}${accessBadges.join('')} -
-
- `; - }).join('')} -
- `).join(''); -} - -function updateStatistics() { - // Count unique targets by type - const targetCounts = leakDatabase.reduce((acc, sub) => { - const targetType = sub.targetType || 'model'; - const key = `${targetType}:${sub.instance}`; - acc.add(key); - return acc; - }, new Set()); - - document.getElementById('activeLeaks').textContent = targetCounts.size; - document.getElementById('totalSubmissions').textContent = leakDatabase.length; - - const verified = leakDatabase.filter(sub => sub.confidence >= 90).length; - document.getElementById('verifiedPrompts').textContent = verified; - - document.getElementById('uniqueInstances').textContent = targetCounts.size; - - // Calculate average similarity from recent comparisons - const avgSim = localStorage.getItem('avgSimilarity') || '0'; - document.getElementById('avgSimilarity').textContent = avgSim + '%'; - - const highConf = leakDatabase.filter(sub => sub.confidence >= 80).length; - document.getElementById('highConfidence').textContent = highConf; -} - -function updateSelectors() { - const selectA = document.getElementById('instanceA'); - const selectB = document.getElementById('instanceB'); - - const options = '' + - leakDatabase.map(sub => { - const targetType = sub.targetType || 'model'; - const typeLabel = targetType.charAt(0).toUpperCase() + targetType.slice(1); - const fullName = sub.functionName ? - `${sub.instance} → ${sub.functionName}` : sub.instance; - return ``; - }).join(''); - - selectA.innerHTML = options; - selectB.innerHTML = options; -} - -function toggleSelection(id) { - if (selectedSubmissions.has(id)) { - selectedSubmissions.delete(id); - } else { - selectedSubmissions.add(id); - } - updateUI(); -} - -function compareInstances() { - const idA = document.getElementById('instanceA').value; - const idB = document.getElementById('instanceB').value; - - if (!idA || !idB || idA === idB) { - showAlert('Please select two different submissions to compare'); - return; - } - - const subA = leakDatabase.find(sub => sub.id === idA); - const subB = leakDatabase.find(sub => sub.id === idB); - - performComparison(subA, subB); -} - -function performComparison(subA, subB) { - document.getElementById('comparisonResults').style.display = 'block'; - - // Display content - document.getElementById('instanceAContent').textContent = subA.content; - document.getElementById('instanceBContent').textContent = subB.content; - - // Normalize texts for comparison (remove extra whitespace, lowercase for some checks) - const normA = normalizeText(subA.content); - const normB = normalizeText(subB.content); - - // Calculate metrics - const charMatch = calculateCharMatch(normA, normB); - const wordMatch = calculateWordMatch(normA, normB); - const structureMatch = calculateStructureMatch(subA.content, subB.content); - const coreSimilarity = calculateCoreSimilarity(normA, normB); - - // Update UI - document.getElementById('charMatch').textContent = charMatch + '%'; - document.getElementById('wordMatch').textContent = wordMatch + '%'; - document.getElementById('structureMatch').textContent = structureMatch + '%'; - document.getElementById('coreSimilarity').textContent = coreSimilarity + '%'; - - // Generate consensus view - generateConsensusView(subA.content, subB.content); - - // Update average similarity - const avgSim = Math.round((charMatch + wordMatch + structureMatch + coreSimilarity) / 4); - localStorage.setItem('avgSimilarity', avgSim.toString()); - - // Update confidence scores if high match - if (coreSimilarity > 85) { - subA.confidence = Math.min(100, subA.confidence + 5); - subB.confidence = Math.min(100, subB.confidence + 5); - subA.verifications++; - subB.verifications++; - - // Award points for verification - if (userStats[subA.source]) { - userStats[subA.source].totalScore += 20; // 20 points for verification - if (subA.confidence >= 95 && !subA.wasVerified) { - userStats[subA.source].verifiedLeaks++; - userStats[subA.source].totalScore += 50; // Bonus for reaching verified status - subA.wasVerified = true; - } - } - if (userStats[subB.source]) { - userStats[subB.source].totalScore += 20; - if (subB.confidence >= 95 && !subB.wasVerified) { - userStats[subB.source].verifiedLeaks++; - userStats[subB.source].totalScore += 50; - subB.wasVerified = true; - } - } - - saveDatabase().then(() => { - updateUI(); - }); - } - - // Scroll to results - document.getElementById('comparisonResults').scrollIntoView({ behavior: 'smooth' }); -} - -function normalizeText(text) { - return text - .toLowerCase() - .replace(/\s+/g, ' ') - .replace(/[^\w\s]/g, '') - .trim(); -} - -function calculateCharMatch(textA, textB) { - const longer = textA.length > textB.length ? textA : textB; - const shorter = textA.length > textB.length ? textB : textA; - - let matches = 0; - for (let i = 0; i < shorter.length; i++) { - if (shorter[i] === longer[i]) matches++; - } - - return Math.round((matches / longer.length) * 100); -} - -function calculateWordMatch(textA, textB) { - const wordsA = new Set(textA.split(' ')); - const wordsB = new Set(textB.split(' ')); - - const intersection = new Set([...wordsA].filter(x => wordsB.has(x))); - const union = new Set([...wordsA, ...wordsB]); - - return Math.round((intersection.size / union.size) * 100); -} - -function calculateStructureMatch(textA, textB) { - // Compare line counts, paragraph structure, etc. - const linesA = textA.split('\n').filter(l => l.trim()); - const linesB = textB.split('\n').filter(l => l.trim()); - - const lineRatio = Math.min(linesA.length, linesB.length) / Math.max(linesA.length, linesB.length); - - // Check for similar patterns (numbered lists, bullet points, etc.) - const hasNumbersA = /^\d+\./.test(textA); - const hasNumbersB = /^\d+\./.test(textB); - const hasBulletsA = /^[-*•]/.test(textA); - const hasBulletsB = /^[-*•]/.test(textB); - - let structureScore = lineRatio * 50; - if (hasNumbersA === hasNumbersB) structureScore += 25; - if (hasBulletsA === hasBulletsB) structureScore += 25; - - return Math.round(structureScore); -} - -function calculateCoreSimilarity(textA, textB) { - // Use a simple sliding window approach to find common phrases - const minPhraseLength = 10; - const commonPhrases = []; - - for (let i = 0; i <= textA.length - minPhraseLength; i++) { - for (let len = minPhraseLength; len <= 50 && i + len <= textA.length; len++) { - const phrase = textA.substring(i, i + len); - if (textB.includes(phrase)) { - commonPhrases.push(phrase); - } - } - } - - // Remove overlapping phrases - const uniquePhrases = commonPhrases.filter((phrase, index) => { - return !commonPhrases.some((other, otherIndex) => - otherIndex !== index && other.includes(phrase) && other.length > phrase.length - ); - }); - - const commonLength = uniquePhrases.reduce((sum, phrase) => sum + phrase.length, 0); - const avgLength = (textA.length + textB.length) / 2; - - return Math.round((commonLength / avgLength) * 100); -} - -function generateConsensusView(textA, textB) { - const consensusDiv = document.getElementById('consensusText'); - - // Find common lines/sections - const linesA = textA.split('\n'); - const linesB = textB.split('\n'); - - let consensus = []; - - linesA.forEach(lineA => { - const trimmedA = lineA.trim(); - if (!trimmedA) return; - - const matchingLine = linesB.find(lineB => { - const trimmedB = lineB.trim(); - // Allow for minor differences - return trimmedB && ( - trimmedA === trimmedB || - similarity(trimmedA.toLowerCase(), trimmedB.toLowerCase()) > 0.8 - ); - }); - - if (matchingLine) { - consensus.push(`${trimmedA}`); - } - }); - - if (consensus.length > 0) { - consensusDiv.innerHTML = consensus.join('\n'); - } else { - consensusDiv.innerHTML = 'No exact line matches found. Consider checking word-level similarities above.'; - } -} - -function similarity(s1, s2) { - const longer = s1.length > s2.length ? s1 : s2; - const shorter = s1.length > s2.length ? s2 : s1; - - if (longer.length === 0) return 1.0; - - const editDistance = levenshteinDistance(longer, shorter); - return (longer.length - editDistance) / longer.length; -} - -function levenshteinDistance(s1, s2) { - const costs = []; - for (let i = 0; i <= s1.length; i++) { - let lastValue = i; - for (let j = 0; j <= s2.length; j++) { - if (i === 0) { - costs[j] = j; - } else if (j > 0) { - let newValue = costs[j - 1]; - if (s1.charAt(i - 1) !== s2.charAt(j - 1)) { - newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1; - } - costs[j - 1] = lastValue; - lastValue = newValue; - } - } - if (i > 0) costs[s2.length] = lastValue; - } - return costs[s2.length]; -} - -async function saveDatabase() { - try { - await window.LeakHubDB.setLeakDatabase(leakDatabase); - await window.LeakHubDB.setUserStats(userStats); - await window.LeakHubDB.setLeakRequests(leakRequests); - await window.LeakHubDB.setUserVotes(userVotes); - await window.LeakHubDB.setDailyChallenge(dailyChallenge); - - // Also save to localStorage as backup - localStorage.setItem('leakDatabase', JSON.stringify(leakDatabase)); - localStorage.setItem('userStats', JSON.stringify(userStats)); - localStorage.setItem('leakRequests', JSON.stringify(leakRequests)); - localStorage.setItem('userVotes', JSON.stringify(userVotes)); - localStorage.setItem('dailyChallenge', JSON.stringify(dailyChallenge)); - } catch (error) { - console.error('Error saving to database:', error); - // Fallback to localStorage only - localStorage.setItem('leakDatabase', JSON.stringify(leakDatabase)); - localStorage.setItem('userStats', JSON.stringify(userStats)); - localStorage.setItem('leakRequests', JSON.stringify(leakRequests)); - localStorage.setItem('userVotes', JSON.stringify(userVotes)); - localStorage.setItem('dailyChallenge', JSON.stringify(dailyChallenge)); - } -} - -function showAlert(message) { - const alert = document.getElementById('alert'); - alert.textContent = message; - alert.style.display = 'block'; - - setTimeout(() => { - alert.style.display = 'none'; - }, 3000); -} - -// Leaderboard functions -function toggleLeaderboard() { - const overlay = document.getElementById('leaderboardOverlay'); - overlay.style.display = overlay.style.display === 'none' ? 'block' : 'none'; - if (overlay.style.display === 'block') { - updateLeaderboard(); - } -} - -function switchLeaderboardTab(tab) { - document.querySelectorAll('.leaderboard-tab').forEach(t => t.classList.remove('active')); - document.querySelectorAll('.leaderboard-content').forEach(c => c.style.display = 'none'); - - event.target.classList.add('active'); - document.getElementById(`${tab}-content`).style.display = 'block'; -} - -function updateLeaderboard() { - updateRankings(); - updateAchievements(); - updateTimeline(); -} - -function updateRankings() { - const rankingsList = document.getElementById('rankingsList'); - - // Sort users by total score - const sortedUsers = Object.entries(userStats) - .sort((a, b) => b[1].totalScore - a[1].totalScore) - .slice(0, 10); // Top 10 - - if (sortedUsers.length === 0) { - rankingsList.innerHTML = '

No contributors yet!

'; - return; - } - - rankingsList.innerHTML = sortedUsers.map(([username, stats], index) => { - const rank = index + 1; - const rankClass = rank <= 3 ? `rank-${rank}` : ''; - const rankEmoji = rank === 1 ? '🥇' : rank === 2 ? '🥈' : rank === 3 ? '🥉' : `#${rank}`; - - return ` -
-
${rankEmoji}
-
-
${username}
-
- 📤 ${stats.submissions} submissions - ✅ ${stats.verifiedLeaks} verified - 🎯 ${stats.firstDiscoveries} first discoveries -
-
-
${stats.totalScore} pts
-
- `; - }).join(''); -} - -function updateAchievements() { - const achievementsList = document.getElementById('achievementsList'); - const unlockedAchievements = displayAchievements(localStorage.getItem('currentUser')); - - if (unlockedAchievements.length === 0) { - achievementsList.innerHTML = '

No achievements yet!

'; - return; - } - - achievementsList.innerHTML = unlockedAchievements.map(achievement => ` -
-
${achievement.icon}
-
${achievement.name}
-

${achievement.description}

-
- `).join(''); -} - -function updateTimeline() { - const timelineList = document.getElementById('timelineList'); - - // Get significant events - const events = []; - - // First discoveries - const instanceFirsts = {}; - leakDatabase.forEach(sub => { - if (sub.isFirstDiscovery && !instanceFirsts[sub.instance]) { - instanceFirsts[sub.instance] = { - user: sub.source, - date: sub.timestamp, - instance: sub.instance - }; - } - }); - - Object.values(instanceFirsts).forEach(event => { - events.push({ - date: event.date, - type: 'discovery', - text: `${event.user} discovered the first ${event.instance} leak` - }); - }); - - // Verification milestones - leakDatabase.forEach(sub => { - if (sub.confidence >= 95 && sub.wasVerified) { - events.push({ - date: sub.timestamp, - type: 'verification', - text: `${sub.instance} leak verified by ${sub.source}` - }); - } - }); - - // Sort by date - events.sort((a, b) => new Date(b.date) - new Date(a.date)); - - if (events.length === 0) { - timelineList.innerHTML = '

No events yet!

'; - return; - } - - timelineList.innerHTML = events.slice(0, 20).map(event => ` -
-
-
-
${new Date(event.date).toLocaleString()}
-
${event.text}
-
-
- `).join(''); -} - -// Requests & Challenges functions -function toggleRequests() { - const overlay = document.getElementById('requestsOverlay'); - overlay.style.display = overlay.style.display === 'none' ? 'block' : 'none'; - if (overlay.style.display === 'block') { - updateRequestsList(); - } -} - -function initializeDailyChallenge() { - const now = new Date(); - const tomorrow = new Date(now); - tomorrow.setDate(tomorrow.getDate() + 1); - tomorrow.setHours(0, 0, 0, 0); - - if (!dailyChallenge || new Date(dailyChallenge.expires) < now) { - // Create new daily challenge - const challenges = [ - { model: 'GPT-4 Turbo', reward: 500 }, - { model: 'Claude 3 Opus', reward: 600 }, - { model: 'Gemini Ultra', reward: 700 }, - { model: 'Llama 3', reward: 400 }, - { model: 'Mistral Large', reward: 450 } - ]; - - const randomChallenge = challenges[Math.floor(Math.random() * challenges.length)]; - dailyChallenge = { - model: randomChallenge.model, - reward: randomChallenge.reward, - expires: tomorrow.toISOString(), - completedBy: [] - }; - saveDatabase(); - } - - document.getElementById('challengeDescription').textContent = - `Find and verify a system prompt from ${dailyChallenge.model}!`; -} - -function startChallengeTimer() { - setInterval(updateChallengeTimer, 1000); - updateChallengeTimer(); -} - -function updateChallengeTimer() { - if (!dailyChallenge) return; - - const now = new Date(); - const expires = new Date(dailyChallenge.expires); - const diff = expires - now; - - if (diff <= 0) { - initializeDailyChallenge(); - return; - } - - const hours = Math.floor(diff / (1000 * 60 * 60)); - const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); - const seconds = Math.floor((diff % (1000 * 60)) / 1000); - - document.getElementById('challengeTimer').textContent = - `Time remaining: ${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; -} - -function submitRequest(event) { - event.preventDefault(); - - const currentUser = prompt('Enter your username to submit this request:'); - if (!currentUser) return; - - const request = { - id: Date.now().toString(), - targetType: document.getElementById('requestTargetType').value, - model: document.getElementById('requestModel').value, - targetUrl: document.getElementById('requestUrl').value || null, - requiresLogin: document.getElementById('requestRequiresLogin').checked, - requiresPaid: document.getElementById('requestRequiresPaid').checked, - description: document.getElementById('requestDescription').value, - bounty: parseInt(document.getElementById('requestBounty').value) || 0, - requestedBy: currentUser, - timestamp: new Date().toISOString(), - votes: 0, - voters: [], - status: 'open' - }; - - leakRequests.push(request); - saveDatabase().then(() => { - updateRequestsList(); - - // Clear form - document.getElementById('requestModel').value = ''; - document.getElementById('requestDescription').value = ''; - document.getElementById('requestBounty').value = ''; - - showAlert('Request submitted successfully!'); - }); -} - -function updateRequestsList() { - const requestsList = document.getElementById('requestsList'); - const filterType = document.querySelector('.filter-tab.active')?.textContent.includes('Trending') ? 'trending' : - document.querySelector('.filter-tab.active')?.textContent.includes('Bounty') ? 'bounty' : - document.querySelector('.filter-tab.active')?.textContent.includes('Newest') ? 'new' : 'myvotes'; - - let filteredRequests = [...leakRequests]; - - // Apply filters - switch(filterType) { - case 'trending': - filteredRequests.sort((a, b) => b.votes - a.votes); - break; - case 'bounty': - filteredRequests.sort((a, b) => b.bounty - a.bounty); - break; - case 'new': - filteredRequests.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp)); - break; - case 'myvotes': - const currentUser = localStorage.getItem('currentUser'); - if (currentUser && userVotes[currentUser]) { - filteredRequests = filteredRequests.filter(req => userVotes[currentUser].includes(req.id)); - } - break; - } - - if (filteredRequests.length === 0) { - requestsList.innerHTML = '

No requests found.

'; - return; - } - - requestsList.innerHTML = filteredRequests.slice(0, 10).map(request => { - const currentUser = localStorage.getItem('currentUser'); - const hasVoted = currentUser && userVotes[currentUser] && userVotes[currentUser].includes(request.id); - const isTrending = request.votes > 5; - - const targetType = request.targetType || 'model'; - const typeEmoji = { - 'model': '🤖 ', - 'app': '📱 ', - 'tool': '🔧 ', - 'agent': '🤝 ', - 'plugin': '🔌 ', - 'custom': '🛠️ ' - }[targetType] || '📄 '; - - // Access indicators - const accessInfo = []; - if (request.requiresLogin) accessInfo.push('🔒'); - if (request.requiresPaid) accessInfo.push('💰'); - const accessString = accessInfo.length > 0 ? ` ${accessInfo.join(' ')}` : ''; - - const linkIcon = request.targetUrl ? - `🔗` : ''; - - return ` -
-
- ${typeEmoji} ${request.model}${accessString}${linkIcon} -
- ${isTrending ? '🔥 Trending' : ''} - ${request.votes} votes - -
-
- ${request.description ? `

${request.description}

` : ''} -
- Requested by ${request.requestedBy} - ${request.bounty > 0 ? `+${request.bounty} bounty` : ''} -
-
- `; - }).join(''); -} - -function voteForRequest(requestId) { - const currentUser = prompt('Enter your username to vote:'); - if (!currentUser) return; - - localStorage.setItem('currentUser', currentUser); - - if (!userVotes[currentUser]) { - userVotes[currentUser] = []; - } - - const request = leakRequests.find(r => r.id === requestId); - if (!request) return; - - if (userVotes[currentUser].includes(requestId)) { - // Remove vote - userVotes[currentUser] = userVotes[currentUser].filter(id => id !== requestId); - request.votes--; - request.voters = request.voters.filter(v => v !== currentUser); - } else { - // Add vote - userVotes[currentUser].push(requestId); - request.votes++; - request.voters.push(currentUser); - } - - saveDatabase(); - updateRequestsList(); -} - -function filterRequests(type) { - document.querySelectorAll('.filter-tab').forEach(tab => tab.classList.remove('active')); - event.target.classList.add('active'); - updateRequestsList(); -} - -// Check for daily challenge completion -function checkDailyChallengeCompletion(submission) { - if (!dailyChallenge || dailyChallenge.completedBy.includes(submission.source)) return; - - if (submission.instance === dailyChallenge.model && submission.confidence >= 90) { - // Challenge completed! - dailyChallenge.completedBy.push(submission.source); - - if (!userStats[submission.source]) { - userStats[submission.source] = { - submissions: 0, - verifiedLeaks: 0, - firstDiscoveries: 0, - totalScore: 0, - joinDate: new Date().toISOString(), - dailyChallenges: 0 - }; - } - - userStats[submission.source].totalScore += dailyChallenge.reward; - userStats[submission.source].dailyChallenges = (userStats[submission.source].dailyChallenges || 0) + 1; - - saveDatabase().then(() => { - showAlert(`🎯 Daily Challenge Completed! +${dailyChallenge.reward} points!`); - }); - } -} - -// Advanced AI-Powered Similarity Detection -function advancedSimilarityAnalysis(text1, text2) { - const analysis = { - semantic: calculateSemanticSimilarity(text1, text2), - structural: calculateStructuralSimilarity(text1, text2), - pattern: detectCommonPatterns(text1, text2), - keyword: analyzeKeywordOverlap(text1, text2), - confidence: 0 - }; - - // Calculate overall confidence based on all metrics - analysis.confidence = ( - analysis.semantic * 0.4 + - analysis.structural * 0.3 + - analysis.pattern * 0.2 + - analysis.keyword * 0.1 - ); - - return analysis; -} - -function calculateSemanticSimilarity(text1, text2) { - // Normalize and tokenize - const tokens1 = text1.toLowerCase().replace(/[^\w\s]/g, ' ').split(/\s+/).filter(t => t.length > 2); - const tokens2 = text2.toLowerCase().replace(/[^\w\s]/g, ' ').split(/\s+/).filter(t => t.length > 2); - - // Calculate Jaccard similarity - const set1 = new Set(tokens1); - const set2 = new Set(tokens2); - const intersection = new Set([...set1].filter(x => set2.has(x))); - const union = new Set([...set1, ...set2]); - - return intersection.size / union.size; -} - -function calculateStructuralSimilarity(text1, text2) { - // Analyze sentence structure and formatting - const lines1 = text1.split('\n').filter(line => line.trim().length > 0); - const lines2 = text2.split('\n').filter(line => line.trim().length > 0); - - // Compare line count and average line length - const avgLength1 = lines1.reduce((sum, line) => sum + line.length, 0) / lines1.length; - const avgLength2 = lines2.reduce((sum, line) => sum + line.length, 0) / lines2.length; - - const lengthSimilarity = 1 - Math.abs(avgLength1 - avgLength2) / Math.max(avgLength1, avgLength2); - const countSimilarity = 1 - Math.abs(lines1.length - lines2.length) / Math.max(lines1.length, lines2.length); - - return (lengthSimilarity + countSimilarity) / 2; -} - -function detectCommonPatterns(text1, text2) { - const patterns = []; - - // Detect common phrases (3+ words) - const words1 = text1.toLowerCase().split(/\s+/); - const words2 = text2.toLowerCase().split(/\s+/); - - for (let i = 0; i <= words1.length - 3; i++) { - for (let j = 0; j <= words2.length - 3; j++) { - const phrase1 = words1.slice(i, i + 3).join(' '); - const phrase2 = words2.slice(j, j + 3).join(' '); - - if (phrase1 === phrase2 && phrase1.length > 10) { - patterns.push(phrase1); - } - } - } - - // Calculate pattern density - const totalWords = Math.min(words1.length, words2.length); - return patterns.length / Math.max(totalWords / 10, 1); -} - -function analyzeKeywordOverlap(text1, text2) { - // Define AI-related keywords - const aiKeywords = [ - 'system', 'prompt', 'assistant', 'user', 'context', 'instruction', - 'behavior', 'response', 'format', 'output', 'input', 'model', - 'ai', 'artificial', 'intelligence', 'language', 'processing', - 'generate', 'analyze', 'provide', 'help', 'support', 'guide' - ]; - - const text1Lower = text1.toLowerCase(); - const text2Lower = text2.toLowerCase(); - - let overlap = 0; - aiKeywords.forEach(keyword => { - if (text1Lower.includes(keyword) && text2Lower.includes(keyword)) { - overlap++; - } - }); - - return overlap / aiKeywords.length; -} - -// Enhanced comparison function -function performAdvancedComparison() { - const submission1Id = document.getElementById('submission1').value; - const submission2Id = document.getElementById('submission2').value; - - if (!submission1Id || !submission2Id) { - showAlert('Please select two submissions to compare.'); - return; - } - - const submission1 = leakDatabase.find(s => s.id === submission1Id); - const submission2 = leakDatabase.find(s => s.id === submission2Id); - - if (!submission1 || !submission2) { - showAlert('Selected submissions not found.'); - return; - } - - // Perform advanced analysis - const advancedAnalysis = advancedSimilarityAnalysis(submission1.content, submission2.content); - - // Update comparison results - const resultsDiv = document.getElementById('comparisonResults'); - resultsDiv.innerHTML = ` -
-

🤖 Advanced AI Analysis Results

-
-
- ${Math.round(advancedAnalysis.confidence * 100)}% Match -
-
- -
-
-

🧠 Semantic Similarity

-
-
- ${Math.round(advancedAnalysis.semantic * 100)}% -
-

Meaning and context similarity

-
- -
-

🏗️ Structural Similarity

-
-
- ${Math.round(advancedAnalysis.structural * 100)}% -
-

Format and organization similarity

-
- -
-

🔍 Pattern Detection

-
-
- ${Math.round(advancedAnalysis.pattern * 100)}% -
-

Common phrase and pattern density

-
- -
-

🎯 Keyword Overlap

-
-
- ${Math.round(advancedAnalysis.keyword * 100)}% -
-

AI-related terminology overlap

-
-
- -
-

🔍 Verification Recommendation

-

${advancedAnalysis.confidence > 0.8 ? '✅ HIGH CONFIDENCE - Strong evidence of similarity' : - advancedAnalysis.confidence > 0.6 ? '⚠️ MODERATE CONFIDENCE - Some similarities detected' : - '❌ LOW CONFIDENCE - Minimal similarity detected'}

-
- `; - - // Auto-boost confidence if high similarity - if (advancedAnalysis.confidence > 0.7) { - submission1.confidence = Math.min(100, submission1.confidence + 20); - submission2.confidence = Math.min(100, submission2.confidence + 20); - saveDatabase().then(() => { - updateUI(); - showAlert('High similarity detected! Confidence scores automatically boosted! 🚀'); - }); - } -} - -// Dynamic Achievement System -function checkAchievements(username) { - if (!userStats[username]) return; - - const stats = userStats[username]; - const newAchievements = []; - - // Check each achievement - Object.values(achievements).forEach(achievement => { - if (userAchievements[username] && userAchievements[username].includes(achievement.id)) return; - - let unlocked = false; - - switch (achievement.id) { - case 'firstBlood': - unlocked = stats.submissions >= 1; - break; - case 'discoverer': - unlocked = stats.firstDiscoveries >= 1; - break; - case 'verifier': - unlocked = stats.verifiedLeaks >= 5; - break; - case 'collector': - unlocked = stats.submissions >= 10; - break; - case 'expert': - unlocked = stats.totalScore >= 1000; - break; - case 'pioneer': - unlocked = stats.firstDiscoveries >= 5; - break; - case 'analyst': - unlocked = (stats.comparisons || 0) >= 20; - break; - case 'challenger': - unlocked = (stats.challengesCompleted || 0) >= 5; - break; - case 'community': - unlocked = (stats.requestsSubmitted || 0) >= 10; - break; - case 'legend': - unlocked = Object.keys(achievements).every(id => - userAchievements[username] && userAchievements[username].includes(id) - ); - break; - } - - if (unlocked) { - if (!userAchievements[username]) userAchievements[username] = []; - userAchievements[username].push(achievement.id); - newAchievements.push(achievement); - - // Award points - stats.totalScore += achievement.points; - - // Show achievement notification - showAchievementNotification(achievement); - } - }); - - if (newAchievements.length > 0) { - saveDatabase(); - updateUI(); - } -} - -function showAchievementNotification(achievement) { - const notification = document.createElement('div'); - notification.className = 'achievement-notification'; - notification.innerHTML = ` -
-
${achievement.icon}
-
-

🏆 Achievement Unlocked!

-

${achievement.name}

-

${achievement.description}

- +${achievement.points} points -
-
- `; - - document.body.appendChild(notification); - - // Animate in - setTimeout(() => notification.classList.add('show'), 100); - - // Remove after 5 seconds - setTimeout(() => { - notification.classList.remove('show'); - setTimeout(() => document.body.removeChild(notification), 500); - }, 5000); -} - -function displayAchievements(username) { - if (!userAchievements[username]) return []; - - return userAchievements[username].map(id => achievements[id]).filter(Boolean); -} - -// Enhanced user stats tracking -function updateUserStats(username, action, data = {}) { - if (!userStats[username]) { - userStats[username] = { - submissions: 0, - verifiedLeaks: 0, - firstDiscoveries: 0, - totalScore: 0, - joinDate: new Date().toISOString(), - toolsDiscovered: 0, - appsDiscovered: 0, - agentsDiscovered: 0, - comparisons: 0, - challengesCompleted: 0, - requestsSubmitted: 0 - }; - } - - switch (action) { - case 'submission': - userStats[username].submissions++; - break; - case 'firstDiscovery': - userStats[username].firstDiscoveries++; - break; - case 'verification': - userStats[username].verifiedLeaks++; - break; - case 'comparison': - userStats[username].comparisons++; - break; - case 'challengeComplete': - userStats[username].challengesCompleted++; - break; - case 'requestSubmitted': - userStats[username].requestsSubmitted++; - break; - } - - // Check for new achievements - checkAchievements(username); -} - -// Chat System Functions -let chatMessages = []; -let onlineUsers = new Set(); - -function toggleChat() { - const chatPanel = document.getElementById('chatPanel'); - if (chatPanel.style.display === 'none') { - chatPanel.style.display = 'block'; - if (!currentUser || currentUser === 'Guest') { - currentUser = prompt('Enter your username for chat:') || 'Guest'; - localStorage.setItem('currentUser', currentUser); - updateUserInterface(); - } - if (currentUser && currentUser !== 'Guest') { - onlineUsers.add(currentUser); - updateOnlineUsers(); - addChatMessage('system', `${currentUser} joined the chat!`); - } - } else { - chatPanel.style.display = 'none'; - } -} - -function sendChatMessage() { - const input = document.getElementById('chatInput'); - const message = input.value.trim(); - - if (message && currentUser) { - addChatMessage('user', message, currentUser); - input.value = ''; - - // Simulate responses for demo - setTimeout(() => { - const responses = [ - 'Interesting discovery! 🔍', - 'I\'ll help verify that! ✅', - 'Great find! 🚀', - 'Let me check the similarity...', - 'This looks promising! 💡' - ]; - const randomResponse = responses[Math.floor(Math.random() * responses.length)]; - addChatMessage('bot', randomResponse, 'LeakHub Bot'); - }, 1000 + Math.random() * 2000); - } -} - -function addChatMessage(type, message, username = 'System') { - const messagesDiv = document.getElementById('chatMessages'); - const messageDiv = document.createElement('div'); - messageDiv.className = `chat-message ${type}-message`; - - const timestamp = new Date().toLocaleTimeString(); - messageDiv.innerHTML = ` -
- ${username} - ${timestamp} -
-
${message}
- `; - - messagesDiv.appendChild(messageDiv); - messagesDiv.scrollTop = messagesDiv.scrollHeight; - - // Keep only last 50 messages - if (messagesDiv.children.length > 50) { - messagesDiv.removeChild(messagesDiv.firstChild); - } -} - -function updateOnlineUsers() { - const usersDiv = document.getElementById('chatUsers'); - const countSpan = document.getElementById('onlineCount'); - - countSpan.textContent = onlineUsers.size; - - const usersList = Array.from(onlineUsers).map(user => - `
🟢 ${user}
` - ).join(''); - - usersDiv.innerHTML = ` -
🟢 Online: ${onlineUsers.size}
-
${usersList}
- `; -} - -// Initialize chat -document.addEventListener('DOMContentLoaded', () => { - const chatInput = document.getElementById('chatInput'); - if (chatInput) { - chatInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - sendChatMessage(); - } - }); - } -}); - -// Security utility functions -function sanitizeHTML(text) { - if (typeof text !== 'string') return ''; - - // Create a temporary div to escape HTML - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; -} - -function safeInnerHTML(element, content) { - if (!element) return; - - // For simple text content, use textContent instead - if (typeof content === 'string' && !content.includes('<')) { - element.textContent = content; - return; - } - - // For HTML content, sanitize user inputs - if (typeof content === 'string') { - // This is a simplified sanitizer - in production, use a library like DOMPurify - const sanitized = content - .replace(/)<[^<]*)*<\/script>/gi, '') - .replace(/)<[^<]*)*<\/iframe>/gi, '') - .replace(/javascript:/gi, '') - .replace(/on\w+\s*=/gi, ''); - element.innerHTML = sanitized; - } -} - -// Production-Ready Features -let userPreferences = JSON.parse(localStorage.getItem('userPreferences') || '{}'); - -// Initialize production features -function initializeProductionFeatures() { - updateUserInterface(); - setupNavigation(); - loadUserPreferences(); - updateActiveUsers(); - - // Auto-save every 30 seconds - setInterval(autoSave, 30000); - - // Update stats every 10 seconds - setInterval(updateRealTimeStats, 10000); -} - -function updateUserInterface() { - // Initialize currentUser if not set - if (!currentUser || currentUser === 'Guest') { - currentUser = localStorage.getItem('currentUser') || 'Guest'; - } - - const currentUserNameEl = document.getElementById('currentUserName'); - const profileNameEl = document.getElementById('profileName'); - const userNameInputEl = document.getElementById('userNameInput'); - const activeUsersEl = document.getElementById('activeUsers'); - - if (currentUserNameEl) currentUserNameEl.textContent = currentUser; - if (profileNameEl) profileNameEl.textContent = currentUser; - if (userNameInputEl) userNameInputEl.value = currentUser; - - // Update active users count - if (activeUsersEl) { - const uniqueUsers = new Set(leakDatabase.map(sub => sub.source)); - activeUsersEl.textContent = uniqueUsers.size; - } -} - -function setupNavigation() { - // Handle navigation links - document.querySelectorAll('.nav-link').forEach(link => { - link.addEventListener('click', (e) => { - e.preventDefault(); - const target = e.target.getAttribute('href').substring(1); - scrollToSection(target); - - // Update active state - document.querySelectorAll('.nav-link').forEach(l => l.classList.remove('active')); - e.target.classList.add('active'); - }); - }); -} - -function scrollToSection(sectionId) { - const sections = { - 'submit': document.querySelector('.submission-form'), - 'library': document.querySelector('.submissions-list'), - 'compare': document.querySelector('.comparison-section'), - 'community': document.querySelector('.leaderboard-overlay'), - 'analytics': document.querySelector('.analytics-overlay') - }; - - if (sections[sectionId]) { - sections[sectionId].scrollIntoView({ behavior: 'smooth' }); - } -} - -// User Profile Functions -function toggleUserProfile() { - const overlay = document.getElementById('userProfileOverlay'); - if (overlay.style.display === 'none') { - loadUserProfile(); - overlay.style.display = 'flex'; - } else { - overlay.style.display = 'none'; - } -} - -function loadUserProfile() { - const stats = userStats[currentUser] || {}; - const userAchievements = displayAchievements(currentUser); - - // Update profile stats - document.getElementById('profileStats').innerHTML = ` -
-
${stats.submissions || 0}
-
Submissions
-
-
-
${stats.firstDiscoveries || 0}
-
First Discoveries
-
-
-
${stats.verifiedLeaks || 0}
-
Verified Leaks
-
-
-
${stats.totalScore || 0}
-
Total Score
-
- `; - - // Update achievements - document.getElementById('profileAchievements').innerHTML = userAchievements.length > 0 - ? userAchievements.map(achievement => ` -
-
${achievement.icon}
-
${achievement.name}
-
- `).join('') - : '

No achievements yet. Start submitting to earn badges!

'; -} - -// Settings Functions -function toggleSettings() { - const overlay = document.getElementById('settingsOverlay'); - if (overlay.style.display === 'none') { - overlay.style.display = 'flex'; - } else { - overlay.style.display = 'none'; - } -} - -function loadUserPreferences() { - document.getElementById('userNameInput').value = currentUser; - document.getElementById('notificationsEnabled').checked = userPreferences.notifications !== false; - document.getElementById('autoSaveEnabled').checked = userPreferences.autoSave !== false; -} - -function saveUserPreferences() { - currentUser = document.getElementById('userNameInput').value || 'Guest'; - userPreferences.notifications = document.getElementById('notificationsEnabled').checked; - userPreferences.autoSave = document.getElementById('autoSaveEnabled').checked; - - localStorage.setItem('currentUser', currentUser); - localStorage.setItem('userPreferences', JSON.stringify(userPreferences)); - - updateUserInterface(); - showAlert('Settings saved successfully!'); -} - -// Analytics Functions -function toggleAnalytics() { - const overlay = document.getElementById('analyticsOverlay'); - if (overlay.style.display === 'none') { - loadAnalytics(); - overlay.style.display = 'flex'; - } else { - overlay.style.display = 'none'; - } -} - -function loadAnalytics() { - loadPlatformStats(); - loadTargetDistribution(); - loadGrowthTrends(); - loadTopContributors(); -} - -function loadPlatformStats() { - const totalSubmissions = leakDatabase.length; - const verifiedCount = leakDatabase.filter(sub => sub.confidence >= 95).length; - const uniqueUsers = new Set(leakDatabase.map(sub => sub.source)).size; - const avgConfidence = leakDatabase.length > 0 - ? Math.round(leakDatabase.reduce((sum, sub) => sum + sub.confidence, 0) / leakDatabase.length) - : 0; - - document.getElementById('platformStats').innerHTML = ` -
-
${totalSubmissions}
-
Total Submissions
-
-
-
${verifiedCount}
-
Verified Prompts
-
-
-
${uniqueUsers}
-
Active Users
-
-
-
${avgConfidence}%
-
Avg Confidence
-
- `; -} - -function loadTargetDistribution() { - const distribution = {}; - leakDatabase.forEach(sub => { - distribution[sub.targetType] = (distribution[sub.targetType] || 0) + 1; - }); - - const chartData = Object.entries(distribution).map(([type, count]) => ` -
-
${type}
-
-
-
-
${count}
-
- `).join(''); - - document.getElementById('targetChart').innerHTML = chartData; -} - -function loadGrowthTrends() { - const last7Days = Array.from({length: 7}, (_, i) => { - const date = new Date(); - date.setDate(date.getDate() - i); - return date.toISOString().split('T')[0]; - }).reverse(); - - const dailySubmissions = last7Days.map(date => - leakDatabase.filter(sub => sub.timestamp.startsWith(date)).length - ); - - const trendData = last7Days.map((date, i) => ` -
-
${new Date(date).toLocaleDateString()}
-
${dailySubmissions[i]}
-
- `).join(''); - - document.getElementById('growthTrends').innerHTML = trendData; -} - -function loadTopContributors() { - const topUsers = Object.entries(userStats) - .sort((a, b) => b[1].totalScore - a[1].totalScore) - .slice(0, 5); - - const contributorsData = topUsers.map((user, index) => ` -
-
#${index + 1}
-
${user[0]}
-
${user[1].totalScore} pts
-
- `).join(''); - - document.getElementById('topContributors').innerHTML = contributorsData; -} - -// Data Management Functions -function exportData() { - const data = { - leakDatabase, - userStats, - leakRequests, - userVotes, - dailyChallenge, - userAchievements, - userPreferences, - exportDate: new Date().toISOString() - }; - - const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); - const url = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = `leakhub-backup-${new Date().toISOString().split('T')[0]}.json`; - a.click(); - URL.revokeObjectURL(url); - - showAlert('Data exported successfully!'); -} - -function importData() { - const input = document.createElement('input'); - input.type = 'file'; - input.accept = '.json'; - input.onchange = (e) => { - const file = e.target.files[0]; - if (file) { - const reader = new FileReader(); - reader.onload = (e) => { - try { - const data = JSON.parse(e.target.result); - - if (confirm('This will replace all current data. Are you sure?')) { - leakDatabase = data.leakDatabase || []; - userStats = data.userStats || {}; - leakRequests = data.leakRequests || []; - userVotes = data.userVotes || {}; - dailyChallenge = data.dailyChallenge || null; - userAchievements = data.userAchievements || {}; - userPreferences = data.userPreferences || {}; - - saveDatabase().then(() => { - updateUI(); - showAlert('Data imported successfully!'); - }); - } - } catch (error) { - showAlert('Error importing data. Please check the file format.'); - } - }; - reader.readAsText(file); - } - }; - input.click(); -} - -function clearAllData() { - if (confirm('This will permanently delete all data. Are you absolutely sure?')) { - leakDatabase = []; - userStats = {}; - leakRequests = []; - userVotes = {}; - dailyChallenge = null; - userAchievements = {}; - - localStorage.clear(); - updateUI(); - showAlert('All data cleared successfully!'); - } -} - -// Utility Functions -function autoSave() { - if (userPreferences.autoSave !== false) { - saveDatabase(); - console.log('Auto-saved at', new Date().toLocaleTimeString()); - } -} - -function updateRealTimeStats() { - updateActiveUsers(); - updateUI(); -} - -function updateActiveUsers() { - const uniqueUsers = new Set(leakDatabase.map(sub => sub.source)); - document.getElementById('activeUsers').textContent = uniqueUsers.size; -} - -// Enhanced notification system -function showNotification(title, message, type = 'info') { - if (userPreferences.notifications !== false) { - const notification = document.createElement('div'); - notification.className = `notification ${type}`; - notification.innerHTML = ` -
-

${title}

- -
-

${message}

- `; - - document.body.appendChild(notification); - - setTimeout(() => { - if (notification.parentElement) { - notification.remove(); - } - }, 5000); - } -} - -// Production features are now initialized in initializeApp() - -// Tab System Functions -function initializeTabSystem() { - // Set default active tab - switchTab('leaks'); -} - -function switchTab(tabName) { - // Hide all tab panels - const tabPanels = document.querySelectorAll('.tab-panel'); - tabPanels.forEach(panel => { - panel.classList.remove('active'); - }); - - // Remove active class from all nav links - const navLinks = document.querySelectorAll('.nav-link'); - navLinks.forEach(link => { - link.classList.remove('active'); - }); - - // Show selected tab panel - const selectedPanel = document.getElementById(`${tabName}-tab`); - if (selectedPanel) { - selectedPanel.classList.add('active'); - } - - // Add active class to selected nav link - const selectedLink = document.querySelector(`[onclick="switchTab('${tabName}')"]`); - if (selectedLink) { - selectedLink.classList.add('active'); - } - - // Update UI for the selected tab - updateTabUI(tabName); -} - -function updateTabUI(tabName) { - switch(tabName) { - case 'leaks': - updateSubmissionsList(); - break; - case 'validator': - updateValidationRequests(); - break; - case 'library': - updateSubmissionsList(); - break; - case 'compare': - updateComparisonDropdowns(); - break; - case 'community': - // Community features are handled by existing functions - break; - case 'analytics': - // Analytics are handled by existing functions - break; - } -} - -function updateComparisonDropdowns() { - const submission1Select = document.getElementById('submission1'); - const submission2Select = document.getElementById('submission2'); - const instanceASelect = document.getElementById('instanceA'); - const instanceBSelect = document.getElementById('instanceB'); - - if (submission1Select && submission2Select) { - updateComparisonSelect(submission1Select); - updateComparisonSelect(submission2Select); - } - - if (instanceASelect && instanceBSelect) { - updateComparisonSelect(instanceASelect); - updateComparisonSelect(instanceBSelect); - } -} - -function updateComparisonSelect(selectElement) { - const currentValue = selectElement.value; - selectElement.innerHTML = ''; - - leakDatabase.forEach((submission, index) => { - const option = document.createElement('option'); - option.value = index; - option.textContent = `${submission.instance} (${submission.targetType})`; - selectElement.appendChild(option); - }); - - if (currentValue) { - selectElement.value = currentValue; - } -} - -// Validation System Functions -function submitValidation(event) { - event.preventDefault(); - - const source = document.getElementById('validatorSourceName').value; - const validation = { - id: Date.now().toString(), - source: source, - category: document.getElementById('validationCategory').value, - title: document.getElementById('validationTitle').value, - url: document.getElementById('validationUrl').value || null, - content: document.getElementById('validationContent').value, - context: document.getElementById('validationContext').value, - relatedComponents: document.getElementById('relatedComponents').value || null, - timestamp: new Date().toISOString(), - votes: 0, - validations: 0, - confidence: 0, - status: 'pending', // pending, validated, rejected - validators: [], - comments: [] - }; - - // Calculate initial confidence - validation.confidence = calculateValidationConfidence(validation.content); - - // Add to validation requests (we'll use leakRequests for now, but could create separate storage) - if (!window.validationRequests) { - window.validationRequests = []; - } - window.validationRequests.push(validation); - - // Update user stats - if (!userStats[source]) { - userStats[source] = { - submissions: 0, - verifiedLeaks: 0, - firstDiscoveries: 0, - totalScore: 0, - joinDate: new Date().toISOString(), - toolsDiscovered: 0, - appsDiscovered: 0, - agentsDiscovered: 0, - comparisons: 0, - challengesCompleted: 0, - requestsSubmitted: 0, - validationsSubmitted: 0 - }; - } - - userStats[source].validationsSubmitted = (userStats[source].validationsSubmitted || 0) + 1; - - // Save to database - saveDatabase().then(() => { - updateValidationRequests(); - showAlert('Validation request submitted successfully!'); - - // Clear form - event.target.reset(); - }); -} - -function calculateValidationConfidence(content) { - // Simple confidence calculation based on content length and structure - let confidence = 50; // Base confidence - - if (content.length > 100) confidence += 10; - if (content.length > 500) confidence += 10; - if (content.includes('http')) confidence += 5; - if (content.includes('function') || content.includes('class')) confidence += 10; - if (content.includes('import') || content.includes('require')) confidence += 5; - - return Math.min(confidence, 100); -} - -function updateValidationRequests() { - const container = document.getElementById('validationRequests'); - if (!container || !window.validationRequests) return; - - if (window.validationRequests.length === 0) { - container.innerHTML = '

No validation requests yet. Be the first to submit!

'; - return; - } - - const requestsHTML = window.validationRequests.map(request => ` -
-
-

${request.title}

- ${request.status.toUpperCase()} -
-
- Category: ${request.category} • - Submitted by: ${request.source} • - Confidence: ${request.confidence}% -
-
- ${request.content.substring(0, 200)}${request.content.length > 200 ? '...' : ''} -
-
- - - -
-
- `).join(''); - - container.innerHTML = requestsHTML; -} - -function getStatusColor(status) { - switch(status) { - case 'pending': return 'rgba(255, 255, 0, 0.3)'; - case 'validated': return 'rgba(0, 255, 136, 0.3)'; - case 'rejected': return 'rgba(255, 0, 0, 0.3)'; - default: return 'rgba(128, 128, 128, 0.3)'; - } -} - -function validateRequest(requestId, action) { - const request = window.validationRequests.find(r => r.id === requestId); - if (!request) return; - - request.status = action; - request.validations++; - - // Update user stats for the validator - const currentUser = localStorage.getItem('currentUser') || 'Anonymous'; - if (!userStats[currentUser]) { - userStats[currentUser] = { - submissions: 0, - verifiedLeaks: 0, - firstDiscoveries: 0, - totalScore: 0, - joinDate: new Date().toISOString(), - toolsDiscovered: 0, - appsDiscovered: 0, - agentsDiscovered: 0, - comparisons: 0, - challengesCompleted: 0, - requestsSubmitted: 0, - validationsSubmitted: 0, - validationsPerformed: 0 - }; - } - - userStats[currentUser].validationsPerformed = (userStats[currentUser].validationsPerformed || 0) + 1; - - saveDatabase().then(() => { - updateValidationRequests(); - showAlert(`Request ${action} successfully!`); - }); -} - -function viewValidationDetails(requestId) { - const request = window.validationRequests.find(r => r.id === requestId); - if (!request) return; - - const details = ` -Title: ${request.title} -Category: ${request.category} -Submitted by: ${request.source} -Status: ${request.status} -Confidence: ${request.confidence}% -Timestamp: ${new Date(request.timestamp).toLocaleString()} - -Content: -${request.content} - -Context: ${request.context || 'None provided'} - -Related Components: ${request.relatedComponents || 'None provided'} - `; - - alert(details); -} - -function toggleRelatedComponents() { - const checkbox = document.getElementById('hasRelatedComponents'); - const section = document.getElementById('relatedComponentsSection'); - - if (checkbox.checked) { - section.style.display = 'block'; - } else { - section.style.display = 'none'; - } -} diff --git a/security-headers.js b/security-headers.js deleted file mode 100644 index 14e0db5..0000000 --- a/security-headers.js +++ /dev/null @@ -1,71 +0,0 @@ -// Security Headers Configuration for LeakHub -// Add these headers to your web server or CDN configuration - -const securityHeaders = { - // Prevent XSS attacks - 'X-XSS-Protection': '1; mode=block', - - // Prevent MIME type sniffing - 'X-Content-Type-Options': 'nosniff', - - // Prevent clickjacking - 'X-Frame-Options': 'DENY', - - // Strict transport security (HTTPS only) - 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', - - // Content Security Policy - 'Content-Security-Policy': [ - "default-src 'self'", - "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com", - "style-src 'self' 'unsafe-inline'", - "img-src 'self' data: https:", - "font-src 'self'", - "connect-src 'self'", - "frame-ancestors 'none'", - "base-uri 'self'", - "form-action 'self'" - ].join('; '), - - // Referrer Policy - 'Referrer-Policy': 'strict-origin-when-cross-origin', - - // Permissions Policy - 'Permissions-Policy': 'geolocation=(), microphone=(), camera=()', - - // Cache Control for sensitive pages - 'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate', - 'Pragma': 'no-cache', - 'Expires': '0' -}; - -// For different deployment platforms: - -// Vercel (vercel.json) -const vercelConfig = { - headers: Object.entries(securityHeaders).map(([key, value]) => ({ - source: '/(.*)', - headers: [{ key, value }] - })) -}; - -// Netlify (netlify.toml) -const netlifyHeaders = Object.entries(securityHeaders).map(([key, value]) => ({ - for: '/*', - [key.toLowerCase()]: value -})); - -// Express.js middleware -function securityMiddleware(req, res, next) { - Object.entries(securityHeaders).forEach(([key, value]) => { - res.setHeader(key, value); - }); - next(); -} - -module.exports = { - securityHeaders, - vercelConfig, - netlifyHeaders, - securityMiddleware -}; diff --git a/setup.mjs b/setup.mjs new file mode 100644 index 0000000..0ffb1ae --- /dev/null +++ b/setup.mjs @@ -0,0 +1,35 @@ +/** + * This script runs `npx @convex-dev/auth` to help with setting up + * environment variables for Convex Auth. + * + * You can safely delete it and remove it from package.json scripts. + */ + +import fs from "fs"; +import { config as loadEnvFile } from "dotenv"; +import { spawnSync } from "child_process"; + +if (!fs.existsSync(".env.local")) { + // Something is off, skip the script. + process.exit(0); +} + +const config = {}; +loadEnvFile({ path: ".env.local", processEnv: config }); + +const runOnceWorkflow = process.argv.includes("--once"); + +if (runOnceWorkflow && config.SETUP_SCRIPT_RAN !== undefined) { + // The script has already ran once, skip. + process.exit(0); +} + +const result = spawnSync("npx", ["@convex-dev/auth", "--skip-git-check"], { + stdio: "inherit", +}); + +if (runOnceWorkflow) { + fs.writeFileSync(".env.local", `\nSETUP_SCRIPT_RAN=1\n`, { flag: "a" }); +} + +process.exit(result.status); diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..87e9ab3 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,147 @@ +"use client"; + +import { Authenticated, Unauthenticated, useConvexAuth } from "convex/react"; +import { useNavigate, Routes, Route, useLocation } from "react-router-dom"; +import { Navbar } from "./components/navbar"; +import Leaderboard from "./pages/Leaderboard"; +import Requests from "./pages/Requests"; +import Browse from "./pages/Browse"; +import ProviderLeaks from "./pages/ProviderLeaks"; +import { LeakLibrary } from "./components/leakLibrary"; +import { SubmitLeakForm } from "./components/submitLeakForm"; +import Dashboard from "./pages/Dashboard"; + +export default function App() { + const { isLoading } = useConvexAuth(); + const navigate = useNavigate(); + const location = useLocation(); + const isHomePage = location.pathname === "/"; + + // Show only loading spinner during auth initialization + if (isLoading) { + return ( +
+
+
+ ); + } + + return ( + <> +
+ {/* Floating Grid Background */} +
+ +
+
+
+ {!isHomePage && ( +

navigate("/")} + className="text-3xl font-bold bg-linear-to-r from-[#00ff88] via-[#00aaff] to-[#ff00ff] bg-clip-text text-transparent animate-[gradientShift_5s_ease_infinite] cursor-pointer hover:opacity-80 transition-opacity" + > + LeakHub +

+ )} +
+ +
+
+ {isHomePage && ( +
+

navigate("/")} + className="text-5xl font-bold mb-4 bg-linear-to-r from-[#00ff88] via-[#00aaff] to-[#ff00ff] bg-clip-text text-transparent animate-[gradientShift_5s_ease_infinite] cursor-pointer hover:opacity-80 transition-opacity" + > + LeakHub +

+

+ The community hub for crowd-sourced system prompt leak + verification. CL4R1T4S! +

+
+ )} +
+
+ + } /> + } /> + } /> + } /> + } /> + } /> + +
+
+
+ + ); +} + +function Home() { + const navigate = useNavigate(); + return ( + <> +
+ {/* Status Bar */} + {/*
+
+ Active Targets: + 0 +
+
+ Total Submissions: + 0 +
+
+ Verified Prompts: + 0 +
+
*/} + + {/* Action Buttons */} +
+ + + +
+
+ + +
+ + +
+
+ + + + + ); +} diff --git a/src/components/leakLibrary.tsx b/src/components/leakLibrary.tsx new file mode 100644 index 0000000..a649ead --- /dev/null +++ b/src/components/leakLibrary.tsx @@ -0,0 +1,488 @@ +import { useState } from "react"; +import { useQuery } from "convex/react"; +import { api } from "../../convex/_generated/api"; + +interface LeakLibraryProps { + isUserLoggedIn?: boolean; +} + +export function LeakLibrary({ isUserLoggedIn }: LeakLibraryProps) { + const verifiedLeaks = useQuery(api.leaks.getVerifiedLeaks); + const requestsWithStatus = useQuery( + api.requests.getRequestsWithVerificationStatus, + ); + const [openSections, setOpenSections] = useState>( + new Set(["verified"]), + ); + const [openFolders, setOpenFolders] = useState>(new Set()); + const [openLeaks, setOpenLeaks] = useState>(new Set()); + const [copiedLeakId, setCopiedLeakId] = useState(null); + const [showErrorToast, setShowErrorToast] = useState(false); + + const toggleSection = (section: string) => { + setOpenSections((prev) => { + const next = new Set(prev); + if (next.has(section)) { + next.delete(section); + } else { + next.add(section); + } + return next; + }); + }; + + const toggleFolder = (provider: string) => { + setOpenFolders((prev) => { + const next = new Set(prev); + if (next.has(provider)) { + next.delete(provider); + } else { + next.add(provider); + } + return next; + }); + }; + + const toggleLeak = (leakId: string) => { + setOpenLeaks((prev) => { + const next = new Set(prev); + if (next.has(leakId)) { + next.delete(leakId); + } else { + next.add(leakId); + } + return next; + }); + }; + + const copyPrompt = async (text: string, leakId: string) => { + try { + await navigator.clipboard.writeText(text); + setCopiedLeakId(leakId); + setTimeout(() => setCopiedLeakId(null), 2000); + } catch (err) { + setShowErrorToast(true); + setTimeout(() => setShowErrorToast(false), 3000); + } + }; + + const renderRequestSection = (requests: typeof requestsWithStatus) => { + if (!requests || requests.length === 0) { + return ( +

+ No requests awaiting verification yet. +

+ ); + } + + const groupedByProvider = requests.reduce( + (acc, request) => { + if (!acc[request.provider]) { + acc[request.provider] = []; + } + acc[request.provider].push(request); + return acc; + }, + {} as Record, + ); + + return ( +
+ {Object.entries(groupedByProvider).map( + ([provider, providerRequests]) => { + const folderKey = `requests-${provider}`; + const isOpen = openFolders.has(folderKey); + return ( +
+

toggleFolder(folderKey)} + > + + ▶ + + {isOpen ? "📂" : "📁"} + {provider} + + ({providerRequests.length}) + +

+ {isOpen && ( +
+ {providerRequests.map((request) => { + // Determine status color based on confirmations + let statusColor = "text-red-400"; + let statusEmoji = "🔴"; + if (request.confirmationCount === 1) { + statusColor = "text-yellow-400"; + statusEmoji = "🟡"; + } else if (request.confirmationCount === 0) { + statusColor = "text-red-400"; + statusEmoji = "🔴"; + } + + return ( +
+
+
+ + {request.targetName} + + + {request.targetType} + +
+
+ {statusEmoji} + + {request.confirmationCount}/2 + +
+
+
+
Requested by: {request.submitterName}
+ {request.uniqueSubmitters > 0 && ( +
+ Unique submitters: {request.uniqueSubmitters} +
+ )} + {request.targetUrl && ( + + )} +
+
+ ); + })} +
+ )} +
+ ); + }, + )} +
+ ); + }; + + const renderLeakSection = ( + leaks: typeof verifiedLeaks, + sectionPrefix: string, + ) => { + if (!leaks || leaks.length === 0) { + return ( +

+ No leaks in this section yet. +

+ ); + } + + const groupedByProvider = leaks.reduce( + (acc, leak) => { + if (!acc[leak.provider]) { + acc[leak.provider] = []; + } + acc[leak.provider].push(leak); + return acc; + }, + {} as Record, + ); + + return ( +
+ {Object.entries(groupedByProvider).map(([provider, providerLeaks]) => { + const folderKey = `${sectionPrefix}-${provider}`; + const isOpen = openFolders.has(folderKey); + return ( +
+

toggleFolder(folderKey)} + > + + ▶ + + {isOpen ? "📂" : "📁"} + {provider} + + ({providerLeaks.length}) + +

+ {isOpen && ( +
+ {providerLeaks.map((leak) => { + const isLeakOpen = openLeaks.has(leak._id); + return ( +
+
toggleLeak(leak._id)} + > + + ▶ + + + {leak.targetName} + + + {leak.targetType} + +
+ {isLeakOpen && ( +
+ {/* Submitter and Verifiers Info */} + {(leak.submitterName || leak.verifierNames) && ( +
+ {leak.submitterName && ( +
+ + Submitted by: + {" "} + {leak.submitterName} +
+ )} + {leak.verifierNames && + leak.verifierNames.length > 0 && ( +
+ + ✓ Verified by: + {" "} + {leak.verifierNames.join(", ")} +
+ )} +
+ )} +
+
+ Prompt: + +
+
+
+                                  {leak.leakText}
+                                
+
+
+ {leak.leakContext && ( +
+
+ Context: +
+
+ {leak.leakContext} +
+
+ )} + {leak.url && ( +
+
+ URL: +
+ + {leak.url} + +
+ )} + {leak.accessNotes && ( +
+
+ Access Notes: +
+
+ {leak.accessNotes} +
+
+ )} +
+ {leak.requiresLogin && ( + + 🔐 Requires Login + + )} + {leak.isPaid && ( + + 💰 Paid + + )} + {leak.hasToolPrompts && ( + + 🔧 Has Tool Prompts + + )} +
+
+ )} +
+ ); + })} +
+ )} +
+ ); + })} +
+ ); + }; + + if (verifiedLeaks === undefined || requestsWithStatus === undefined) { + return ( +
+

📚 Leak Library

+
+

Loading leaks...

+
+
+
+ ); + } + const openSectionsCount = openSections.size; + + return ( +
+ {showErrorToast && ( +
+ + Failed to copy to clipboard +
+ )} +

📚 Leak Library

+ {!isUserLoggedIn && ( +
+

+ 🔒 Please sign in to submit leaks +

+
+ )} +
+ {/* Verified Leaks Section */} +
0 ? "flex-1" : "shrink-0"} min-h-0`} + > +
+

toggleSection("verified")} + > + + ▶ + + {openSections.has("verified") ? "📂" : "📁"} + Verified Leaks + + ({verifiedLeaks.length}) + +

+
+ {openSections.has("verified") && ( +
+ {renderLeakSection(verifiedLeaks, "verified")} +
+ )} +
+ + {/* Requests Awaiting Verification Section */} +
0 ? "flex-1" : "shrink-0"} min-h-0`} + > +
+

toggleSection("requests")} + > + + ▶ + + {openSections.has("requests") ? "📂" : "📁"} + Requests Awaiting Verification + + ({requestsWithStatus.length}) + +

+
+ {openSections.has("requests") && ( +
+ {renderRequestSection(requestsWithStatus)} +
+ )} +
+
+
+ ); +} diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx new file mode 100644 index 0000000..0c8bcd3 --- /dev/null +++ b/src/components/navbar.tsx @@ -0,0 +1,91 @@ +import { Github, LogOut, LayoutDashboard } from "lucide-react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { useAuthActions } from "@convex-dev/auth/react"; +import { useConvexAuth, useQuery } from "convex/react"; +import { api } from "../../convex/_generated/api"; + +export function Navbar() { + const { isAuthenticated } = useConvexAuth(); + const user = useQuery(api.users.currentUser); + const { signOut } = useAuthActions(); + + function SignOutButton() { + return ( + <> + + Sign out + + ); + } + + function SignInButton() { + const { signIn } = useAuthActions(); + return ( + + ); + } + + return ( +
+ {isAuthenticated ? ( + + + + + + {user?.name?.charAt(0).toUpperCase() ?? "U"} + + + + + + {user?.name ?? "My Account"} + + + + + + Dashboard + + + void signOut()} + className="cursor-pointer hover:bg-[#00ff88]/10 hover:text-white focus:bg-[#00ff88]/10 focus:text-white flex items-center gap-2" + > + + + + + ) : ( + + )} + + + +
+ ); +} diff --git a/src/components/submitLeakForm.tsx b/src/components/submitLeakForm.tsx new file mode 100644 index 0000000..0f4a9ac --- /dev/null +++ b/src/components/submitLeakForm.tsx @@ -0,0 +1,437 @@ +import { useState, useEffect } from "react"; +import { useQuery, useMutation } from "convex/react"; +import { api } from "../../convex/_generated/api"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Id } from "../../convex/_generated/dataModel"; + +type TargetType = "model" | "app" | "tool" | "agent" | "plugin" | "custom"; + +export function SubmitLeakForm() { + const user = useQuery(api.users.currentUser); + const insertLeak = useMutation(api.leaks.insertLeak); + const createRequest = useMutation(api.requests.createRequest); + + const [searchQuery, setSearchQuery] = useState(""); + const [selectedRequest, setSelectedRequest] = useState<{ + _id: Id<"requests">; + targetName: string; + provider: string; + targetType: TargetType; + targetUrl: string; + submitterName: string; + } | null>(null); + const [showNewRequestForm, setShowNewRequestForm] = useState(false); + + const [targetType, setTargetType] = useState(""); + const [targetName, setTargetName] = useState(""); + const [targetUrl, setTargetUrl] = useState(""); + const [provider, setProvider] = useState(""); + const [requiresLogin, setRequiresLogin] = useState(false); + const [isPaid, setIsPaid] = useState(false); + const [hasToolPrompts, setHasToolPrompts] = useState(false); + const [accessNotes, setAccessNotes] = useState(""); + const [leakText, setLeakText] = useState(""); + const [leakContext, setLeakContext] = useState(""); + const [isSubmitting, setIsSubmitting] = useState(false); + const [error, setError] = useState(null); + const [successMessage, setSuccessMessage] = useState(null); + + // Search for existing requests + const searchResults = useQuery( + api.requests.searchRequests, + searchQuery.trim() ? { searchQuery } : "skip", + ); + + // Auto-populate form when a request is selected + useEffect(() => { + if (selectedRequest) { + setTargetName(selectedRequest.targetName); + setProvider(selectedRequest.provider); + setTargetType(selectedRequest.targetType); + setTargetUrl(selectedRequest.targetUrl); + } + }, [selectedRequest]); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setError(null); + setSuccessMessage(null); + + // Validate required fields + if (!leakText.trim()) { + setError("Leak text is required"); + return; + } + + if (showNewRequestForm) { + // Validate new request fields + if ( + !targetName.trim() || + !provider.trim() || + !targetUrl.trim() || + !targetType + ) { + setError( + "Target name, provider, URL, and type are required for new submissions", + ); + return; + } + } + + setIsSubmitting(true); + + try { + let requestId: Id<"requests"> | undefined = undefined; + + // If submitting for a new request (not linked to existing), create a new request + if (showNewRequestForm && !selectedRequest) { + const requestResult = await createRequest({ + targetName, + provider, + targetType: targetType as TargetType, + targetUrl, + }); + + if (!requestResult.success) { + setError(requestResult.error); + setIsSubmitting(false); + return; + } + + requestId = requestResult.requestId; + } else if (selectedRequest) { + requestId = selectedRequest._id; + } + + // Submit the leak + const result = await insertLeak({ + targetName: selectedRequest?.targetName || targetName, + provider: selectedRequest?.provider || provider, + leakText, + targetType: selectedRequest?.targetType || (targetType as TargetType), + requestId, + requiresLogin, + isPaid, + hasToolPrompts, + accessNotes: accessNotes || undefined, + leakContext: leakContext || undefined, + url: selectedRequest?.targetUrl || targetUrl || undefined, + }); + + if (!result.success) { + setError(result.error); + setIsSubmitting(false); + return; + } + + // Success - reset form + setError(null); + setLeakText(""); + setLeakContext(""); + setAccessNotes(""); + setRequiresLogin(false); + setIsPaid(false); + setHasToolPrompts(false); + setSelectedRequest(null); + setShowNewRequestForm(false); + setTargetName(""); + setProvider(""); + setTargetUrl(""); + setTargetType(""); + + // Show success message + setSuccessMessage( + result.message || + "Leak submitted successfully! It will be reviewed for verification.", + ); + + // Clear success message after 5 seconds + setTimeout(() => setSuccessMessage(null), 5000); + } catch (error: any) { + // Fallback for unexpected errors + const errorMessage = + error?.data || + error?.message || + "Failed to submit leak. Please try again."; + setError(errorMessage); + } finally { + setIsSubmitting(false); + } + }; + + const handleSelectRequest = (request: { + _id: Id<"requests">; + targetName: string; + provider: string; + targetType: TargetType; + targetUrl: string; + submitterName: string; + }) => { + setSelectedRequest(request); + setSearchQuery(""); + setShowNewRequestForm(false); + }; + + const handleCreateNew = () => { + setSelectedRequest(null); + setShowNewRequestForm(true); + setSearchQuery(""); + }; + + return ( +
+

+ 📤 Submit Leak +

+ {error && ( +
+

⚠️ {error}

+
+ )} + {successMessage && ( +
+

✓ {successMessage}

+
+ )} +
+ {/* Search for existing requests */} + {!selectedRequest && !showNewRequestForm && ( +
+

+ 🔍 Search for Existing Requests +

+ setSearchQuery(e.target.value)} + placeholder="Search by target name (e.g., ChatGPT-4, Claude)..." + className="w-full bg-black/50 border border-white/10 rounded-lg text-[#e0e0e0] p-4 transition-all focus:outline-none focus:border-[#00ff88] focus:shadow-[0_0_20px_rgba(0,255,136,0.2)]" + /> + + {/* Search results */} + {searchResults && searchResults.length > 0 && ( +
+ {searchResults.map((request) => ( +
handleSelectRequest(request)} + className="bg-black/50 border border-white/10 rounded-lg p-4 cursor-pointer transition-all hover:border-[#00ff88] hover:shadow-[0_0_10px_rgba(0,255,136,0.2)]" + > +
+
+

+ {request.targetName} +

+

+ {request.provider} +

+

+ Requested by: {request.submitterName} +

+
+ + {request.targetType} + +
+
+ ))} +
+ )} + + {searchQuery && searchResults && searchResults.length === 0 && ( +

+ No existing requests found. Create a new one below. +

+ )} + + +
+ )} + + {/* Display selected request */} + {selectedRequest && ( +
+
+
+

+ ✓ Submitting for existing request: +

+

+ {selectedRequest.targetName} +

+

+ {selectedRequest.provider} +

+
+ +
+
+ )} + + {/* Display new submission mode */} + {showNewRequestForm && !selectedRequest && ( +
+
+
+

+ Creating new submission (no existing request) +

+
+ +
+
+ )} + + {/* Show form only after selection or new request choice */} + {(selectedRequest || showNewRequestForm) && ( + <> + {/* Display logged-in user */} +
+

Submitting as:

+
+ {user?.image && ( + {user.name} + )} +

+ {user?.name || "Loading..."} +

+
+
+ + {/* Show target details for new submissions */} + {showNewRequestForm && ( + <> + + + setTargetName(e.target.value)} + placeholder="Target name (e.g., ChatGPT-4, GitHub Copilot)" + className="bg-black/50 border border-white/10 rounded-lg text-[#e0e0e0] p-4 transition-all focus:outline-none focus:border-[#00ff88] focus:shadow-[0_0_20px_rgba(0,255,136,0.2)]" + /> + + setProvider(e.target.value)} + placeholder="Provider (e.g., OpenAI, Anthropic, Google)" + className="bg-black/50 border border-white/10 rounded-lg text-[#e0e0e0] p-4 transition-all focus:outline-none focus:border-[#00ff88] focus:shadow-[0_0_20px_rgba(0,255,136,0.2)]" + /> + + setTargetUrl(e.target.value)} + placeholder="Target URL (e.g., https://chat.openai.com)" + className="bg-black/50 border border-white/10 rounded-lg text-[#e0e0e0] p-4 transition-all focus:outline-none focus:border-[#00ff88] focus:shadow-[0_0_20px_rgba(0,255,136,0.2)]" + /> + + )} + +
+

+ 🔐 Access Requirements +

+
+ + +
+ setAccessNotes(e.target.value)} + placeholder="Additional access notes (e.g., 'Plus subscription required')" + className="w-full mt-3 bg-black/50 border border-white/10 rounded-lg text-[#e0e0e0] p-2" + /> +
+ +