diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 0000000..673fab3
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,41 @@
+/** @type {import("eslint").Linter.Config} */
+const config = {
+ parser: "@typescript-eslint/parser",
+ parserOptions: {
+ project: true,
+ },
+ plugins: ["@typescript-eslint"],
+ extends: [
+ "plugin:@next/next/recommended",
+ "plugin:@typescript-eslint/recommended-type-checked",
+ "plugin:@typescript-eslint/stylistic-type-checked",
+ ],
+ rules: {
+ // These opinionated rules are enabled in stylistic-type-checked above.
+ // Feel free to reconfigure them to your own preference.
+ "@typescript-eslint/array-type": "off",
+ "@typescript-eslint/consistent-type-definitions": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-member-access": "off",
+ "@typescript-eslint/no-unsafe-return": "off",
+ "@typescript-eslint/no-unsafe-call": "off",
+
+ "@typescript-eslint/consistent-type-imports": [
+ "warn",
+ {
+ prefer: "type-imports",
+ fixStyle: "inline-type-imports",
+ },
+ ],
+ "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
+ "@typescript-eslint/require-await": "off",
+ "@typescript-eslint/no-misused-promises": [
+ "error",
+ {
+ checksVoidReturn: { attributes: false },
+ },
+ ],
+ },
+};
+
+module.exports = config;
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 1cd4470..0000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "parser": "@typescript-eslint/parser",
- "parserOptions": {
- "project": "./tsconfig.json"
- },
- "plugins": ["@typescript-eslint"],
- "extends": ["next/core-web-vitals", "plugin:@typescript-eslint/recommended"]
-}
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index fa8557b..9217f21 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1 +1 @@
-github: pheralb
+github: pheralb
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..1d70f86
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,49 @@
+name: ⚙️ Check
+
+on:
+ push:
+ branches:
+ - main
+ - next
+ pull_request:
+ branches:
+ - main
+ - next
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup pnpm 8
+ uses: pnpm/action-setup@v2
+ with:
+ version: 8
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: Run linter
+ run: |
+ pnpm run lint
+ env:
+ SKIP_ENV_VALIDATION: true
+
+ typecheck:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup pnpm 8
+ uses: pnpm/action-setup@v2
+ with:
+ version: 8
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: Run typecheck
+ run: pnpm run typecheck
+ env:
+ SKIP_ENV_VALIDATION: true
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 48034dc..099e71a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,41 +1,50 @@
-# Dependencies =>
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
/node_modules
/.pnp
.pnp.js
-package-lock.json
-yarn.lock
-pnpm-lock.json
-# Testing =>
+# testing
/coverage
-# Database =>
+# database
/prisma/db.sqlite
/prisma/db.sqlite-journal
-# Next.js =>
+# next.js
/.next/
/out/
+next-env.d.ts
-# Production =>
+# production
/build
-# Misc =>
+# misc
.DS_Store
*.pem
-# Debug =>
+# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
-# Local env files =>
+# local env files
.env
.env*.local
-# Vercel =>
+# vercel
.vercel
-# Typescript =>
+# typescript
*.tsbuildinfo
+
+# prisma & dump files
+migrations
+dev.db
+dev.db-journal
+mysql2sqlite
+pscale*
+db_dump.sql
+dump-in-sqlite.db
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..1f4f18e
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,8 @@
+{
+ "recommendations": [
+ "esbenp.prettier-vscode",
+ "dbaeumer.vscode-eslint",
+ "dsznajder.es7-react-js-snippets",
+ "usernamehw.errorlens"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..d1b02e8
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,6 @@
+{
+ "tailwindCSS.experimental.classRegex": [
+ ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
+ ["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
+ ]
+}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 5a24d8e..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2022 Pablo Hdez
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index b717aea..524671e 100644
--- a/README.md
+++ b/README.md
@@ -1,66 +1,72 @@
-> [!IMPORTANT]
-> We are preparing a new version of Slug, including a new database.
-> **The option to create new links is closed.**
-> The new update is planned for April.
-> You can see all the changes [here](https://github.com/pheralb/slug/tree/next) 🚀
-
+
+
+
+
+
+ An open-source URL shortener built with T3 Stack.
+
+
+
+
Dashboard
+
❖
+
Roadmap
+
❖
+
Contribute
+
❖
+
Create issue
+
❖
+
X/Twitter
-
-
+
+
+
-
+
-🚀 Short link
-
•
-
🤝 Contribute
-
•
-
🐦 Twitter
-
+![Next.js Badge](https://img.shields.io/badge/Next.js 14-000?logo=nextdotjs&logoColor=fff&style=flat)
+![Turso Badge](https://img.shields.io/badge/Turso-4FF8D2?logo=turso&logoColor=000&style=flat)
+![Check workflow](https://github.com/pheralb/slug/actions/workflows/ci.yml/badge.svg)
![GitHub stars](https://img.shields.io/github/stars/pheralb/slug)
+![GitHub releases](https://img.shields.io/github/release/pheralb/slug)
![GitHub issues](https://img.shields.io/github/issues/pheralb/slug)
![GitHub license](https://img.shields.io/github/license/pheralb/slug)
-[![Required Node.JS >=16.0.0](https://img.shields.io/static/v1?label=node&message=%20%3E=16.0.0&logo=node.js&color=3f893e)](https://nodejs.org/about/releases)
-## 🤔 What is T3 Stack?
+## 👨🚀 Introduction
-The [**T3 Stack**](https://create.t3.gg/) is a web development stack made by [Theo](https://twitter.com/t3dotgg) focused on simplicity, modularity, and full-stack **typesafety**. This project is using:
+[**Slug**](slug.vercel.app) is a service that offers to shorten urls in a simple, fast and secure way. It's built with [**T3 Stack**](https://create.t3.gg/), a web development stack made by [**Theo**](https://twitter.com/t3dotgg) focused on simplicity, modularity, and full-stack **typesafety**.
-- ✅ **Bootstrapping**: [create-t3-app](https://create.t3.gg).
-- ✅ **Framework**: [Nextjs 13 + Typescript](https://nextjs.org/).
-- ✅ **Auth**: [Next-Auth.js](https://next-auth.js.org)
-- ✅ **ORM**: [Prisma](https://prisma.io).
-- ✅ **Database**: [Planetscale](https://planetscale.com/).
-- ✅ **Styling**: [TailwindCSS + HeadlessUI](https://tailwindcss.com).
-- ✅ **Typescript Schema Validation**: [Zod](https://github.com/colinhacks/zod).
-- ✅ **End-to-end typesafe API**: [tRPC](https://trpc.io/).
-- ✅ **Safely serialize JavaScript expressions**: [Superjson](https://github.com/blitz-js/superjson).
+This project uses the following technologies:
-## 📦 Project structure
+- [**create-t3-app**](https://create.t3.gg) - The best way to start a full-stack, typesafe Next.js app.
+- [**Next.js 14 App Router**](https://nextjs.org/) - The React Framework for the Web.
+- [**Auth.js v5**](https://authjs.dev/) - Authentication for the Web.
+- [**Prisma**](https://prisma.io) - A next-generation Node.js and TypeScript ORM.
+- [**Turso**](https://turso.tech/) (SQLite) + [**libSQL**](https://github.com/tursodatabase/libsql) - SQLite for Production.
+- [**Next.js Server Actions**](https://nextjs.org/docs/api-reference/server-actions) - Asynchronous functions that are executed on the server.
+- [**TailwindCSS**](https://tailwindcss.com) + [**shadcn/ui**](https://ui.shadcn.com) & [**Radix Primitives**](https://www.radix-ui.com) - Design System.
+- [**Prettier**](https://prettier.io) with [**prettier-plugin-tailwindcss**](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) - Code Formatter.
+- [**Lucide Icons**](https://lucide.dev) + [**svgl**](https://svgl.app) - Beautiful SVG icons & logos for the web.
-```
-- prisma
-- public
-- src
- |- components
- |- env
- |- layout
- |- motions
- |- pages
- |- schema
- |- server
- |- styles
- |- types
- |- ui
- |- utils
-```
+> ⚠️ This is a community project, not associated with [Vercel](https://vercel.com/).
+
+## 🚀 Getting Started
+
+**Requirements:**
-## 👨🚀 Getting Started
+- [x] [Node.js](https://nodejs.org) (+v18.x) installed.
+- [x] [pnpm](https://pnpm.io) (v8+) installed.
+- [x] [Turso CLI](https://docs.turso.tech/cli/install) installed (for Windows users, it's necessary to [activate WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install)).
+- [x] [Visual Studio Code](https://code.visualstudio.com) with the recommended extensions installed (ESLint, Prettier, Tailwind CSS IntelliSense).
-> 🚧 You will need [Nodejs +16 (LTS recommended)](https://nodejs.org/en/) installed.
+**Steps:**
1. Fork this project:
@@ -75,13 +81,11 @@ git clone git@github.com:YOU_USER/slug.git
3. Install dependencies:
```bash
-npm install
-# or
+# Install pnpm globally if you don't have it:
+npm install -g pnpm
+
+# and install dependencies:
pnpm install
-# or
-yarn install
-# or
-ultra install
```
4. Create a **.env** file with the following content:
@@ -89,50 +93,123 @@ ultra install
> 🚧 The environment variables must match the following [schema](https://github.com/pheralb/slug/blob/main/src/env/schema.mjs#L8).
```bash
-# Planetscale DB URL:
-DATABASE_URL:
+# Database:
+DATABASE_URL= # "file:./dev.db"
+TURSO_DATABASE_URL=
+TURSO_AUTH_TOKEN=
+
+# Auth.js =>
+AUTH_SECRET=
-# Github OAuth secrets:
-GITHUB_ID:
-GITHUB_CLIENT_SECRET:
+# Github Provider =>
+GITHUB_ID=
+GITHUB_CLIENT_SECRET=
-# Next Auth config:
-NEXTAUTH_SECRET:
-NEXTAUTH_URL:
+# Google Provider =>
+GOOGLE_CLIENT_ID=
+GOOGLE_CLIENT_SECRET=
```
-### 🔑 How to get environment variables:
+**Database:**
+
+- [**Create** a new database with Turso](https://docs.turso.tech/cli/db/create).
+- [Get Turso **Auth Token**](https://docs.turso.tech/cli/auth/token).
+- [Get Turso **Database URL**](https://docs.turso.tech/cli/db/show).
-**Planetscale database:**
-- [Create a new database](https://planetscale.com/docs/tutorials/planetscale-quick-start-guide#getting-started-planet-scale-dashboard).
-- [Create a dev branch](https://planetscale.com/docs/onboarding/branching-and-deploy-requests#create-a-dev-branch).
-- [In the dev branch, click on "Connect" and select "Prisma". Now you have the DATABASE_URL](https://planetscale.com/docs/concepts/connection-strings#creating-a-password).
+**Auth.js:**
-> 🚧 The environment variable in the dev branch is not the same as main. When you deploy your app to production, in the environment variables change DATABASE_URL to the main variable.
+- [Get Auth.js **Secret**](https://authjs.dev/getting-started/providers/oauth-tutorial#adding-environment-variables).
+- ``AUTH_URL`` is the URL of your Auth.js API, for example, ``/api/auth``. You can change it in the [**``auth.ts`` file**](https://github.com/pheralb/slug/blob/next/src/auth.ts#L20).
-**Github OAuth:**
-- [Click here to create new Github OAuth app](https://github.com/settings/applications/new).
-- Go to "Client secrets" and generate new client secret and and paste it into GITHUB_CLIENT_SECRET env.
-- Copy the Client ID and paste it into GITHUB_ID env.
+**Github Credentials:**
-**Next Auth:**
-- NEXTAUTH_SECRET: ``mykey123`` for example.
-- NEXTAUTH_URL: ``http://localhost:3000/``.
+- [Create a new OAuth App](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app).
-5. Ready 🥳, now run:
+**Google Credentials:**
+
+- [Create a new OAuth 2.0 App from Google API Console](https://developers.google.com/identity/protocols/oauth2?hl=es-419#1.-obtain-oauth-2.0-credentials-from-the-dynamic_data.setvar.console_name-.).
+
+5. Generate a new migration file with Prisma:
```bash
-# Push your DB to Planetscale:
-npx prisma db push
+pnpm db:migrate
+```
-# Run the project:
-npm run dev
+6. Insert the migration data into the Turso database. To do this, go to ``package.json``, modify the ``db:push`` command with the name of the migration folder (2024***xxxxxxxxxx***_init) and run it in your terminal:
-# (Optional) Run Prisma Studio to see your DB data:
-npx prisma studio
+```bash
+pnpm db:push
```
-😊 Contributing:
+7. Run:
+
+- Development server:
+
+```bash
+pnpm dev
+```
+
+and open [http://localhost:3000](http://localhost:3000) with your browser 🚀
+
+- Prisma Studio:
+
+```bash
+pnpm db:studio
+```
+
+and open [http://localhost:5555](http://localhost:5555) with your browser ✨
+
+## 🔭 Roadmap
+
+This is the roadmap I will be following for the complete migration to v3:
+
+> - *✅* = Stable, completed.
+> - *🔔* = Stable, but unexpected errors may appear.
+> - *⚙️* = In progress.
+
+⬆️ **Known issues:**
+
+- ⚙️ Fix issue when logging in with different provider but with the same email. Redirect to an existing route in the app ([authjs error](https://authjs.dev/reference/core/errors#accountnotlinked)).
+
+⬆️ **Dependencies:**
+
+- ✅ Update `@prisma/adapter-libsql`, `@prisma/client` & `prisma` to the stable version when it's released.
+- ⚙️ Update `authjs` to the stable version (v5) when it's released.
+
+⬆️ **Auth:**
+
+- ✅ Sign In with Github.
+- 🔔 Sign In with Google.
+
+🔔 Only for users who have not previously logged in with an existing email address in their Github account. This is an issue that will be worked on soon.
+
+⬆️ **Middleware:**
+
+- ✅ Redirect with `/*` and `/s/*`.
+- ✅ Separate public, protected & authentication routes.
+
+⬆️ **Dashboard (main):**
+
+- ✅ Create a new short URL.
+- ✅ List all shorted URLs.
+- ✅ Delete a shorted URL.
+- ✅ Update a shorted URL.`
+
+⬆️ **Dashboard (tags):**
+
+- ⚙️ Add search links by tags in the dashboard.
+- ⚙️ Create a new tag.
+- ⚙️ Update a tag.
+- ⚙️ Delete a tag.
+
+⬆️ **Dashboard (settings):**
+
+- ✅ Change name.
+- ✅ Change email.
+- ✅ Delete account.
+- ✅ Download all links data.
+
+## ✌️ Contributing
@@ -140,9 +217,9 @@ npx prisma studio
-## 🎉 Deploy on Vercel
+## ☁️ Deploy on Vercel
-- ✅ [https://slug.vercel.app/](https://slug.vercel.app/).
+- ✅ [slug.vercel.app](https://slug.vercel.app/).
## 🔑 License
diff --git a/components.json b/components.json
new file mode 100644
index 0000000..173ae51
--- /dev/null
+++ b/components.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": true,
+ "tsx": true,
+ "tailwind": {
+ "config": "tailwind.config.ts",
+ "css": "./src/styles/globals.css",
+ "baseColor": "neutral",
+ "cssVariables": false,
+ "prefix": ""
+ },
+ "aliases": {
+ "components": "@/ui",
+ "utils": "@/utils"
+ }
+}
\ No newline at end of file
diff --git a/next-env.d.ts b/next-env.d.ts
deleted file mode 100644
index 4f11a03..0000000
--- a/next-env.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-///
-///
-
-// NOTE: This file should not be edited
-// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/next-seo.config.ts b/next-seo.config.ts
deleted file mode 100644
index acb0eb4..0000000
--- a/next-seo.config.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-export default {
- title: "URL Shortener",
- titleTemplate: "%s - slug",
- description:
- "A URL shortener built with T3 Stack",
- defaultTitle: "slug",
- additionalLinkTags: [
- {
- rel: "icon",
- href: "/img/favicon.ico",
- },
- {
- rel: "apple-touch-icon",
- href: "/img/apple-touch-icon-180x180.png",
- sizes: "180x180",
- },
- {
- rel: "apple-touch-icon",
- href: "/img/apple-touch-icon-152x152.png",
- sizes: "152x152",
- },
- {
- rel: "apple-touch-icon",
- href: "/img/apple-touch-icon-114x114.png",
- sizes: "114x114",
- },
- {
- rel: "manifest",
- href: "/manifest.json",
- },
- {
- rel: "preload",
- href: "/fonts/inter.woff2",
- as: "font",
- type: "font/woff2",
- crossOrigin: "anonymous",
- },
- ],
- openGraph: {
- site_name: "slug",
- url: "https://slug.vercel.app/",
- type: "website",
- locale: "en_IE",
- images: [
- {
- url: "/img/banner.jpg",
- width: 1920,
- height: 1080,
- type: "image/jpg",
- },
- ],
- },
- twitter: {
- handle: "@pheralb_",
- site: "@pheralb_",
- cardType: "summary_large_image",
- },
-};
diff --git a/next.config.mjs b/next.config.mjs
index 6a22c89..be9c9d3 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,22 +1,13 @@
-import { env } from "./src/env/server.mjs";
+await import("./src/env.mjs");
-/**
- * Don't be scared of the generics here.
- * All they do is to give us autocompletion when using this.
- *
- * @template {import('next').NextConfig} T
- * @param {T} config - A generic parameter that flows through to the return type
- * @constraint {{import('next').NextConfig}}
- */
-function defineNextConfig(config) {
- return config;
-}
-
-export default defineNextConfig({
+// Next.js config:
+/** @type {import('next').NextConfig} */
+const nextConfig = {
reactStrictMode: true,
- swcMinify: true,
- i18n: {
- locales: ["en"],
- defaultLocale: "en",
+ pageExtensions: ["ts", "tsx", "js", "jsx"],
+ experimental: {
+ optimizePackageImports: ["lucide-react"],
},
-});
+};
+
+export default nextConfig;
diff --git a/package.json b/package.json
index 586dea9..8536345 100644
--- a/package.json
+++ b/package.json
@@ -1,60 +1,84 @@
{
- "name": "slug",
+ "name": "@pheralb/slug",
+ "version": "3.0.0",
"author": "@pheralb_",
"description": "A URL shortener built with T3 Stack",
- "version": "2.2.0",
"private": true,
+ "license": "MIT",
+ "type": "module",
"scripts": {
"build": "next build",
"dev": "next dev",
"lint": "next lint",
"start": "next start",
- "postinstall": "prisma generate"
+ "typecheck": "tsc --noEmit",
+ "postinstall": "pnpm db:generate",
+ "db:generate": "prisma generate",
+ "db:migrate": "prisma migrate dev --name init",
+ "db:studio": "prisma studio",
+ "db:push": "turso db shell slug < ./prisma/migrations/20240328133022_init/migration.sql",
+ "db:pscale:dump": "pscale database dump databasename databasebranch",
+ "db:turso:dump": "turso db shell databasename .dump > dump.sql"
},
"dependencies": {
- "@headlessui/react": "1.7.13",
- "@next-auth/prisma-adapter": "1.0.5",
- "@prisma/client": "4.11.0",
- "@tanstack/react-query": "4.28.0",
- "@trpc/client": "10.18.0",
- "@trpc/next": "10.18.00",
- "@trpc/react-query": "10.18.0",
- "@trpc/server": "10.18.0",
- "@uiball/loaders": "1.2.6",
- "@vercel/analytics": "0.1.11",
- "framer-motion": "10.9.1",
- "nanoid": "3.3.6",
- "next": "13.2.4",
- "next-auth": "4.20.1",
- "next-seo": "5.15.0",
- "nextjs-progressbar": "0.0.16",
+ "@auth/core": "0.28.1",
+ "@auth/prisma-adapter": "1.5.1",
+ "@hookform/resolvers": "3.3.4",
+ "@libsql/client": "0.6.0",
+ "@prisma/adapter-libsql": "5.11.0",
+ "@prisma/client": "5.11.0",
+ "@radix-ui/react-collapsible": "1.0.3",
+ "@radix-ui/react-dialog": "1.0.5",
+ "@radix-ui/react-dropdown-menu": "2.0.6",
+ "@radix-ui/react-label": "2.0.2",
+ "@radix-ui/react-popover": "1.0.7",
+ "@radix-ui/react-slot": "1.0.2",
+ "@radix-ui/react-tabs": "1.0.4",
+ "@radix-ui/react-tooltip": "1.0.7",
+ "@t3-oss/env-nextjs": "0.9.2",
+ "bcryptjs": "2.4.3",
+ "boring-avatars": "1.10.1",
+ "class-variance-authority": "0.7.0",
+ "clsx": "2.1.0",
+ "cmdk": "1.0.0",
+ "date-fns": "3.6.0",
+ "eslint-config-next": "14.1.4",
+ "js-confetti": "0.12.0",
+ "lucide-react": "0.363.0",
+ "next": "14.1.4",
+ "next-auth": "5.0.0-beta.16",
+ "next-themes": "0.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-hook-form": "7.43.8",
- "react-hot-toast": "2.4.0",
- "react-icons": "4.8.0",
- "superjson": "1.12.2",
- "superkey": "0.2.2",
- "zod": "3.21.4"
+ "react-hook-form": "7.51.2",
+ "react-qr-code": "2.0.12",
+ "sonner": "1.4.41",
+ "tailwind-merge": "2.2.2",
+ "tailwindcss-animate": "1.0.7",
+ "use-debounce": "10.0.0",
+ "zod": "3.22.4"
},
"devDependencies": {
- "@types/node": "18.15.10",
- "@types/react": "18.0.29",
- "@types/nanoid": "3.0.0",
- "@types/react-dom": "18.0.11",
- "@typescript-eslint/eslint-plugin": "5.56.0",
- "@typescript-eslint/parser": "5.56.0",
- "autoprefixer": "10.4.14",
- "eslint": "8.36.0",
- "eslint-config-next": "13.2.4",
- "postcss": "8.4.21",
- "prettier": "2.8.7",
- "prettier-plugin-tailwindcss": "0.2.5",
- "prisma": "4.11.0",
- "tailwindcss": "3.2.7",
- "typescript": "5.0.2"
+ "@tailwindcss/typography": "0.5.12",
+ "@types/bcryptjs": "2.4.6",
+ "@types/eslint": "8.56.6",
+ "@types/node": "20.12.2",
+ "@types/react": "18.2.73",
+ "@types/react-dom": "18.2.23",
+ "@types/uuid": "9.0.8",
+ "@typescript-eslint/eslint-plugin": "7.4.0",
+ "@typescript-eslint/parser": "7.4.0",
+ "autoprefixer": "10.4.19",
+ "eslint": "8.57.0",
+ "postcss": "8.4.38",
+ "prettier": "3.2.5",
+ "prettier-plugin-tailwindcss": "0.5.13",
+ "prisma": "5.11.0",
+ "tailwindcss": "3.4.3",
+ "typescript": "5.4.3"
},
"ct3aMetadata": {
- "initVersion": "6.10.2"
- }
+ "initVersion": "7.25.0"
+ },
+ "packageManager": "pnpm@8.15.5"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..d9736ca
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,4411 @@
+lockfileVersion: '6.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+dependencies:
+ '@auth/core':
+ specifier: 0.28.1
+ version: 0.28.1
+ '@auth/prisma-adapter':
+ specifier: 1.5.1
+ version: 1.5.1(@prisma/client@5.11.0)
+ '@hookform/resolvers':
+ specifier: 3.3.4
+ version: 3.3.4(react-hook-form@7.51.2)
+ '@libsql/client':
+ specifier: 0.6.0
+ version: 0.6.0
+ '@prisma/adapter-libsql':
+ specifier: 5.11.0
+ version: 5.11.0(@libsql/client@0.6.0)
+ '@prisma/client':
+ specifier: 5.11.0
+ version: 5.11.0(prisma@5.11.0)
+ '@radix-ui/react-collapsible':
+ specifier: 1.0.3
+ version: 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-dialog':
+ specifier: 1.0.5
+ version: 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-dropdown-menu':
+ specifier: 2.0.6
+ version: 2.0.6(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-label':
+ specifier: 2.0.2
+ version: 2.0.2(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-popover':
+ specifier: 1.0.7
+ version: 1.0.7(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot':
+ specifier: 1.0.2
+ version: 1.0.2(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-tabs':
+ specifier: 1.0.4
+ version: 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-tooltip':
+ specifier: 1.0.7
+ version: 1.0.7(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@t3-oss/env-nextjs':
+ specifier: 0.9.2
+ version: 0.9.2(typescript@5.4.3)(zod@3.22.4)
+ bcryptjs:
+ specifier: 2.4.3
+ version: 2.4.3
+ boring-avatars:
+ specifier: 1.10.1
+ version: 1.10.1
+ class-variance-authority:
+ specifier: 0.7.0
+ version: 0.7.0
+ clsx:
+ specifier: 2.1.0
+ version: 2.1.0
+ cmdk:
+ specifier: 1.0.0
+ version: 1.0.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ date-fns:
+ specifier: 3.6.0
+ version: 3.6.0
+ eslint-config-next:
+ specifier: 14.1.4
+ version: 14.1.4(eslint@8.57.0)(typescript@5.4.3)
+ js-confetti:
+ specifier: 0.12.0
+ version: 0.12.0
+ lucide-react:
+ specifier: 0.363.0
+ version: 0.363.0(react@18.2.0)
+ next:
+ specifier: 14.1.4
+ version: 14.1.4(react-dom@18.2.0)(react@18.2.0)
+ next-auth:
+ specifier: 5.0.0-beta.16
+ version: 5.0.0-beta.16(next@14.1.4)(react@18.2.0)
+ next-themes:
+ specifier: 0.3.0
+ version: 0.3.0(react-dom@18.2.0)(react@18.2.0)
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+ react-hook-form:
+ specifier: 7.51.2
+ version: 7.51.2(react@18.2.0)
+ react-qr-code:
+ specifier: 2.0.12
+ version: 2.0.12(react@18.2.0)
+ sonner:
+ specifier: 1.4.41
+ version: 1.4.41(react-dom@18.2.0)(react@18.2.0)
+ tailwind-merge:
+ specifier: 2.2.2
+ version: 2.2.2
+ tailwindcss-animate:
+ specifier: 1.0.7
+ version: 1.0.7(tailwindcss@3.4.3)
+ use-debounce:
+ specifier: 10.0.0
+ version: 10.0.0(react@18.2.0)
+ zod:
+ specifier: 3.22.4
+ version: 3.22.4
+
+devDependencies:
+ '@tailwindcss/typography':
+ specifier: 0.5.12
+ version: 0.5.12(tailwindcss@3.4.3)
+ '@types/bcryptjs':
+ specifier: 2.4.6
+ version: 2.4.6
+ '@types/eslint':
+ specifier: 8.56.6
+ version: 8.56.6
+ '@types/node':
+ specifier: 20.12.2
+ version: 20.12.2
+ '@types/react':
+ specifier: 18.2.73
+ version: 18.2.73
+ '@types/react-dom':
+ specifier: 18.2.23
+ version: 18.2.23
+ '@types/uuid':
+ specifier: 9.0.8
+ version: 9.0.8
+ '@typescript-eslint/eslint-plugin':
+ specifier: 7.4.0
+ version: 7.4.0(@typescript-eslint/parser@7.4.0)(eslint@8.57.0)(typescript@5.4.3)
+ '@typescript-eslint/parser':
+ specifier: 7.4.0
+ version: 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+ autoprefixer:
+ specifier: 10.4.19
+ version: 10.4.19(postcss@8.4.38)
+ eslint:
+ specifier: 8.57.0
+ version: 8.57.0
+ postcss:
+ specifier: 8.4.38
+ version: 8.4.38
+ prettier:
+ specifier: 3.2.5
+ version: 3.2.5
+ prettier-plugin-tailwindcss:
+ specifier: 0.5.13
+ version: 0.5.13(prettier@3.2.5)
+ prisma:
+ specifier: 5.11.0
+ version: 5.11.0
+ tailwindcss:
+ specifier: 3.4.3
+ version: 3.4.3
+ typescript:
+ specifier: 5.4.3
+ version: 5.4.3
+
+packages:
+
+ /@aashutoshrathi/word-wrap@1.2.6:
+ resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
+ engines: {node: '>=0.10.0'}
+
+ /@alloc/quick-lru@5.2.0:
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
+ /@auth/core@0.28.1:
+ resolution: {integrity: sha512-gvp74mypYZADpTlfGRp6HE0G3pIHWvtJpy+KZ+8FvY0cmlIpHog+jdMOdd29dQtLtN25kF2YbfHsesCFuGUQbg==}
+ 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
+ dependencies:
+ '@panva/hkdf': 1.1.1
+ '@types/cookie': 0.6.0
+ cookie: 0.6.0
+ jose: 5.2.3
+ oauth4webapi: 2.10.4
+ preact: 10.11.3
+ preact-render-to-string: 5.2.3(preact@10.11.3)
+ dev: false
+
+ /@auth/prisma-adapter@1.5.1(@prisma/client@5.11.0):
+ resolution: {integrity: sha512-qie27TFTc2XDb9YPwNCSA/sCHaykMr4IHhAzQpTry0XTNftsFLWkni1zc+4OzkAJ7c82QU9LbGRISGLc+DiN5Q==}
+ peerDependencies:
+ '@prisma/client': '>=2.26.0 || >=3 || >=4 || >=5'
+ dependencies:
+ '@auth/core': 0.28.1
+ '@prisma/client': 5.11.0(prisma@5.11.0)
+ transitivePeerDependencies:
+ - '@simplewebauthn/browser'
+ - '@simplewebauthn/server'
+ - nodemailer
+ dev: false
+
+ /@babel/runtime@7.24.1:
+ resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ regenerator-runtime: 0.14.1
+ dev: false
+
+ /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0):
+ resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ dependencies:
+ eslint: 8.57.0
+ eslint-visitor-keys: 3.4.3
+
+ /@eslint-community/regexpp@4.10.0:
+ resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+ /@eslint/eslintrc@2.1.4:
+ resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.3.4
+ espree: 9.6.1
+ globals: 13.24.0
+ ignore: 5.3.1
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ /@eslint/js@8.57.0:
+ resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ /@floating-ui/core@1.6.0:
+ resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==}
+ dependencies:
+ '@floating-ui/utils': 0.2.1
+ dev: false
+
+ /@floating-ui/dom@1.6.3:
+ resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==}
+ dependencies:
+ '@floating-ui/core': 1.6.0
+ '@floating-ui/utils': 0.2.1
+ dev: false
+
+ /@floating-ui/react-dom@2.0.8(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+ dependencies:
+ '@floating-ui/dom': 1.6.3
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@floating-ui/utils@0.2.1:
+ resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==}
+ dev: false
+
+ /@hookform/resolvers@3.3.4(react-hook-form@7.51.2):
+ resolution: {integrity: sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==}
+ peerDependencies:
+ react-hook-form: ^7.0.0
+ dependencies:
+ react-hook-form: 7.51.2(react@18.2.0)
+ dev: false
+
+ /@humanwhocodes/config-array@0.11.14:
+ resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
+ engines: {node: '>=10.10.0'}
+ dependencies:
+ '@humanwhocodes/object-schema': 2.0.2
+ debug: 4.3.4
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ /@humanwhocodes/module-importer@1.0.1:
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ /@humanwhocodes/object-schema@2.0.2:
+ resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==}
+
+ /@isaacs/cliui@8.0.2:
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: /string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: /strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: /wrap-ansi@7.0.0
+
+ /@jridgewell/gen-mapping@0.3.5:
+ resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+ '@jridgewell/trace-mapping': 0.3.25
+
+ /@jridgewell/resolve-uri@3.1.2:
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ /@jridgewell/set-array@1.2.1:
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
+ /@jridgewell/sourcemap-codec@1.4.15:
+ resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+
+ /@jridgewell/trace-mapping@0.3.25:
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.4.15
+
+ /@libsql/client@0.6.0:
+ resolution: {integrity: sha512-qhQzTG/y2IEVbL3+9PULDvlQFWJ/RnjFXECr/Nc3nRngGiiMysDaOV5VUzYk7DulUX98EA4wi+z3FspKrUplUA==}
+ dependencies:
+ '@libsql/core': 0.6.0
+ '@libsql/hrana-client': 0.6.0
+ js-base64: 3.7.7
+ libsql: 0.3.10
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
+ /@libsql/core@0.6.0:
+ resolution: {integrity: sha512-affAB8vSqQwqI9NBDJ5uJCVaHoOAS2pOpbv1kWConh1SBbmJBnHHd4KG73RAJ2sgd2+NbT9WA+XJBqxgp28YSw==}
+ dependencies:
+ js-base64: 3.7.7
+ dev: false
+
+ /@libsql/darwin-arm64@0.3.10:
+ resolution: {integrity: sha512-RaexEFfPAFogd6dJlqkpCkTxdr6K14Z0286lodIJ8Ny77mWuWyBkWKxf70OYWXXAMxMJFUW+6al1F3/Osf/pTg==}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@libsql/darwin-x64@0.3.10:
+ resolution: {integrity: sha512-SNVN6n4qNUdMW1fJMFmx4qn4n5RnXsxjFbczpkzG/V7m/5VeTFt1chhGcrahTHCr3+K6eRJWJUEQHRGqjBwPkw==}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@libsql/hrana-client@0.6.0:
+ resolution: {integrity: sha512-k+fqzdjqg3IvWfKmVJK5StsbjeTcyNAXFelUbXbGNz3yH1gEVT9mZ6kmhsIXP30ZSyVV0AE1Gi25p82mxC9hwg==}
+ dependencies:
+ '@libsql/isomorphic-fetch': 0.2.1
+ '@libsql/isomorphic-ws': 0.1.5
+ js-base64: 3.7.7
+ node-fetch: 3.3.2
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
+ /@libsql/isomorphic-fetch@0.2.1:
+ resolution: {integrity: sha512-Sv07QP1Aw8A5OOrmKgRUBKe2fFhF2hpGJhtHe3d1aRnTESZCGkn//0zDycMKTGamVWb3oLYRroOsCV8Ukes9GA==}
+ dev: false
+
+ /@libsql/isomorphic-ws@0.1.5:
+ resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==}
+ dependencies:
+ '@types/ws': 8.5.10
+ ws: 8.16.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
+ /@libsql/linux-arm64-gnu@0.3.10:
+ resolution: {integrity: sha512-2uXpi9d8qtyIOr7pyG4a88j6YXgemyIHEs2Wbp+PPletlCIPsFS+E7IQHbz8VwTohchOzcokGUm1Bc5QC+A7wg==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@libsql/linux-arm64-musl@0.3.10:
+ resolution: {integrity: sha512-72SN1FUavLvzHddCS861ynSpQndcW5oLGKA3U8CyMfgIZIwJAPc7+48Uj1plW00htXBx4GBpcntFp68KKIx3YQ==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@libsql/linux-x64-gnu@0.3.10:
+ resolution: {integrity: sha512-hXyNqVRi7ONuyWZ1SX6setxL0QaQ7InyS3bHLupsi9s7NpOGD5vcpTaYicJOqmIIm+6kt8vJfmo7ZxlarIHy7Q==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@libsql/linux-x64-musl@0.3.10:
+ resolution: {integrity: sha512-kNmIRxomVwt9S+cLyYS497F/3gXFF4r8wW12YSBQgxG75JYft07AHVd8J7HINg+oqRkLzT0s+mVX5dM6nk68EQ==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@libsql/win32-x64-msvc@0.3.10:
+ resolution: {integrity: sha512-c/6rjdtGULKrJkLgfLobFefObfOtxjXGmCfPxv6pr0epPCeUEssfDbDIeEH9fQUgzogIMWEHwT8so52UJ/iT1Q==}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@neon-rs/load@0.0.4:
+ resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==}
+ dev: false
+
+ /@next/env@14.1.4:
+ resolution: {integrity: sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ==}
+ dev: false
+
+ /@next/eslint-plugin-next@14.1.4:
+ resolution: {integrity: sha512-n4zYNLSyCo0Ln5b7qxqQeQ34OZKXwgbdcx6kmkQbywr+0k6M3Vinft0T72R6CDAcDrne2IAgSud4uWCzFgc5HA==}
+ dependencies:
+ glob: 10.3.10
+ dev: false
+
+ /@next/swc-darwin-arm64@14.1.4:
+ resolution: {integrity: sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-darwin-x64@14.1.4:
+ resolution: {integrity: sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-arm64-gnu@14.1.4:
+ resolution: {integrity: sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-arm64-musl@14.1.4:
+ resolution: {integrity: sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-x64-gnu@14.1.4:
+ resolution: {integrity: sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-x64-musl@14.1.4:
+ resolution: {integrity: sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-arm64-msvc@14.1.4:
+ resolution: {integrity: sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-ia32-msvc@14.1.4:
+ resolution: {integrity: sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw==}
+ engines: {node: '>= 10'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-x64-msvc@14.1.4:
+ resolution: {integrity: sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@nodelib/fs.scandir@2.1.5:
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ /@nodelib/fs.stat@2.0.5:
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ /@nodelib/fs.walk@1.2.8:
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.17.1
+
+ /@panva/hkdf@1.1.1:
+ resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==}
+ dev: false
+
+ /@pkgjs/parseargs@0.11.0:
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+ requiresBuild: true
+ optional: true
+
+ /@prisma/adapter-libsql@5.11.0(@libsql/client@0.6.0):
+ resolution: {integrity: sha512-Q2GxamPew8AviqO/6kQskqvuh4Y0bGj8hbMefjD2+3Q3geNfE/W6XbfH0tHLOK6gQgawoAONrRgbRfoJPzUvQA==}
+ peerDependencies:
+ '@libsql/client': ^0.3.5 || ^0.4.0 || ^0.5.0
+ dependencies:
+ '@libsql/client': 0.6.0
+ '@prisma/driver-adapter-utils': 5.11.0
+ async-mutex: 0.4.1
+ dev: false
+
+ /@prisma/client@5.11.0(prisma@5.11.0):
+ resolution: {integrity: sha512-SWshvS5FDXvgJKM/a0y9nDC1rqd7KG0Q6ZVzd+U7ZXK5soe73DJxJJgbNBt2GNXOa+ysWB4suTpdK5zfFPhwiw==}
+ engines: {node: '>=16.13'}
+ requiresBuild: true
+ peerDependencies:
+ prisma: '*'
+ peerDependenciesMeta:
+ prisma:
+ optional: true
+ dependencies:
+ prisma: 5.11.0
+ dev: false
+
+ /@prisma/debug@5.11.0:
+ resolution: {integrity: sha512-N6yYr3AbQqaiUg+OgjkdPp3KPW1vMTAgtKX6+BiB/qB2i1TjLYCrweKcUjzOoRM5BriA4idrkTej9A9QqTfl3A==}
+
+ /@prisma/driver-adapter-utils@5.11.0:
+ resolution: {integrity: sha512-C2Qa/HZXZNwDBZCHJxlV4eibqXakbOBLd+mUeNCxSfaM8yi8Qi8zToN8Kb3M60Kr1ymr+tzzw/wVqYIfIfUiXw==}
+ dependencies:
+ '@prisma/debug': 5.11.0
+ dev: false
+
+ /@prisma/engines-version@5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102:
+ resolution: {integrity: sha512-WXCuyoymvrS4zLz4wQagSsc3/nE6CHy8znyiMv8RKazKymOMd5o9FP5RGwGHAtgoxd+aB/BWqxuP/Ckfu7/3MA==}
+
+ /@prisma/engines@5.11.0:
+ resolution: {integrity: sha512-gbrpQoBTYWXDRqD+iTYMirDlF9MMlQdxskQXbhARhG6A/uFQjB7DZMYocMQLoiZXO/IskfDOZpPoZE8TBQKtEw==}
+ requiresBuild: true
+ dependencies:
+ '@prisma/debug': 5.11.0
+ '@prisma/engines-version': 5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102
+ '@prisma/fetch-engine': 5.11.0
+ '@prisma/get-platform': 5.11.0
+
+ /@prisma/fetch-engine@5.11.0:
+ resolution: {integrity: sha512-994viazmHTJ1ymzvWugXod7dZ42T2ROeFuH6zHPcUfp/69+6cl5r9u3NFb6bW8lLdNjwLYEVPeu3hWzxpZeC0w==}
+ dependencies:
+ '@prisma/debug': 5.11.0
+ '@prisma/engines-version': 5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102
+ '@prisma/get-platform': 5.11.0
+
+ /@prisma/get-platform@5.11.0:
+ resolution: {integrity: sha512-rxtHpMLxNTHxqWuGOLzR2QOyQi79rK1u1XYAVLZxDGTLz/A+uoDnjz9veBFlicrpWjwuieM4N6jcnjj/DDoidw==}
+ dependencies:
+ '@prisma/debug': 5.11.0
+
+ /@radix-ui/primitive@1.0.1:
+ resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==}
+ dependencies:
+ '@babel/runtime': 7.24.1
+ dev: false
+
+ /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-context@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ aria-hidden: 1.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ react-remove-scroll: 2.5.5(@types/react@18.2.73)(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-direction@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-dropdown-menu@2.0.6(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-menu': 2.0.6(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-id@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-label@2.0.2(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-menu@2.0.6(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ aria-hidden: 1.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ react-remove-scroll: 2.5.5(@types/react@18.2.73)(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ aria-hidden: 1.2.4
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ react-remove-scroll: 2.5.5(@types/react@18.2.73)(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/rect': 1.0.1
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-slot@1.0.2(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/rect': 1.0.1
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-use-size@1.0.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0)
+ '@types/react': 18.2.73
+ react: 18.2.0
+ dev: false
+
+ /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.1
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@types/react': 18.2.73
+ '@types/react-dom': 18.2.23
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /@radix-ui/rect@1.0.1:
+ resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==}
+ dependencies:
+ '@babel/runtime': 7.24.1
+ dev: false
+
+ /@rushstack/eslint-patch@1.10.1:
+ resolution: {integrity: sha512-S3Kq8e7LqxkA9s7HKLqXGTGck1uwis5vAXan3FnU5yw1Ec5hsSGnq4s/UCaSqABPOnOTg7zASLyst7+ohgWexg==}
+ dev: false
+
+ /@swc/helpers@0.5.2:
+ resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==}
+ dependencies:
+ tslib: 2.6.2
+ dev: false
+
+ /@t3-oss/env-core@0.9.2(typescript@5.4.3)(zod@3.22.4):
+ resolution: {integrity: sha512-KgWXljUTHgO3o7GMZQPAD5+P+HqpauMNNHowlm7V2b9IeMitSUpNKwG6xQrup/xARWHTdxRVIl0mSI4wCevQhQ==}
+ peerDependencies:
+ typescript: '>=5.0.0'
+ zod: ^3.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ typescript: 5.4.3
+ zod: 3.22.4
+ dev: false
+
+ /@t3-oss/env-nextjs@0.9.2(typescript@5.4.3)(zod@3.22.4):
+ resolution: {integrity: sha512-dklHrgKLESStNVB67Jdbu6osxDYA+xNKaPBRerlnkEvzbCccSKMvZENx6EZebJuR4snqB3/yRykNMn/bdIAyiQ==}
+ peerDependencies:
+ typescript: '>=5.0.0'
+ zod: ^3.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@t3-oss/env-core': 0.9.2(typescript@5.4.3)(zod@3.22.4)
+ typescript: 5.4.3
+ zod: 3.22.4
+ dev: false
+
+ /@tailwindcss/typography@0.5.12(tailwindcss@3.4.3):
+ resolution: {integrity: sha512-CNwpBpconcP7ppxmuq3qvaCxiRWnbhANpY/ruH4L5qs2GCiVDJXde/pjj2HWPV1+Q4G9+V/etrwUYopdcjAlyg==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders'
+ dependencies:
+ lodash.castarray: 4.4.0
+ lodash.isplainobject: 4.0.6
+ lodash.merge: 4.6.2
+ postcss-selector-parser: 6.0.10
+ tailwindcss: 3.4.3
+ dev: true
+
+ /@types/bcryptjs@2.4.6:
+ resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==}
+ dev: true
+
+ /@types/cookie@0.6.0:
+ resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
+ dev: false
+
+ /@types/eslint@8.56.6:
+ resolution: {integrity: sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==}
+ dependencies:
+ '@types/estree': 1.0.5
+ '@types/json-schema': 7.0.15
+ dev: true
+
+ /@types/estree@1.0.5:
+ resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
+ dev: true
+
+ /@types/json-schema@7.0.15:
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+ dev: true
+
+ /@types/json5@0.0.29:
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+ dev: false
+
+ /@types/node@20.12.2:
+ resolution: {integrity: sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==}
+ dependencies:
+ undici-types: 5.26.5
+
+ /@types/prop-types@15.7.12:
+ resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
+
+ /@types/react-dom@18.2.23:
+ resolution: {integrity: sha512-ZQ71wgGOTmDYpnav2knkjr3qXdAFu0vsk8Ci5w3pGAIdj7/kKAyn+VsQDhXsmzzzepAiI9leWMmubXz690AI/A==}
+ dependencies:
+ '@types/react': 18.2.73
+
+ /@types/react@18.2.73:
+ resolution: {integrity: sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA==}
+ dependencies:
+ '@types/prop-types': 15.7.12
+ csstype: 3.1.3
+
+ /@types/semver@7.5.8:
+ resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
+ dev: true
+
+ /@types/uuid@9.0.8:
+ resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
+ dev: true
+
+ /@types/ws@8.5.10:
+ resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
+ dependencies:
+ '@types/node': 20.12.2
+ dev: false
+
+ /@typescript-eslint/eslint-plugin@7.4.0(@typescript-eslint/parser@7.4.0)(eslint@8.57.0)(typescript@5.4.3):
+ resolution: {integrity: sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^7.0.0
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@eslint-community/regexpp': 4.10.0
+ '@typescript-eslint/parser': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+ '@typescript-eslint/scope-manager': 7.4.0
+ '@typescript-eslint/type-utils': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+ '@typescript-eslint/utils': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+ '@typescript-eslint/visitor-keys': 7.4.0
+ debug: 4.3.4
+ eslint: 8.57.0
+ graphemer: 1.4.0
+ ignore: 5.3.1
+ natural-compare: 1.4.0
+ semver: 7.6.0
+ ts-api-utils: 1.3.0(typescript@5.4.3)
+ typescript: 5.4.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3):
+ resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 6.21.0
+ '@typescript-eslint/types': 6.21.0
+ '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.3)
+ '@typescript-eslint/visitor-keys': 6.21.0
+ debug: 4.3.4
+ eslint: 8.57.0
+ typescript: 5.4.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /@typescript-eslint/parser@7.4.0(eslint@8.57.0)(typescript@5.4.3):
+ resolution: {integrity: sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 7.4.0
+ '@typescript-eslint/types': 7.4.0
+ '@typescript-eslint/typescript-estree': 7.4.0(typescript@5.4.3)
+ '@typescript-eslint/visitor-keys': 7.4.0
+ debug: 4.3.4
+ eslint: 8.57.0
+ typescript: 5.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ /@typescript-eslint/scope-manager@6.21.0:
+ resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.21.0
+ '@typescript-eslint/visitor-keys': 6.21.0
+ dev: false
+
+ /@typescript-eslint/scope-manager@7.4.0:
+ resolution: {integrity: sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ dependencies:
+ '@typescript-eslint/types': 7.4.0
+ '@typescript-eslint/visitor-keys': 7.4.0
+
+ /@typescript-eslint/type-utils@7.4.0(eslint@8.57.0)(typescript@5.4.3):
+ resolution: {integrity: sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/typescript-estree': 7.4.0(typescript@5.4.3)
+ '@typescript-eslint/utils': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+ debug: 4.3.4
+ eslint: 8.57.0
+ ts-api-utils: 1.3.0(typescript@5.4.3)
+ typescript: 5.4.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/types@6.21.0:
+ resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dev: false
+
+ /@typescript-eslint/types@7.4.0:
+ resolution: {integrity: sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+
+ /@typescript-eslint/typescript-estree@6.21.0(typescript@5.4.3):
+ resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 6.21.0
+ '@typescript-eslint/visitor-keys': 6.21.0
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ minimatch: 9.0.3
+ semver: 7.6.0
+ ts-api-utils: 1.3.0(typescript@5.4.3)
+ typescript: 5.4.3
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /@typescript-eslint/typescript-estree@7.4.0(typescript@5.4.3):
+ resolution: {integrity: sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 7.4.0
+ '@typescript-eslint/visitor-keys': 7.4.0
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ minimatch: 9.0.3
+ semver: 7.6.0
+ ts-api-utils: 1.3.0(typescript@5.4.3)
+ typescript: 5.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ /@typescript-eslint/utils@7.4.0(eslint@8.57.0)(typescript@5.4.3):
+ resolution: {integrity: sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
+ '@types/json-schema': 7.0.15
+ '@types/semver': 7.5.8
+ '@typescript-eslint/scope-manager': 7.4.0
+ '@typescript-eslint/types': 7.4.0
+ '@typescript-eslint/typescript-estree': 7.4.0(typescript@5.4.3)
+ eslint: 8.57.0
+ semver: 7.6.0
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
+ /@typescript-eslint/visitor-keys@6.21.0:
+ resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ dependencies:
+ '@typescript-eslint/types': 6.21.0
+ eslint-visitor-keys: 3.4.3
+ dev: false
+
+ /@typescript-eslint/visitor-keys@7.4.0:
+ resolution: {integrity: sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ dependencies:
+ '@typescript-eslint/types': 7.4.0
+ eslint-visitor-keys: 3.4.3
+
+ /@ungap/structured-clone@1.2.0:
+ resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
+
+ /acorn-jsx@5.3.2(acorn@8.11.3):
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ acorn: 8.11.3
+
+ /acorn@8.11.3:
+ resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ /ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ /ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ /ansi-regex@6.0.1:
+ resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
+ engines: {node: '>=12'}
+
+ /ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+ dependencies:
+ color-convert: 2.0.1
+
+ /ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
+ /any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ /anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ /arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ /argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ /aria-hidden@1.2.4:
+ resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
+ engines: {node: '>=10'}
+ dependencies:
+ tslib: 2.6.2
+ dev: false
+
+ /aria-query@5.3.0:
+ resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
+ dependencies:
+ dequal: 2.0.3
+ dev: false
+
+ /array-buffer-byte-length@1.0.1:
+ resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ is-array-buffer: 3.0.4
+ dev: false
+
+ /array-includes@3.1.8:
+ resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-object-atoms: 1.0.0
+ get-intrinsic: 1.2.4
+ is-string: 1.0.7
+ dev: false
+
+ /array-union@2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
+
+ /array.prototype.findlast@1.2.5:
+ resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ es-shim-unscopables: 1.0.2
+ dev: false
+
+ /array.prototype.findlastindex@1.2.5:
+ resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ es-shim-unscopables: 1.0.2
+ dev: false
+
+ /array.prototype.flat@1.3.2:
+ resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-shim-unscopables: 1.0.2
+ dev: false
+
+ /array.prototype.flatmap@1.3.2:
+ resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-shim-unscopables: 1.0.2
+ dev: false
+
+ /array.prototype.toreversed@1.1.2:
+ resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-shim-unscopables: 1.0.2
+ dev: false
+
+ /array.prototype.tosorted@1.1.3:
+ resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-shim-unscopables: 1.0.2
+ dev: false
+
+ /arraybuffer.prototype.slice@1.0.3:
+ resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ array-buffer-byte-length: 1.0.1
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ is-array-buffer: 3.0.4
+ is-shared-array-buffer: 1.0.3
+ dev: false
+
+ /ast-types-flow@0.0.8:
+ resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
+ dev: false
+
+ /async-mutex@0.4.1:
+ resolution: {integrity: sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA==}
+ dependencies:
+ tslib: 2.6.2
+ dev: false
+
+ /autoprefixer@10.4.19(postcss@8.4.38):
+ resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+ dependencies:
+ browserslist: 4.23.0
+ caniuse-lite: 1.0.30001600
+ fraction.js: 4.3.7
+ normalize-range: 0.1.2
+ picocolors: 1.0.0
+ postcss: 8.4.38
+ postcss-value-parser: 4.2.0
+ dev: true
+
+ /available-typed-arrays@1.0.7:
+ resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ possible-typed-array-names: 1.0.0
+ dev: false
+
+ /axe-core@4.7.0:
+ resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==}
+ engines: {node: '>=4'}
+ dev: false
+
+ /axobject-query@3.2.1:
+ resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==}
+ dependencies:
+ dequal: 2.0.3
+ dev: false
+
+ /balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ /bcryptjs@2.4.3:
+ resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
+ dev: false
+
+ /binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ /boring-avatars@1.10.1:
+ resolution: {integrity: sha512-WcgHDeLrazCR03CDPEvCchLsUecZAZvs4F6FnMiGlTEjyQQf15Q5TRl4EUaAQ1dacvhPq7lC9EOTWkCojQ6few==}
+ dev: false
+
+ /brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ /brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+ dependencies:
+ balanced-match: 1.0.2
+
+ /braces@3.0.2:
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ engines: {node: '>=8'}
+ dependencies:
+ fill-range: 7.0.1
+
+ /browserslist@4.23.0:
+ resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+ dependencies:
+ caniuse-lite: 1.0.30001600
+ electron-to-chromium: 1.4.722
+ node-releases: 2.0.14
+ update-browserslist-db: 1.0.13(browserslist@4.23.0)
+ dev: true
+
+ /busboy@1.6.0:
+ resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
+ engines: {node: '>=10.16.0'}
+ dependencies:
+ streamsearch: 1.1.0
+ dev: false
+
+ /call-bind@1.0.7:
+ resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ set-function-length: 1.2.2
+ dev: false
+
+ /callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ /camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
+ /caniuse-lite@1.0.30001600:
+ resolution: {integrity: sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==}
+
+ /chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ /chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.2
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ /class-variance-authority@0.7.0:
+ resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==}
+ dependencies:
+ clsx: 2.0.0
+ dev: false
+
+ /client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+ dev: false
+
+ /clsx@2.0.0:
+ resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /clsx@2.1.0:
+ resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /cmdk@1.0.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==}
+ peerDependencies:
+ react: ^18.0.0
+ react-dom: ^18.0.0
+ dependencies:
+ '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ transitivePeerDependencies:
+ - '@types/react'
+ - '@types/react-dom'
+ dev: false
+
+ /color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+ dependencies:
+ color-name: 1.1.4
+
+ /color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ /commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
+ /concat-map@0.0.1:
+ resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
+
+ /cookie@0.6.0:
+ resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ /cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ /csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ /damerau-levenshtein@1.0.8:
+ resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
+ dev: false
+
+ /data-uri-to-buffer@4.0.1:
+ resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
+ engines: {node: '>= 12'}
+ dev: false
+
+ /data-view-buffer@1.0.1:
+ resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-data-view: 1.0.1
+ dev: false
+
+ /data-view-byte-length@1.0.1:
+ resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-data-view: 1.0.1
+ dev: false
+
+ /data-view-byte-offset@1.0.0:
+ resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-data-view: 1.0.1
+ dev: false
+
+ /date-fns@3.6.0:
+ resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==}
+ dev: false
+
+ /debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.3
+ dev: false
+
+ /debug@4.3.4:
+ resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.2
+
+ /deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ /define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ gopd: 1.0.1
+ dev: false
+
+ /define-properties@1.2.1:
+ resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-data-property: 1.1.4
+ has-property-descriptors: 1.0.2
+ object-keys: 1.1.1
+ dev: false
+
+ /dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /detect-libc@2.0.2:
+ resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /detect-node-es@1.1.0:
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
+ dev: false
+
+ /didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
+ /dir-glob@3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-type: 4.0.0
+
+ /dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ /doctrine@2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: false
+
+ /doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ esutils: 2.0.3
+
+ /eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ /electron-to-chromium@1.4.722:
+ resolution: {integrity: sha512-5nLE0TWFFpZ80Crhtp4pIp8LXCztjYX41yUcV6b+bKR2PqzjskTMOOlBi1VjBHlvHwS+4gar7kNKOrsbsewEZQ==}
+ dev: true
+
+ /emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ /emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ /enhanced-resolve@5.16.0:
+ resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==}
+ engines: {node: '>=10.13.0'}
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.2.1
+ dev: false
+
+ /es-abstract@1.23.3:
+ resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ array-buffer-byte-length: 1.0.1
+ arraybuffer.prototype.slice: 1.0.3
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
+ data-view-buffer: 1.0.1
+ data-view-byte-length: 1.0.1
+ data-view-byte-offset: 1.0.0
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ es-set-tostringtag: 2.0.3
+ es-to-primitive: 1.2.1
+ function.prototype.name: 1.1.6
+ get-intrinsic: 1.2.4
+ get-symbol-description: 1.0.2
+ globalthis: 1.0.3
+ gopd: 1.0.1
+ has-property-descriptors: 1.0.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ hasown: 2.0.2
+ internal-slot: 1.0.7
+ is-array-buffer: 3.0.4
+ is-callable: 1.2.7
+ is-data-view: 1.0.1
+ is-negative-zero: 2.0.3
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.3
+ is-string: 1.0.7
+ is-typed-array: 1.1.13
+ is-weakref: 1.0.2
+ object-inspect: 1.13.1
+ object-keys: 1.1.1
+ object.assign: 4.1.5
+ regexp.prototype.flags: 1.5.2
+ safe-array-concat: 1.1.2
+ safe-regex-test: 1.0.3
+ string.prototype.trim: 1.2.9
+ string.prototype.trimend: 1.0.8
+ string.prototype.trimstart: 1.0.8
+ typed-array-buffer: 1.0.2
+ typed-array-byte-length: 1.0.1
+ typed-array-byte-offset: 1.0.2
+ typed-array-length: 1.0.6
+ unbox-primitive: 1.0.2
+ which-typed-array: 1.1.15
+ dev: false
+
+ /es-define-property@1.0.0:
+ resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.4
+ dev: false
+
+ /es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /es-iterator-helpers@1.0.18:
+ resolution: {integrity: sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-set-tostringtag: 2.0.3
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ globalthis: 1.0.3
+ has-property-descriptors: 1.0.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ internal-slot: 1.0.7
+ iterator.prototype: 1.1.2
+ safe-array-concat: 1.1.2
+ dev: false
+
+ /es-object-atoms@1.0.0:
+ resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ es-errors: 1.3.0
+ dev: false
+
+ /es-set-tostringtag@2.0.3:
+ resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.4
+ has-tostringtag: 1.0.2
+ hasown: 2.0.2
+ dev: false
+
+ /es-shim-unscopables@1.0.2:
+ resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==}
+ dependencies:
+ hasown: 2.0.2
+ dev: false
+
+ /es-to-primitive@1.2.1:
+ resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ is-callable: 1.2.7
+ is-date-object: 1.0.5
+ is-symbol: 1.0.4
+ dev: false
+
+ /escalade@3.1.2:
+ resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ /eslint-config-next@14.1.4(eslint@8.57.0)(typescript@5.4.3):
+ resolution: {integrity: sha512-cihIahbhYAWwXJwZkAaRPpUi5t9aOi/HdfWXOjZeUOqNWXHD8X22kd1KG58Dc3MVaRx3HoR/oMGk2ltcrqDn8g==}
+ peerDependencies:
+ eslint: ^7.23.0 || ^8.0.0
+ typescript: '>=3.3.1'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@next/eslint-plugin-next': 14.1.4
+ '@rushstack/eslint-patch': 1.10.1
+ '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3)
+ eslint: 8.57.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.4.0)(eslint@8.57.0)
+ eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
+ eslint-plugin-react: 7.34.1(eslint@8.57.0)
+ eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0)
+ typescript: 5.4.3
+ transitivePeerDependencies:
+ - eslint-import-resolver-webpack
+ - supports-color
+ dev: false
+
+ /eslint-import-resolver-node@0.3.9:
+ resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
+ dependencies:
+ debug: 3.2.7
+ is-core-module: 2.13.1
+ resolve: 1.22.8
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0):
+ resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ eslint: '*'
+ eslint-plugin-import: '*'
+ dependencies:
+ debug: 4.3.4
+ enhanced-resolve: 5.16.0
+ eslint: 8.57.0
+ eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.4.0)(eslint@8.57.0)
+ fast-glob: 3.3.2
+ get-tsconfig: 4.7.3
+ is-core-module: 2.13.1
+ is-glob: 4.0.3
+ transitivePeerDependencies:
+ - '@typescript-eslint/parser'
+ - eslint-import-resolver-node
+ - eslint-import-resolver-webpack
+ - supports-color
+ dev: false
+
+ /eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
+ resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3)
+ debug: 3.2.7
+ eslint: 8.57.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /eslint-module-utils@2.8.1(@typescript-eslint/parser@7.4.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
+ resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+ debug: 3.2.7
+ eslint: 8.57.0
+ eslint-import-resolver-node: 0.3.9
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.4.0)(eslint@8.57.0):
+ resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 7.4.0(eslint@8.57.0)(typescript@5.4.3)
+ array-includes: 3.1.8
+ array.prototype.findlastindex: 1.2.5
+ array.prototype.flat: 1.3.2
+ array.prototype.flatmap: 1.3.2
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.57.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.4.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
+ hasown: 2.0.2
+ is-core-module: 2.13.1
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.fromentries: 2.0.8
+ object.groupby: 1.0.3
+ object.values: 1.2.0
+ semver: 6.3.1
+ tsconfig-paths: 3.15.0
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+ dev: false
+
+ /eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0):
+ resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+ dependencies:
+ '@babel/runtime': 7.24.1
+ aria-query: 5.3.0
+ array-includes: 3.1.8
+ array.prototype.flatmap: 1.3.2
+ ast-types-flow: 0.0.8
+ axe-core: 4.7.0
+ axobject-query: 3.2.1
+ damerau-levenshtein: 1.0.8
+ emoji-regex: 9.2.2
+ es-iterator-helpers: 1.0.18
+ eslint: 8.57.0
+ hasown: 2.0.2
+ jsx-ast-utils: 3.3.5
+ language-tags: 1.0.9
+ minimatch: 3.1.2
+ object.entries: 1.1.8
+ object.fromentries: 2.0.8
+ dev: false
+
+ /eslint-plugin-react-hooks@4.6.0(eslint@8.57.0):
+ resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
+ dependencies:
+ eslint: 8.57.0
+ dev: false
+
+ /eslint-plugin-react@7.34.1(eslint@8.57.0):
+ resolution: {integrity: sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+ dependencies:
+ array-includes: 3.1.8
+ array.prototype.findlast: 1.2.5
+ array.prototype.flatmap: 1.3.2
+ array.prototype.toreversed: 1.1.2
+ array.prototype.tosorted: 1.1.3
+ doctrine: 2.1.0
+ es-iterator-helpers: 1.0.18
+ eslint: 8.57.0
+ estraverse: 5.3.0
+ jsx-ast-utils: 3.3.5
+ minimatch: 3.1.2
+ object.entries: 1.1.8
+ object.fromentries: 2.0.8
+ object.hasown: 1.1.4
+ object.values: 1.2.0
+ prop-types: 15.8.1
+ resolve: 2.0.0-next.5
+ semver: 6.3.1
+ string.prototype.matchall: 4.0.11
+ dev: false
+
+ /eslint-scope@7.2.2:
+ resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ /eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ /eslint@8.57.0:
+ resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ hasBin: true
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
+ '@eslint-community/regexpp': 4.10.0
+ '@eslint/eslintrc': 2.1.4
+ '@eslint/js': 8.57.0
+ '@humanwhocodes/config-array': 0.11.14
+ '@humanwhocodes/module-importer': 1.0.1
+ '@nodelib/fs.walk': 1.2.8
+ '@ungap/structured-clone': 1.2.0
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.3
+ debug: 4.3.4
+ 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.5.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ globals: 13.24.0
+ graphemer: 1.4.0
+ ignore: 5.3.1
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ 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
+ transitivePeerDependencies:
+ - supports-color
+
+ /espree@9.6.1:
+ resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ acorn: 8.11.3
+ acorn-jsx: 5.3.2(acorn@8.11.3)
+ eslint-visitor-keys: 3.4.3
+
+ /esquery@1.5.0:
+ resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
+ engines: {node: '>=0.10'}
+ dependencies:
+ estraverse: 5.3.0
+
+ /esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+ dependencies:
+ estraverse: 5.3.0
+
+ /estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ /esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ /fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ /fast-glob@3.3.2:
+ resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+
+ /fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ /fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ /fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+ dependencies:
+ reusify: 1.0.4
+
+ /fetch-blob@3.2.0:
+ resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
+ engines: {node: ^12.20 || >= 14.13}
+ dependencies:
+ node-domexception: 1.0.0
+ web-streams-polyfill: 3.3.3
+ dev: false
+
+ /file-entry-cache@6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flat-cache: 3.2.0
+
+ /fill-range@7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+
+ /find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+
+ /flat-cache@3.2.0:
+ resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flatted: 3.3.1
+ keyv: 4.5.4
+ rimraf: 3.0.2
+
+ /flatted@3.3.1:
+ resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
+
+ /for-each@0.3.3:
+ resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+ dependencies:
+ is-callable: 1.2.7
+ dev: false
+
+ /foreground-child@3.1.1:
+ resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==}
+ engines: {node: '>=14'}
+ dependencies:
+ cross-spawn: 7.0.3
+ signal-exit: 4.1.0
+
+ /formdata-polyfill@4.0.10:
+ resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
+ engines: {node: '>=12.20.0'}
+ dependencies:
+ fetch-blob: 3.2.0
+ dev: false
+
+ /fraction.js@4.3.7:
+ resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
+ dev: true
+
+ /fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
+ /fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
+ /function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ /function.prototype.name@1.1.6:
+ resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ functions-have-names: 1.2.3
+ dev: false
+
+ /functions-have-names@1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+ dev: false
+
+ /get-intrinsic@1.2.4:
+ resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ hasown: 2.0.2
+ dev: false
+
+ /get-nonce@1.0.1:
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /get-symbol-description@1.0.2:
+ resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ dev: false
+
+ /get-tsconfig@4.7.3:
+ resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==}
+ dependencies:
+ resolve-pkg-maps: 1.0.0
+ dev: false
+
+ /glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+ dependencies:
+ is-glob: 4.0.3
+
+ /glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+ dependencies:
+ is-glob: 4.0.3
+
+ /glob@10.3.10:
+ resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+ dependencies:
+ foreground-child: 3.1.1
+ jackspeak: 2.3.6
+ minimatch: 9.0.4
+ minipass: 7.0.4
+ path-scurry: 1.10.2
+ dev: false
+
+ /glob@10.3.12:
+ resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+ dependencies:
+ foreground-child: 3.1.1
+ jackspeak: 2.3.6
+ minimatch: 9.0.4
+ minipass: 7.0.4
+ path-scurry: 1.10.2
+
+ /glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
+ /globals@13.24.0:
+ resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ type-fest: 0.20.2
+
+ /globalthis@1.0.3:
+ resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-properties: 1.2.1
+ dev: false
+
+ /globby@11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+ engines: {node: '>=10'}
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.3.2
+ ignore: 5.3.1
+ merge2: 1.4.1
+ slash: 3.0.0
+
+ /gopd@1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+ dependencies:
+ get-intrinsic: 1.2.4
+ dev: false
+
+ /graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+ dev: false
+
+ /graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+
+ /has-bigints@1.0.2:
+ resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+ dev: false
+
+ /has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ /has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
+ dependencies:
+ es-define-property: 1.0.0
+ dev: false
+
+ /has-proto@1.0.3:
+ resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /has-symbols@1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: false
+
+ /hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ function-bind: 1.1.2
+
+ /ignore@5.3.1:
+ resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
+ engines: {node: '>= 4'}
+
+ /import-fresh@3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ /imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ /inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+
+ /inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ /internal-slot@1.0.7:
+ resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ es-errors: 1.3.0
+ hasown: 2.0.2
+ side-channel: 1.0.6
+ dev: false
+
+ /invariant@2.2.4:
+ resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
+ dependencies:
+ loose-envify: 1.4.0
+ dev: false
+
+ /is-array-buffer@3.0.4:
+ resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+ dev: false
+
+ /is-async-function@2.0.0:
+ resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.2
+ dev: false
+
+ /is-bigint@1.0.4:
+ resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+ dependencies:
+ has-bigints: 1.0.2
+ dev: false
+
+ /is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+ dependencies:
+ binary-extensions: 2.3.0
+
+ /is-boolean-object@1.1.2:
+ resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
+ dev: false
+
+ /is-callable@1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-core-module@2.13.1:
+ resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
+ dependencies:
+ hasown: 2.0.2
+
+ /is-data-view@1.0.1:
+ resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ is-typed-array: 1.1.13
+ dev: false
+
+ /is-date-object@1.0.5:
+ resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.2
+ dev: false
+
+ /is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ /is-finalizationregistry@1.0.2:
+ resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==}
+ dependencies:
+ call-bind: 1.0.7
+ dev: false
+
+ /is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ /is-generator-function@1.0.10:
+ resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.2
+ dev: false
+
+ /is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extglob: 2.1.1
+
+ /is-map@2.0.3:
+ resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-negative-zero@2.0.3:
+ resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-number-object@1.0.7:
+ resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.2
+ dev: false
+
+ /is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ /is-path-inside@3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+
+ /is-regex@1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
+ dev: false
+
+ /is-set@2.0.3:
+ resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-shared-array-buffer@1.0.3:
+ resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ dev: false
+
+ /is-string@1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.2
+ dev: false
+
+ /is-symbol@1.0.4:
+ resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: false
+
+ /is-typed-array@1.1.13:
+ resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ which-typed-array: 1.1.15
+ dev: false
+
+ /is-weakmap@2.0.2:
+ resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-weakref@1.0.2:
+ resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+ dependencies:
+ call-bind: 1.0.7
+ dev: false
+
+ /is-weakset@2.0.3:
+ resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+ dev: false
+
+ /isarray@2.0.5:
+ resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+ dev: false
+
+ /isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ /iterator.prototype@1.1.2:
+ resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==}
+ dependencies:
+ define-properties: 1.2.1
+ get-intrinsic: 1.2.4
+ has-symbols: 1.0.3
+ reflect.getprototypeof: 1.0.6
+ set-function-name: 2.0.2
+ dev: false
+
+ /jackspeak@2.3.6:
+ resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
+ engines: {node: '>=14'}
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
+ /jiti@1.21.0:
+ resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==}
+ hasBin: true
+
+ /jose@5.2.3:
+ resolution: {integrity: sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA==}
+ dev: false
+
+ /js-base64@3.7.7:
+ resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==}
+ dev: false
+
+ /js-confetti@0.12.0:
+ resolution: {integrity: sha512-1R0Akxn3Zn82pMqW65N1V2NwKkZJ75bvBN/VAb36Ya0YHwbaSiAJZVRr/19HBxH/O8x2x01UFAbYI18VqlDN6g==}
+ dev: false
+
+ /js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ dev: false
+
+ /js-yaml@4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+ dependencies:
+ argparse: 2.0.1
+
+ /json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ /json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ /json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ /json5@1.0.2:
+ resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.8
+ dev: false
+
+ /jsx-ast-utils@3.3.5:
+ resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
+ engines: {node: '>=4.0'}
+ dependencies:
+ array-includes: 3.1.8
+ array.prototype.flat: 1.3.2
+ object.assign: 4.1.5
+ object.values: 1.2.0
+ dev: false
+
+ /keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+ dependencies:
+ json-buffer: 3.0.1
+
+ /language-subtag-registry@0.3.22:
+ resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==}
+ dev: false
+
+ /language-tags@1.0.9:
+ resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
+ engines: {node: '>=0.10'}
+ dependencies:
+ language-subtag-registry: 0.3.22
+ dev: false
+
+ /levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ /libsql@0.3.10:
+ resolution: {integrity: sha512-/8YMTbwWFPmrDWY+YFK3kYqVPFkMgQre0DGmBaOmjogMdSe+7GHm1/q9AZ61AWkEub/vHmi+bA4tqIzVhKnqzg==}
+ cpu: [x64, arm64, wasm32]
+ os: [darwin, linux, win32]
+ dependencies:
+ '@neon-rs/load': 0.0.4
+ detect-libc: 2.0.2
+ optionalDependencies:
+ '@libsql/darwin-arm64': 0.3.10
+ '@libsql/darwin-x64': 0.3.10
+ '@libsql/linux-arm64-gnu': 0.3.10
+ '@libsql/linux-arm64-musl': 0.3.10
+ '@libsql/linux-x64-gnu': 0.3.10
+ '@libsql/linux-x64-musl': 0.3.10
+ '@libsql/win32-x64-msvc': 0.3.10
+ dev: false
+
+ /lilconfig@2.1.0:
+ resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
+ engines: {node: '>=10'}
+
+ /lilconfig@3.1.1:
+ resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==}
+ engines: {node: '>=14'}
+
+ /lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ /locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-locate: 5.0.0
+
+ /lodash.castarray@4.4.0:
+ resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
+ dev: true
+
+ /lodash.isplainobject@4.0.6:
+ resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
+ dev: true
+
+ /lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ /loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+ dependencies:
+ js-tokens: 4.0.0
+ dev: false
+
+ /lru-cache@10.2.0:
+ resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==}
+ engines: {node: 14 || >=16.14}
+
+ /lru-cache@6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+ dependencies:
+ yallist: 4.0.0
+
+ /lucide-react@0.363.0(react@18.2.0):
+ resolution: {integrity: sha512-AlsfPCsXQyQx7wwsIgzcKOL9LwC498LIMAo+c0Es5PkHJa33xwmYAkkSoKoJWWWSYQEStqu58/jT4tL2gi32uQ==}
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0
+ dependencies:
+ react: 18.2.0
+ dev: false
+
+ /merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ /micromatch@4.0.5:
+ resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.3.1
+
+ /minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ dependencies:
+ brace-expansion: 1.1.11
+
+ /minimatch@9.0.3:
+ resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ dependencies:
+ brace-expansion: 2.0.1
+
+ /minimatch@9.0.4:
+ resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ dependencies:
+ brace-expansion: 2.0.1
+
+ /minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ dev: false
+
+ /minipass@7.0.4:
+ resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ /ms@2.1.2:
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+
+ /ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ dev: false
+
+ /mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
+ /nanoid@3.3.7:
+ resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ /natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ /next-auth@5.0.0-beta.16(next@14.1.4)(react@18.2.0):
+ resolution: {integrity: sha512-dX2snB+ezN23tFzSes3n3uosT9iBf0eILPYWH/R2fd9n3ZzdMQlRzq7JIOPeS1aLc84IuRlyuyXyx9XmmZB6og==}
+ peerDependencies:
+ '@simplewebauthn/browser': ^9.0.1
+ '@simplewebauthn/server': ^9.0.2
+ next: ^14
+ nodemailer: ^6.6.5
+ react: ^18.2.0
+ peerDependenciesMeta:
+ '@simplewebauthn/browser':
+ optional: true
+ '@simplewebauthn/server':
+ optional: true
+ nodemailer:
+ optional: true
+ dependencies:
+ '@auth/core': 0.28.1
+ next: 14.1.4(react-dom@18.2.0)(react@18.2.0)
+ react: 18.2.0
+ dev: false
+
+ /next-themes@0.3.0(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==}
+ peerDependencies:
+ react: ^16.8 || ^17 || ^18
+ react-dom: ^16.8 || ^17 || ^18
+ dependencies:
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /next@14.1.4(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ==}
+ engines: {node: '>=18.17.0'}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ react: ^18.2.0
+ react-dom: ^18.2.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ sass:
+ optional: true
+ dependencies:
+ '@next/env': 14.1.4
+ '@swc/helpers': 0.5.2
+ busboy: 1.6.0
+ caniuse-lite: 1.0.30001600
+ graceful-fs: 4.2.11
+ postcss: 8.4.31
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ styled-jsx: 5.1.1(react@18.2.0)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 14.1.4
+ '@next/swc-darwin-x64': 14.1.4
+ '@next/swc-linux-arm64-gnu': 14.1.4
+ '@next/swc-linux-arm64-musl': 14.1.4
+ '@next/swc-linux-x64-gnu': 14.1.4
+ '@next/swc-linux-x64-musl': 14.1.4
+ '@next/swc-win32-arm64-msvc': 14.1.4
+ '@next/swc-win32-ia32-msvc': 14.1.4
+ '@next/swc-win32-x64-msvc': 14.1.4
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+ dev: false
+
+ /node-domexception@1.0.0:
+ resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
+ engines: {node: '>=10.5.0'}
+ dev: false
+
+ /node-fetch@3.3.2:
+ resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dependencies:
+ data-uri-to-buffer: 4.0.1
+ fetch-blob: 3.2.0
+ formdata-polyfill: 4.0.10
+ dev: false
+
+ /node-releases@2.0.14:
+ resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
+ dev: true
+
+ /normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ /normalize-range@0.1.2:
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /oauth4webapi@2.10.4:
+ resolution: {integrity: sha512-DSoj8QoChzOCQlJkRmYxAJCIpnXFW32R0Uq7avyghIeB6iJq0XAblOD7pcq3mx4WEBDwMuKr0Y1qveCBleG2Xw==}
+ dev: false
+
+ /object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ /object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+
+ /object-inspect@1.13.1:
+ resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
+ dev: false
+
+ /object-keys@1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /object.assign@4.1.5:
+ resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ has-symbols: 1.0.3
+ object-keys: 1.1.1
+ dev: false
+
+ /object.entries@1.1.8:
+ resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+ dev: false
+
+ /object.fromentries@2.0.8:
+ resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-object-atoms: 1.0.0
+ dev: false
+
+ /object.groupby@1.0.3:
+ resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ dev: false
+
+ /object.hasown@1.1.4:
+ resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-object-atoms: 1.0.0
+ dev: false
+
+ /object.values@1.2.0:
+ resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+ dev: false
+
+ /once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ dependencies:
+ wrappy: 1.0.2
+
+ /optionator@0.9.3:
+ resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ '@aashutoshrathi/word-wrap': 1.2.6
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ /p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ yocto-queue: 0.1.0
+
+ /p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-limit: 3.1.0
+
+ /parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+ dependencies:
+ callsites: 3.1.0
+
+ /path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ /path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
+ /path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ /path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ /path-scurry@1.10.2:
+ resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ dependencies:
+ lru-cache: 10.2.0
+ minipass: 7.0.4
+
+ /path-type@4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+
+ /picocolors@1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+
+ /picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ /pify@2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+
+ /pirates@4.0.6:
+ resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
+ engines: {node: '>= 6'}
+
+ /possible-typed-array-names@1.0.0:
+ resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /postcss-import@15.1.0(postcss@8.4.38):
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+ dependencies:
+ postcss: 8.4.38
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.8
+
+ /postcss-js@4.0.1(postcss@8.4.38):
+ resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.4.38
+
+ /postcss-load-config@4.0.2(postcss@8.4.38):
+ resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+ dependencies:
+ lilconfig: 3.1.1
+ postcss: 8.4.38
+ yaml: 2.4.1
+
+ /postcss-nested@6.0.1(postcss@8.4.38):
+ resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+ dependencies:
+ postcss: 8.4.38
+ postcss-selector-parser: 6.0.16
+
+ /postcss-selector-parser@6.0.10:
+ resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
+ engines: {node: '>=4'}
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+ dev: true
+
+ /postcss-selector-parser@6.0.16:
+ resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==}
+ engines: {node: '>=4'}
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ /postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ /postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.7
+ picocolors: 1.0.0
+ source-map-js: 1.2.0
+ dev: false
+
+ /postcss@8.4.38:
+ resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.7
+ picocolors: 1.0.0
+ source-map-js: 1.2.0
+
+ /preact-render-to-string@5.2.3(preact@10.11.3):
+ resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==}
+ peerDependencies:
+ preact: '>=10'
+ dependencies:
+ preact: 10.11.3
+ pretty-format: 3.8.0
+ dev: false
+
+ /preact@10.11.3:
+ resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==}
+ dev: false
+
+ /prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ /prettier-plugin-tailwindcss@0.5.13(prettier@3.2.5):
+ resolution: {integrity: sha512-2tPWHCFNC+WRjAC4SIWQNSOdcL1NNkydXim8w7TDqlZi+/ulZYz2OouAI6qMtkggnPt7lGamboj6LcTMwcCvoQ==}
+ engines: {node: '>=14.21.3'}
+ peerDependencies:
+ '@ianvs/prettier-plugin-sort-imports': '*'
+ '@prettier/plugin-pug': '*'
+ '@shopify/prettier-plugin-liquid': '*'
+ '@trivago/prettier-plugin-sort-imports': '*'
+ '@zackad/prettier-plugin-twig-melody': '*'
+ prettier: ^3.0
+ prettier-plugin-astro: '*'
+ prettier-plugin-css-order: '*'
+ prettier-plugin-import-sort: '*'
+ prettier-plugin-jsdoc: '*'
+ prettier-plugin-marko: '*'
+ prettier-plugin-organize-attributes: '*'
+ prettier-plugin-organize-imports: '*'
+ prettier-plugin-sort-imports: '*'
+ prettier-plugin-style-order: '*'
+ prettier-plugin-svelte: '*'
+ peerDependenciesMeta:
+ '@ianvs/prettier-plugin-sort-imports':
+ optional: true
+ '@prettier/plugin-pug':
+ optional: true
+ '@shopify/prettier-plugin-liquid':
+ optional: true
+ '@trivago/prettier-plugin-sort-imports':
+ optional: true
+ '@zackad/prettier-plugin-twig-melody':
+ optional: true
+ prettier-plugin-astro:
+ optional: true
+ prettier-plugin-css-order:
+ optional: true
+ prettier-plugin-import-sort:
+ optional: true
+ prettier-plugin-jsdoc:
+ optional: true
+ prettier-plugin-marko:
+ optional: true
+ prettier-plugin-organize-attributes:
+ optional: true
+ prettier-plugin-organize-imports:
+ optional: true
+ prettier-plugin-sort-imports:
+ optional: true
+ prettier-plugin-style-order:
+ optional: true
+ prettier-plugin-svelte:
+ optional: true
+ dependencies:
+ prettier: 3.2.5
+ dev: true
+
+ /prettier@3.2.5:
+ resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==}
+ engines: {node: '>=14'}
+ hasBin: true
+ dev: true
+
+ /pretty-format@3.8.0:
+ resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
+ dev: false
+
+ /prisma@5.11.0:
+ resolution: {integrity: sha512-KCLiug2cs0Je7kGkQBN9jDWoZ90ogE/kvZTUTgz2h94FEo8pczCkPH7fPNXkD1sGU7Yh65risGGD1HQ5DF3r3g==}
+ engines: {node: '>=16.13'}
+ hasBin: true
+ requiresBuild: true
+ dependencies:
+ '@prisma/engines': 5.11.0
+
+ /prop-types@15.8.1:
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+ dev: false
+
+ /punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ /qr.js@0.0.0:
+ resolution: {integrity: sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==}
+ dev: false
+
+ /queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ /react-dom@18.2.0(react@18.2.0):
+ resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
+ peerDependencies:
+ react: ^18.2.0
+ dependencies:
+ loose-envify: 1.4.0
+ react: 18.2.0
+ scheduler: 0.23.0
+ dev: false
+
+ /react-hook-form@7.51.2(react@18.2.0):
+ resolution: {integrity: sha512-y++lwaWjtzDt/XNnyGDQy6goHskFualmDlf+jzEZvjvz6KWDf7EboL7pUvRCzPTJd0EOPpdekYaQLEvvG6m6HA==}
+ engines: {node: '>=12.22.0'}
+ peerDependencies:
+ react: ^16.8.0 || ^17 || ^18
+ dependencies:
+ react: 18.2.0
+ dev: false
+
+ /react-is@16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+ dev: false
+
+ /react-qr-code@2.0.12(react@18.2.0):
+ resolution: {integrity: sha512-k+pzP5CKLEGBRwZsDPp98/CAJeXlsYRHM2iZn1Sd5Th/HnKhIZCSg27PXO58zk8z02RaEryg+60xa4vyywMJwg==}
+ peerDependencies:
+ react: ^16.x || ^17.x || ^18.x
+ react-native-svg: '*'
+ peerDependenciesMeta:
+ react-native-svg:
+ optional: true
+ dependencies:
+ prop-types: 15.8.1
+ qr.js: 0.0.0
+ react: 18.2.0
+ dev: false
+
+ /react-remove-scroll-bar@2.3.6(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@types/react': 18.2.73
+ react: 18.2.0
+ react-style-singleton: 2.2.1(@types/react@18.2.73)(react@18.2.0)
+ tslib: 2.6.2
+ dev: false
+
+ /react-remove-scroll@2.5.5(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@types/react': 18.2.73
+ react: 18.2.0
+ react-remove-scroll-bar: 2.3.6(@types/react@18.2.73)(react@18.2.0)
+ react-style-singleton: 2.2.1(@types/react@18.2.73)(react@18.2.0)
+ tslib: 2.6.2
+ use-callback-ref: 1.3.2(@types/react@18.2.73)(react@18.2.0)
+ use-sidecar: 1.1.2(@types/react@18.2.73)(react@18.2.0)
+ dev: false
+
+ /react-style-singleton@2.2.1(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@types/react': 18.2.73
+ get-nonce: 1.0.1
+ invariant: 2.2.4
+ react: 18.2.0
+ tslib: 2.6.2
+ dev: false
+
+ /react@18.2.0:
+ resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ loose-envify: 1.4.0
+ dev: false
+
+ /read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+ dependencies:
+ pify: 2.3.0
+
+ /readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+ dependencies:
+ picomatch: 2.3.1
+
+ /reflect.getprototypeof@1.0.6:
+ resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ globalthis: 1.0.3
+ which-builtin-type: 1.1.3
+ dev: false
+
+ /regenerator-runtime@0.14.1:
+ resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+ dev: false
+
+ /regexp.prototype.flags@1.5.2:
+ resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-errors: 1.3.0
+ set-function-name: 2.0.2
+ dev: false
+
+ /resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ /resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+ dev: false
+
+ /resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+ hasBin: true
+ dependencies:
+ is-core-module: 2.13.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ /resolve@2.0.0-next.5:
+ resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==}
+ hasBin: true
+ dependencies:
+ is-core-module: 2.13.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+ dev: false
+
+ /reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ /rimraf@3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ hasBin: true
+ dependencies:
+ glob: 7.2.3
+
+ /run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ dependencies:
+ queue-microtask: 1.2.3
+
+ /safe-array-concat@1.1.2:
+ resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==}
+ engines: {node: '>=0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+ has-symbols: 1.0.3
+ isarray: 2.0.5
+ dev: false
+
+ /safe-regex-test@1.0.3:
+ resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-regex: 1.1.4
+ dev: false
+
+ /scheduler@0.23.0:
+ resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
+ dependencies:
+ loose-envify: 1.4.0
+ dev: false
+
+ /semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+ dev: false
+
+ /semver@7.6.0:
+ resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+
+ /set-function-length@1.2.2:
+ resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+ engines: {node: '>= 0.4'}
+ 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
+ dev: false
+
+ /set-function-name@2.0.2:
+ resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+ dev: false
+
+ /shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+ dependencies:
+ shebang-regex: 3.0.0
+
+ /shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ /side-channel@1.0.6:
+ resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ object-inspect: 1.13.1
+ dev: false
+
+ /signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ /slash@3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+
+ /sonner@1.4.41(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-uG511ggnnsw6gcn/X+YKkWPo5ep9il9wYi3QJxHsYe7yTZ4+cOd1wuodOUmOpFuXL+/RE3R04LczdNCDygTDgQ==}
+ peerDependencies:
+ react: ^18.0.0
+ react-dom: ^18.0.0
+ dependencies:
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
+ /source-map-js@1.2.0:
+ resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
+ engines: {node: '>=0.10.0'}
+
+ /streamsearch@1.1.0:
+ resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
+ engines: {node: '>=10.0.0'}
+ dev: false
+
+ /string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ /string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
+ /string.prototype.matchall@4.0.11:
+ resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ get-intrinsic: 1.2.4
+ gopd: 1.0.1
+ has-symbols: 1.0.3
+ internal-slot: 1.0.7
+ regexp.prototype.flags: 1.5.2
+ set-function-name: 2.0.2
+ side-channel: 1.0.6
+ dev: false
+
+ /string.prototype.trim@1.2.9:
+ resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-object-atoms: 1.0.0
+ dev: false
+
+ /string.prototype.trimend@1.0.8:
+ resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+ dev: false
+
+ /string.prototype.trimstart@1.0.8:
+ resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+ dev: false
+
+ /strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-regex: 5.0.1
+
+ /strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+ dependencies:
+ ansi-regex: 6.0.1
+
+ /strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+ dev: false
+
+ /strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ /styled-jsx@5.1.1(react@18.2.0):
+ resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+ dependencies:
+ client-only: 0.0.1
+ react: 18.2.0
+ dev: false
+
+ /sucrase@3.35.0:
+ resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ commander: 4.1.1
+ glob: 10.3.12
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.6
+ ts-interface-checker: 0.1.13
+
+ /supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+ dependencies:
+ has-flag: 4.0.0
+
+ /supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ /tailwind-merge@2.2.2:
+ resolution: {integrity: sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==}
+ dependencies:
+ '@babel/runtime': 7.24.1
+ dev: false
+
+ /tailwindcss-animate@1.0.7(tailwindcss@3.4.3):
+ resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders'
+ dependencies:
+ tailwindcss: 3.4.3
+ dev: false
+
+ /tailwindcss@3.4.3:
+ resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.2
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.0
+ lilconfig: 2.1.0
+ micromatch: 4.0.5
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.0.0
+ postcss: 8.4.38
+ postcss-import: 15.1.0(postcss@8.4.38)
+ postcss-js: 4.0.1(postcss@8.4.38)
+ postcss-load-config: 4.0.2(postcss@8.4.38)
+ postcss-nested: 6.0.1(postcss@8.4.38)
+ postcss-selector-parser: 6.0.16
+ resolve: 1.22.8
+ sucrase: 3.35.0
+ transitivePeerDependencies:
+ - ts-node
+
+ /tapable@2.2.1:
+ resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
+ engines: {node: '>=6'}
+ dev: false
+
+ /text-table@0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+
+ /thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+ dependencies:
+ thenify: 3.3.1
+
+ /thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+ dependencies:
+ any-promise: 1.3.0
+
+ /to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+ dependencies:
+ is-number: 7.0.0
+
+ /ts-api-utils@1.3.0(typescript@5.4.3):
+ resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+ dependencies:
+ typescript: 5.4.3
+
+ /ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ /tsconfig-paths@3.15.0:
+ resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.2
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+ dev: false
+
+ /tslib@2.6.2:
+ resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
+ dev: false
+
+ /type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+
+ /type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+
+ /typed-array-buffer@1.0.2:
+ resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-typed-array: 1.1.13
+ dev: false
+
+ /typed-array-byte-length@1.0.1:
+ resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
+ dev: false
+
+ /typed-array-byte-offset@1.0.2:
+ resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
+ dev: false
+
+ /typed-array-length@1.0.6:
+ resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
+ possible-typed-array-names: 1.0.0
+ dev: false
+
+ /typescript@5.4.3:
+ resolution: {integrity: sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ /unbox-primitive@1.0.2:
+ resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+ dependencies:
+ call-bind: 1.0.7
+ has-bigints: 1.0.2
+ has-symbols: 1.0.3
+ which-boxed-primitive: 1.0.2
+ dev: false
+
+ /undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+
+ /update-browserslist-db@1.0.13(browserslist@4.23.0):
+ resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+ dependencies:
+ browserslist: 4.23.0
+ escalade: 3.1.2
+ picocolors: 1.0.0
+ dev: true
+
+ /uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ dependencies:
+ punycode: 2.3.1
+
+ /use-callback-ref@1.3.2(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@types/react': 18.2.73
+ react: 18.2.0
+ tslib: 2.6.2
+ dev: false
+
+ /use-debounce@10.0.0(react@18.2.0):
+ resolution: {integrity: sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A==}
+ engines: {node: '>= 16.0.0'}
+ peerDependencies:
+ react: '>=16.8.0'
+ dependencies:
+ react: 18.2.0
+ dev: false
+
+ /use-sidecar@1.1.2(@types/react@18.2.73)(react@18.2.0):
+ resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ dependencies:
+ '@types/react': 18.2.73
+ detect-node-es: 1.1.0
+ react: 18.2.0
+ tslib: 2.6.2
+ dev: false
+
+ /util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ /web-streams-polyfill@3.3.3:
+ resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
+ engines: {node: '>= 8'}
+ dev: false
+
+ /which-boxed-primitive@1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ dependencies:
+ is-bigint: 1.0.4
+ is-boolean-object: 1.1.2
+ is-number-object: 1.0.7
+ is-string: 1.0.7
+ is-symbol: 1.0.4
+ dev: false
+
+ /which-builtin-type@1.1.3:
+ resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ function.prototype.name: 1.1.6
+ has-tostringtag: 1.0.2
+ is-async-function: 2.0.0
+ is-date-object: 1.0.5
+ is-finalizationregistry: 1.0.2
+ is-generator-function: 1.0.10
+ is-regex: 1.1.4
+ is-weakref: 1.0.2
+ isarray: 2.0.5
+ which-boxed-primitive: 1.0.2
+ which-collection: 1.0.2
+ which-typed-array: 1.1.15
+ dev: false
+
+ /which-collection@1.0.2:
+ resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ is-map: 2.0.3
+ is-set: 2.0.3
+ is-weakmap: 2.0.2
+ is-weakset: 2.0.3
+ dev: false
+
+ /which-typed-array@1.1.15:
+ resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.2
+ dev: false
+
+ /which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+ dependencies:
+ isexe: 2.0.0
+
+ /wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ /wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
+ /wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ /ws@8.16.0:
+ resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==}
+ 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
+ dev: false
+
+ /yallist@4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+
+ /yaml@2.4.1:
+ resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
+ /yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+ /zod@3.22.4:
+ resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
+ dev: false
diff --git a/postcss.config.cjs b/postcss.config.cjs
index 33ad091..e305dd9 100644
--- a/postcss.config.cjs
+++ b/postcss.config.cjs
@@ -1,6 +1,8 @@
-module.exports = {
+const config = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
-}
+};
+
+module.exports = config;
diff --git a/prettier.config.cjs b/prettier.config.cjs
deleted file mode 100644
index 96e2ee1..0000000
--- a/prettier.config.cjs
+++ /dev/null
@@ -1,4 +0,0 @@
-/** @type {import("prettier").Config} */
-module.exports = {
- plugins: [require.resolve("prettier-plugin-tailwindcss")],
- };
\ No newline at end of file
diff --git a/prettier.config.js b/prettier.config.js
new file mode 100644
index 0000000..b2d59b4
--- /dev/null
+++ b/prettier.config.js
@@ -0,0 +1,6 @@
+/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
+const config = {
+ plugins: ["prettier-plugin-tailwindcss"],
+};
+
+export default config;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 3937dc7..3fee9ee 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -1,22 +1,41 @@
generator client {
- provider = "prisma-client-js"
+ provider = "prisma-client-js"
+ previewFeatures = ["driverAdapters"]
}
datasource db {
- provider = "mysql"
+ provider = "sqlite"
url = env("DATABASE_URL")
}
-model link {
- id Int @id @default(autoincrement())
- url String @db.Text
- slug String @unique
+model Links {
+ id String @id @default(cuid())
+ url String
+ slug String @unique
+ description String?
+ createdAt DateTime @default(now())
+ createdBy User? @relation(fields: [creatorId], references: [id], onDelete: Cascade)
+ creatorId String
+ tag Tags? @relation(fields: [tagId], references: [id], onDelete: SetNull)
+ tagId String?
+ clicks Int @default(0)
+ lastClicked DateTime?
+
+ @@index(slug)
+ @@index([creatorId])
+ @@index([tagId])
+}
+
+model Tags {
+ id String @id @default(cuid())
+ name String
description String?
createdAt DateTime @default(now())
createdBy User? @relation(fields: [creatorId], references: [id])
creatorId String
+ links Links[]
- @@index(slug)
+ @@index([creatorId])
}
model Account {
@@ -32,9 +51,11 @@ model Account {
scope String?
id_token String? //@db.Text
session_state String?
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
+ @@index([userId])
}
model Session {
@@ -43,24 +64,59 @@ model Session {
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+
+ @@index([userId])
}
model User {
- id String @id @default(cuid())
- name String?
- username String?
- email String? @unique
- emailVerified DateTime?
- image String?
- accounts Account[]
- sessions Session[]
- links link[]
+ id String @id @default(cuid())
+ name String?
+ username String?
+ email String? @unique
+ emailVerified DateTime?
+ image String?
+ password String?
+ limitLinks Int @default(30)
+ isTwoFactorEnabled Boolean @default(false)
+ twoFactorConfirmation TwoFactorConfirmation?
+ role String @default("USER")
+ accounts Account[]
+ sessions Session[]
+ links Links[]
+ tags Tags[]
}
model VerificationToken {
- identifier String
- token String @unique
- expires DateTime
+ id String @id @default(cuid())
+ email String
+ token String @unique
+ expires DateTime
+
+ @@unique([email, token])
+}
+
+model PasswordResetToken {
+ id String @id @default(cuid())
+ email String
+ token String @unique
+ expires DateTime
+
+ @@unique([email, token])
+}
+
+model TwoFactorToken {
+ id String @id @default(cuid())
+ email String
+ token String @unique
+ expires DateTime
+
+ @@unique([email, token])
+}
+
+model TwoFactorConfirmation {
+ id String @id @default(cuid())
+ userId String
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- @@unique([identifier, token])
+ @@unique([userId])
}
diff --git a/public/fonts/inter.woff2 b/public/fonts/inter.woff2
deleted file mode 100644
index f92498a..0000000
Binary files a/public/fonts/inter.woff2 and /dev/null differ
diff --git a/public/images/apple-touch-icon.png b/public/images/apple-touch-icon.png
new file mode 100644
index 0000000..0762563
Binary files /dev/null and b/public/images/apple-touch-icon.png differ
diff --git a/public/images/icon-192x192.png b/public/images/icon-192x192.png
new file mode 100644
index 0000000..4d39ef6
Binary files /dev/null and b/public/images/icon-192x192.png differ
diff --git a/public/images/icon-256x256.png b/public/images/icon-256x256.png
new file mode 100644
index 0000000..03a88bb
Binary files /dev/null and b/public/images/icon-256x256.png differ
diff --git a/public/images/icon-384x384.png b/public/images/icon-384x384.png
new file mode 100644
index 0000000..1b95b59
Binary files /dev/null and b/public/images/icon-384x384.png differ
diff --git a/public/images/icon-512x512.png b/public/images/icon-512x512.png
new file mode 100644
index 0000000..0bb2afc
Binary files /dev/null and b/public/images/icon-512x512.png differ
diff --git a/public/images/logo_png.png b/public/images/logo_png.png
new file mode 100644
index 0000000..ea0e570
Binary files /dev/null and b/public/images/logo_png.png differ
diff --git a/public/images/logo_svg.svg b/public/images/logo_svg.svg
new file mode 100644
index 0000000..501c508
--- /dev/null
+++ b/public/images/logo_svg.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/images/og_image.png b/public/images/og_image.png
new file mode 100644
index 0000000..9795650
Binary files /dev/null and b/public/images/og_image.png differ
diff --git a/public/images/og_image_v3.jpg b/public/images/og_image_v3.jpg
new file mode 100644
index 0000000..0d66fbc
Binary files /dev/null and b/public/images/og_image_v3.jpg differ
diff --git a/public/images/screenshot_png.png b/public/images/screenshot_png.png
new file mode 100644
index 0000000..c97c23f
Binary files /dev/null and b/public/images/screenshot_png.png differ
diff --git a/public/img/apple-touch-icon-114x114.png b/public/img/apple-touch-icon-114x114.png
deleted file mode 100644
index 73c8d23..0000000
Binary files a/public/img/apple-touch-icon-114x114.png and /dev/null differ
diff --git a/public/img/apple-touch-icon-152x152.png b/public/img/apple-touch-icon-152x152.png
deleted file mode 100644
index 1f4d2e3..0000000
Binary files a/public/img/apple-touch-icon-152x152.png and /dev/null differ
diff --git a/public/img/apple-touch-icon-180x180.png b/public/img/apple-touch-icon-180x180.png
deleted file mode 100644
index b438c75..0000000
Binary files a/public/img/apple-touch-icon-180x180.png and /dev/null differ
diff --git a/public/img/banner.jpg b/public/img/banner.jpg
deleted file mode 100644
index d05eb08..0000000
Binary files a/public/img/banner.jpg and /dev/null differ
diff --git a/public/img/banner_gh.jpg b/public/img/banner_gh.jpg
deleted file mode 100644
index b0410f6..0000000
Binary files a/public/img/banner_gh.jpg and /dev/null differ
diff --git a/public/img/favicon.ico b/public/img/favicon.ico
deleted file mode 100644
index a4fc043..0000000
Binary files a/public/img/favicon.ico and /dev/null differ
diff --git a/public/img/icon-192x192.png b/public/img/icon-192x192.png
deleted file mode 100644
index ee9308d..0000000
Binary files a/public/img/icon-192x192.png and /dev/null differ
diff --git a/public/img/icon-256x256.png b/public/img/icon-256x256.png
deleted file mode 100644
index c4ea660..0000000
Binary files a/public/img/icon-256x256.png and /dev/null differ
diff --git a/public/img/icon-384x384.png b/public/img/icon-384x384.png
deleted file mode 100644
index 0a4c043..0000000
Binary files a/public/img/icon-384x384.png and /dev/null differ
diff --git a/public/img/icon-512x512.png b/public/img/icon-512x512.png
deleted file mode 100644
index 70261a2..0000000
Binary files a/public/img/icon-512x512.png and /dev/null differ
diff --git a/public/img/logo.png b/public/img/logo.png
deleted file mode 100644
index f41316a..0000000
Binary files a/public/img/logo.png and /dev/null differ
diff --git a/public/img/logo_flat.png b/public/img/logo_flat.png
deleted file mode 100644
index c45af9a..0000000
Binary files a/public/img/logo_flat.png and /dev/null differ
diff --git a/public/manifest.json b/public/manifest.json
index 543f824..2238451 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -1,32 +1,32 @@
{
- "theme_color": "#121212",
- "background_color": "#121212",
+ "theme_color": "#171717",
+ "background_color": "#171717",
"display": "standalone",
"scope": "/",
"start_url": "/",
"name": "slug",
- "description": "A URL shortener built with T3 Stack",
+ "description": "A beautifully open-source URL shortener",
"short_name": "slug",
"icons": [
{
- "src": "/img/icon-192x192.png",
+ "src": "/images/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
- "src": "/img/icon-256x256.png",
+ "src": "/images/icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
- "src": "/img/icon-384x384.png",
+ "src": "/images/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
- "src": "/img/icon-512x512.png",
+ "src": "/images/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
-}
+}
\ No newline at end of file
diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 0000000..2e06971
--- /dev/null
+++ b/src/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1 @@
+export { GET, POST } from "@/auth";
diff --git a/src/app/api/url/route.ts b/src/app/api/url/route.ts
new file mode 100644
index 0000000..ed4bc44
--- /dev/null
+++ b/src/app/api/url/route.ts
@@ -0,0 +1,58 @@
+import { Prisma } from "@prisma/client";
+import { NextResponse } from "next/server";
+import { db } from "@/server/db";
+
+export const GET = async (req: Request) => {
+ const url = new URL(req.url);
+ const params = url.searchParams.get("slug");
+ const newHeaders = new Headers(req.headers);
+
+ // If no slug provided (500):
+ if (!params || typeof params !== "string") {
+ return NextResponse.json(
+ { error: "🚧 Error: No slug provided." },
+ { status: 500 },
+ );
+ }
+
+ try {
+ const getLinkFromServer = await db.links.findUnique({
+ where: {
+ slug: params,
+ },
+ });
+
+ if (!getLinkFromServer) {
+ return NextResponse.json(
+ { error: "Error: Slug not found or invalid." },
+ { status: 404 },
+ );
+ }
+
+ await db.links.update({
+ where: {
+ id: getLinkFromServer.id,
+ },
+ data: {
+ clicks: {
+ increment: 1,
+ },
+ },
+ });
+
+ newHeaders.set("cache-control", "public, max-age=31536000, immutable");
+
+ return NextResponse.json(getLinkFromServer, {
+ headers: newHeaders,
+ });
+ } catch (error) {
+ if (error instanceof Prisma.PrismaClientKnownRequestError) {
+ console.log(`🚧 Error: ${error.message}`);
+ return NextResponse.json({ message: error.message }, { status: 400 });
+ }
+ return NextResponse.json(
+ { message: "Something went wrong." },
+ { status: 500 },
+ );
+ }
+};
diff --git a/src/app/auth/error/page.tsx b/src/app/auth/error/page.tsx
new file mode 100644
index 0000000..690be60
--- /dev/null
+++ b/src/app/auth/error/page.tsx
@@ -0,0 +1,23 @@
+import { sharedAnimationCards } from "@/components/auth/animation-cards";
+import { Card, CardContent, CardHeader, CardTitle } from "@/ui/card";
+import Link from "next/link";
+
+const AuthErrorPage = () => {
+ return (
+
+
+ Something went wrong.
+
+
+
+ Back to login
+
+
+
+ );
+};
+
+export default AuthErrorPage;
diff --git a/src/app/auth/layout.tsx b/src/app/auth/layout.tsx
new file mode 100644
index 0000000..7f5e12d
--- /dev/null
+++ b/src/app/auth/layout.tsx
@@ -0,0 +1,26 @@
+import Footer from "@/components/layout/footer";
+import { cn } from "@/utils";
+import type { ReactNode } from "react";
+
+interface AuthLayoutProps {
+ children: ReactNode;
+}
+
+const AuthLayout = (props: AuthLayoutProps) => {
+ return (
+ <>
+
+
+ {props.children}
+
+
+
+ >
+ );
+};
+
+export default AuthLayout;
diff --git a/src/app/auth/page.tsx b/src/app/auth/page.tsx
new file mode 100644
index 0000000..108cfe4
--- /dev/null
+++ b/src/app/auth/page.tsx
@@ -0,0 +1,33 @@
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/ui/card";
+import { cn } from "@/utils";
+
+import { sharedAnimationCards } from "@/components/auth/animation-cards";
+import SocialLogin from "@/components/auth/social-login";
+import Logo from "@/components/icons/logo";
+
+const AuthLoginPage = () => {
+ return (
+
+
+
+
+ Log in to Slug
+
+
+ Log in with your favorite social provider to get started:
+
+
+
+
+
+
+ );
+};
+
+export default AuthLoginPage;
diff --git a/src/app/check/[slug]/page.tsx b/src/app/check/[slug]/page.tsx
new file mode 100644
index 0000000..81ce57e
--- /dev/null
+++ b/src/app/check/[slug]/page.tsx
@@ -0,0 +1,10 @@
+const CheckSlug = ({ params }: { params: { slug: string } }) => {
+ return (
+
+
URL Check
+
Slug: {params.slug}
+
+ );
+};
+
+export default CheckSlug;
diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx
new file mode 100644
index 0000000..4b089fc
--- /dev/null
+++ b/src/app/dashboard/layout.tsx
@@ -0,0 +1,41 @@
+import type { ReactNode } from "react";
+
+import { Button } from "@/ui/button";
+import { PlusIcon } from "lucide-react";
+
+import DashboardRoutesComponent from "@/components/dashboard-routes";
+import { CreateLink } from "@/components/links/create-link";
+import Footer from "@/components/layout/footer";
+import { cn } from "@/utils";
+
+interface DashboardLayoutProps {
+ children: ReactNode;
+}
+
+const DashboardLayout = (props: DashboardLayoutProps) => {
+ return (
+ <>
+
+
+ {props.children}
+
+
+ >
+ );
+};
+
+export default DashboardLayout;
diff --git a/src/app/dashboard/loading.tsx b/src/app/dashboard/loading.tsx
new file mode 100644
index 0000000..a0fc490
--- /dev/null
+++ b/src/app/dashboard/loading.tsx
@@ -0,0 +1,12 @@
+import { LoaderIcon } from "lucide-react";
+
+const Loading = () => {
+ return (
+
+ );
+};
+
+export default Loading;
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
new file mode 100644
index 0000000..c2a2a2e
--- /dev/null
+++ b/src/app/dashboard/page.tsx
@@ -0,0 +1,83 @@
+import type { Metadata } from "next";
+
+import { getLinksByUser } from "@/server/queries";
+
+import CardLink from "@/components/links/card-link";
+import LinksLimit from "@/components/links/links-limit";
+import SearchLinks from "@/components/links/search-link";
+import { CreateLink } from "@/components/links/create-link";
+import { Button } from "@/ui/button";
+import { PackageOpenIcon, PlusIcon, SparklesIcon } from "lucide-react";
+
+export const metadata: Metadata = {
+ title: "Dashboard",
+};
+
+const DashboardPage = async ({
+ searchParams,
+}: {
+ searchParams?: {
+ search?: string;
+ };
+}) => {
+ const data = await getLinksByUser();
+ const query = searchParams?.search;
+
+ if (!data?.links) {
+ return Error
;
+ }
+
+ const filteredLinks = data.links.filter((link) => {
+ if (!query) return true;
+ return link.slug.includes(query);
+ });
+
+ return (
+
+
+
+
+
+
+ {filteredLinks
+ .sort((a, b) => {
+ return (
+ new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
+ );
+ })
+ .map((link) => {
+ return ;
+ })}
+
+ {filteredLinks.length === 0 && (
+
+ {query ? (
+
+ ) : (
+
+ )}
+ {query ? (
+
+ No links found with {query}{" "}
+ slug
+
+ ) : (
+
Start creating your first link:
+ )}
+
+
+
+
+ )}
+
+ );
+};
+
+export default DashboardPage;
diff --git a/src/app/dashboard/settings/page.tsx b/src/app/dashboard/settings/page.tsx
new file mode 100644
index 0000000..454aa14
--- /dev/null
+++ b/src/app/dashboard/settings/page.tsx
@@ -0,0 +1,50 @@
+import type { Metadata } from "next";
+
+import { auth } from "@/auth";
+import UpdateNameAvatar from "@/components/settings/update-name-avatar";
+import DeleteAccount from "@/components/settings/delete-account";
+import { Button } from "@/ui/button";
+import SettingsCard from "@/components/settings/card";
+import DownloadAllLinks from "@/components/links/download-all-links";
+import { HeartCrackIcon } from "lucide-react";
+
+export const metadata: Metadata = {
+ title: "Settings - Dashboard",
+};
+
+const SettingsPage = async () => {
+ const session = await auth();
+
+ if (!session) return null;
+
+ return (
+
+
+
+
+
+
Delete account:
+
+
+ Delete Account
+
+ }
+ />
+
+
+
+ );
+};
+
+export default SettingsPage;
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
new file mode 100644
index 0000000..465bb12
--- /dev/null
+++ b/src/app/layout.tsx
@@ -0,0 +1,128 @@
+import type { Metadata, Viewport } from "next";
+
+// Styles:
+import "@/styles/globals.css";
+import { cn } from "@/utils";
+
+// Providers:
+import { ThemeProvider } from "@/components/providers/theme-provider";
+import { ToasterComponent } from "@/components/providers/toaster";
+
+// External scripts:
+import Script from "next/script";
+
+// Layout:
+import Header from "@/components/layout/header";
+
+// Fonts:
+import localFont from "next/font/local";
+
+const interVariable = localFont({
+ variable: "--font-sans",
+ src: "../fonts/InterVariable.woff2",
+ weight: "100 900",
+ display: "swap",
+ preload: true,
+});
+
+const geistMonoVariable = localFont({
+ variable: "--font-geist-mono",
+ src: "../fonts/GeistMonoVF.woff2",
+ weight: "100 900",
+ display: "swap",
+ preload: true,
+});
+
+// Metadata:
+export const metadata: Metadata = {
+ metadataBase: new URL("https://slug.vercel.app"),
+ title: {
+ default: "Slug - A beautifully open-source URL shortener",
+ template: "%s - Slug",
+ },
+ manifest: "/manifest.json",
+ icons: [
+ {
+ rel: "icon",
+ type: "image/png",
+ sizes: "32x32",
+ url: "/images/logo_png.png",
+ },
+ {
+ rel: "icon",
+ type: "image/svg+xml",
+ sizes: "any",
+ url: "/images/logo_svg.svg",
+ },
+ {
+ rel: "apple-touch-icon",
+ type: "image/png",
+ sizes: "180x180",
+ url: "/images/apple-touch-icon.png",
+ },
+ ],
+ description: "An open-source URL shortener built with T3 Stack.",
+ openGraph: {
+ title: "Slug",
+ description: "An beautifully open-source URL shortener",
+ url: "https://slug.vercel.app/images/og_image.png",
+ siteName: "Slug - An beautifully open-source URL shortener",
+ locale: "en_US",
+ type: "website",
+ },
+ robots: {
+ index: true,
+ follow: true,
+ googleBot: {
+ index: true,
+ follow: true,
+ "max-video-preview": -1,
+ "max-image-preview": "large",
+ "max-snippet": -1,
+ },
+ },
+ twitter: {
+ title: "Slug - An beautifully open-source URL shortener",
+ card: "summary_large_image",
+ },
+};
+
+// Viewport:
+export const viewport: Viewport = {
+ themeColor: "#171717",
+};
+
+// App layout:
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
+
+
+ {children}
+
+
+
+
+
+ );
+}
diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx
new file mode 100644
index 0000000..602a2ff
--- /dev/null
+++ b/src/app/not-found.tsx
@@ -0,0 +1,44 @@
+import Footer from "@/components/layout/footer";
+import { buttonVariants } from "@/ui/button";
+import ExternalLink from "@/ui/external-link";
+import { ArrowUpRight, HomeIcon } from "lucide-react";
+import { headers } from "next/headers";
+import Link from "next/link";
+
+const NotFoundPage = async () => {
+ const headersList = headers();
+ const domain = headersList.get("host");
+ return (
+ <>
+
+
+
+ 404
+
+
+ Page not found
+
+
+ {`The page you're looking for doesn't exist on ${domain}.`}
+
+
+
+
+
Go back home
+
+
+ Create issue
+
+
+
+
+
+
+ >
+ );
+};
+
+export default NotFoundPage;
diff --git a/src/app/page.tsx b/src/app/page.tsx
new file mode 100644
index 0000000..a995d86
--- /dev/null
+++ b/src/app/page.tsx
@@ -0,0 +1,61 @@
+import Footer from "@/components/layout/footer";
+import { GithubLogo } from "@/components/icons/logos";
+import { buttonVariants } from "@/ui/button";
+import ExternalLink from "@/ui/external-link";
+import { TypographyH1, TypographyP } from "@/ui/typography";
+import { LinkIcon } from "lucide-react";
+import Link from "next/link";
+import BetaWarning from "@/components/beta-warning";
+
+export default async function Home() {
+ return (
+ <>
+
+
+
+
+ Enhance Your Link Management
+
+
+ Slug is an open-source platform that allows you to create, manage, and
+ share short links with ease. It's fast, secure, and easy to use.
+
+
+
+
+ Create a Link
+
+
+
+ Star on GitHub
+
+
+
+
+ >
+ );
+}
diff --git a/src/auth.config.ts b/src/auth.config.ts
new file mode 100644
index 0000000..96a755c
--- /dev/null
+++ b/src/auth.config.ts
@@ -0,0 +1,18 @@
+import type { NextAuthConfig } from "next-auth";
+import Github from "next-auth/providers/github";
+import Google from "next-auth/providers/google";
+
+import { env } from "./env.mjs";
+
+export default {
+ providers: [
+ Google({
+ clientId: env.GOOGLE_ID,
+ clientSecret: env.GOOGLE_CLIENT_SECRET,
+ }),
+ Github({
+ clientId: env.GITHUB_ID,
+ clientSecret: env.GITHUB_CLIENT_SECRET,
+ }),
+ ],
+} satisfies NextAuthConfig;
diff --git a/src/auth.ts b/src/auth.ts
new file mode 100644
index 0000000..718281c
--- /dev/null
+++ b/src/auth.ts
@@ -0,0 +1,96 @@
+import NextAuth from "next-auth";
+import { PrismaAdapter } from "@auth/prisma-adapter";
+
+import { db } from "@/server/db";
+import authConfig from "@/auth.config";
+import { getUserById } from "./server/utils/user";
+import { getTwoFactorConfirmationByUserId } from "./server/utils/two-factor-confirm";
+import { getAccountByUserId } from "./server/utils/account";
+import { env } from "./env.mjs";
+
+export const {
+ handlers: { GET, POST },
+ auth,
+ signIn,
+ signOut,
+ unstable_update,
+} = NextAuth({
+ adapter: PrismaAdapter(db),
+ session: { strategy: "jwt" },
+ basePath: "/api/auth",
+ secret: env.AUTH_SECRET,
+ pages: {
+ signIn: "/auth",
+ error: "/auth/error",
+ },
+ events: {
+ async linkAccount({ user }) {
+ await db.user.update({
+ where: { id: user.id },
+ data: { emailVerified: new Date() },
+ });
+ },
+ },
+ callbacks: {
+ async signIn({ user, account }) {
+ // Allow OAuth without email verification
+ if (account?.provider !== "credentials") return true;
+
+ const existingUser = await getUserById(user.id);
+
+ // Prevent sign in without email verification
+ if (!existingUser?.emailVerified) return false;
+
+ if (existingUser.isTwoFactorEnabled) {
+ const twoFactorConfirmation = await getTwoFactorConfirmationByUserId(
+ existingUser.id,
+ );
+
+ if (!twoFactorConfirmation) return false;
+
+ // Delete two factor confirmation for next sign in
+ await db.twoFactorConfirmation.delete({
+ where: { id: twoFactorConfirmation.id },
+ });
+ }
+
+ return true;
+ },
+ async session({ token, session }) {
+ if (token.sub && session.user) {
+ session.user.id = token.sub;
+ }
+ if (session.user) {
+ session.user.isTwoFactorEnabled = token.isTwoFactorEnabled as boolean;
+ }
+
+ if (session.user) {
+ session.user.name = token.name;
+ session.user.email = token.email!;
+ session.user.isOAuth = token.isOAuth as boolean;
+ session.user.limitLinks = token.limitLinks as number;
+ }
+
+ return session;
+ },
+ async jwt({ token }) {
+ if (!token.sub) return token;
+
+ const existingUser = await getUserById(token.sub);
+
+ if (!existingUser) return token;
+
+ const existingAccount = await getAccountByUserId(existingUser.id);
+
+ token.isOAuth = !!existingAccount;
+ token.name = existingUser.name;
+ token.email = existingUser.email;
+ token.role = existingUser.role;
+ token.isTwoFactorEnabled = existingUser.isTwoFactorEnabled;
+ token.limitLinks = existingUser.limitLinks;
+
+ return token;
+ },
+ },
+ ...authConfig,
+});
diff --git a/src/components/auth/animation-cards.ts b/src/components/auth/animation-cards.ts
new file mode 100644
index 0000000..1de2d58
--- /dev/null
+++ b/src/components/auth/animation-cards.ts
@@ -0,0 +1,2 @@
+export const sharedAnimationCards =
+ "duration-300 animate-in fade-in-15 slide-in-from-bottom-3";
diff --git a/src/components/auth/index.tsx b/src/components/auth/index.tsx
deleted file mode 100644
index 6ec9d80..0000000
--- a/src/components/auth/index.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import { useState } from "react";
-import { Button } from "@/ui";
-import { signOut, useSession } from "next-auth/react";
-import {
- BiBox,
- BiExit,
- BiHash,
- BiMessageSquareEdit,
- BiPlus,
-} from "react-icons/bi";
-import Link from "next/link";
-import toast from "react-hot-toast";
-import { Dropdown, DropdownItem } from "@/ui/dropdown";
-import LinkRoute from "@/ui/linkRoute";
-import { toastStyles } from "@/styles/toast";
-
-const Auth = () => {
- const { data: session, status } = useSession();
- const [disabled, setDisabled] = useState(false);
- const [closing, setClosing] = useState(false);
-
- const handleLogout = async () => {
- setDisabled(true);
- setClosing(true);
- try {
- await signOut({
- callbackUrl: "/",
- });
- } catch (error) {
- toast(
- "An error occurred while logout. Please create an issue about the problem.",
- {
- icon: "🤔",
- style: toastStyles,
- }
- );
- } finally {
- setDisabled(false);
- setClosing(false);
- }
- };
-
- if (status === "loading") {
- return (
-
- );
- }
-
- if (status === "unauthenticated") {
- return Sign in;
- }
-
- return (
- }
- >
-
- }>Create new link
-
-
- }>Dashboard
-
-
- } external={true}>
- Report a bug
-
-
- } onClick={handleLogout}>
- Sign Out
-
-
- );
-};
-
-export default Auth;
diff --git a/src/components/auth/sign-out.tsx b/src/components/auth/sign-out.tsx
new file mode 100644
index 0000000..1d56656
--- /dev/null
+++ b/src/components/auth/sign-out.tsx
@@ -0,0 +1,24 @@
+"use client";
+
+import { handleSignOut } from "@/server/actions/auth";
+import { DropdownMenuItem } from "@/ui/dropdown-menu";
+import { LogOutIcon } from "lucide-react";
+import { toast } from "sonner";
+
+export function SignOut() {
+ const iconSize = 15;
+
+ const handleLogout = async () => {
+ toast.promise(handleSignOut, {
+ loading: "Signing out...",
+ error: "Failed to sign out. Please try again.",
+ });
+ };
+
+ return (
+
+
+ Log Out
+
+ );
+}
diff --git a/src/components/auth/social-login.tsx b/src/components/auth/social-login.tsx
new file mode 100644
index 0000000..908316d
--- /dev/null
+++ b/src/components/auth/social-login.tsx
@@ -0,0 +1,67 @@
+"use client";
+
+import { Button } from "@/ui/button";
+import { GithubLogo, GoogleLogo } from "@/components/icons/logos";
+import { signIn } from "next-auth/react";
+import { DEFAULT_LOGIN_REDIRECT_URL } from "@/routes";
+import { useSearchParams } from "next/navigation";
+import { useState } from "react";
+import { Loader } from "lucide-react";
+import { toast } from "sonner";
+
+const socialProviders = [
+ {
+ name: "Continue with Google",
+ icon: ,
+ provider: "google",
+ },
+ {
+ name: "Continue with GitHub",
+ icon: ,
+ provider: "github",
+ },
+];
+
+const SocialLogin = () => {
+ const searchParams = useSearchParams();
+ const callbackUrl = searchParams.get("callbackUrl");
+ const [loading, setLoading] = useState(false);
+ const [provider, setProvider] = useState();
+
+ const handleSocialLogin = async (provider: string) => {
+ try {
+ setLoading(true);
+ setProvider(provider);
+ await signIn(provider, {
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
+ callbackUrl: callbackUrl || DEFAULT_LOGIN_REDIRECT_URL,
+ });
+ } catch (error) {
+ toast.error("An error occurred while trying to sign in");
+ }
+ };
+
+ return (
+
+ {socialProviders.map((sp) => (
+
+ ))}
+
+ );
+};
+
+export default SocialLogin;
diff --git a/src/components/auth/user-btn.tsx b/src/components/auth/user-btn.tsx
new file mode 100644
index 0000000..ff5b619
--- /dev/null
+++ b/src/components/auth/user-btn.tsx
@@ -0,0 +1,64 @@
+import { buttonVariants } from "@/ui/button";
+import { auth } from "@/auth";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "@/ui/dropdown-menu";
+import Avatar from "boring-avatars";
+import UserMenu from "./user-menu";
+import { SignOut } from "./sign-out";
+import { ArrowRight } from "lucide-react";
+import Link from "next/link";
+
+export default async function UserButton() {
+ const session = await auth();
+
+ if (!session?.user)
+ return (
+
+ Get Started
+
+
+ );
+
+ if (session?.user)
+ return (
+
+
+ {session.user.name && (
+
+ )}
+
+
+
+
+
+ {session.user.name}
+
+
+ {session.user.email}
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/auth/user-menu.tsx b/src/components/auth/user-menu.tsx
new file mode 100644
index 0000000..8d6d284
--- /dev/null
+++ b/src/components/auth/user-menu.tsx
@@ -0,0 +1,68 @@
+"use client";
+
+import { DropdownMenuItem } from "@/ui/dropdown-menu";
+import {
+ ArrowUpRight,
+ BugIcon,
+ HomeIcon,
+ LayoutDashboardIcon,
+ SettingsIcon,
+} from "lucide-react";
+import Link from "next/link";
+import { XLogo } from "@/components/icons/logos";
+
+const UserMenu = () => {
+ const iconSize = 15;
+
+ return (
+ <>
+
+
+
+ Home
+
+
+
+
+
+ Dashboard
+
+
+
+
+
+ Settings
+
+
+
+
+
+
+ Report a bug
+
+
+
+
+
+
+
+
+ Contact
+
+
+
+
+ >
+ );
+};
+
+export default UserMenu;
diff --git a/src/components/beta-warning.tsx b/src/components/beta-warning.tsx
new file mode 100644
index 0000000..0b00cc4
--- /dev/null
+++ b/src/components/beta-warning.tsx
@@ -0,0 +1,29 @@
+import Alert from "@/ui/alert";
+import ExternalLink from "@/ui/external-link";
+import { SproutIcon } from "lucide-react";
+
+const BetaWarning = () => {
+ return (
+ }
+ className="rounded-none border-y bg-white p-4 shadow-sm dark:border-neutral-800 dark:bg-neutral-900/85 dark:text-white text-neutral-800"
+ containerClassName="container"
+ iconSize={12}
+ >
+
+ Welcome to the Slug beta. If you detect any problem or bug, feel
+ free to{" "}
+
+ create an issue
+ {" "}
+ on Github.
+
+
+ );
+};
+
+export default BetaWarning;
diff --git a/src/components/card/index.tsx b/src/components/card/index.tsx
deleted file mode 100644
index f6761c8..0000000
--- a/src/components/card/index.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import { useState } from "react";
-import toast from "react-hot-toast";
-import { BiCopy, BiEdit, BiSlider, BiTrash } from "react-icons/bi";
-import IconButton from "@/ui/iconButton";
-import { Dropdown, DropdownItem } from "@/ui/dropdown";
-import Modal from "@/ui/modal";
-import Edit from "../functions/edit";
-import Delete from "../functions/delete";
-
-import { CardProps } from "./interface";
-import { toastStyles } from "@/styles/toast";
-
-const Card = (props: CardProps) => {
- const [editModal, setEditModal] = useState(false);
- const [deleteModal, setDeleteModal] = useState(false);
-
- const handleEditModal = () => {
- setEditModal(!editModal);
- };
-
- const handleDeleteModal = () => {
- setDeleteModal(!deleteModal);
- };
-
- const copyToClipboard = async (txt: string) => {
- try {
- const clipboardItem = new ClipboardItem({
- "text/plain": new Blob([txt], { type: "text/plain" }),
- });
- await navigator.clipboard.write([clipboardItem]);
- } catch (error) {
- await navigator.clipboard.writeText(txt);
- }
- toast("Copied to clipboard", {
- icon: "🚀",
- style: toastStyles,
- });
- };
-
- return (
-
-
-
-
- /s/{props.slug}
-
-
}
- className="ml-1 p-1 text-gray-500 transition-colors duration-200 hover:text-gray-200"
- onClick={() =>
- copyToClipboard(`https://slug.vercel.app/s/${props.slug}`)
- }
- />
-
-
{props.url}
-
{props.description}
-
-
- }
- >
- }
- onClick={() =>
- copyToClipboard(`https://slug.vercel.app/s/${props.slug}`)
- }
- >
- Copy
-
- } onClick={handleEditModal}>
- Edit
-
- }
- onClick={handleDeleteModal}
- >
- Delete
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default Card;
diff --git a/src/components/card/interface.ts b/src/components/card/interface.ts
deleted file mode 100644
index e7be808..0000000
--- a/src/components/card/interface.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export interface CardProps {
- id: number;
- url: string;
- slug: string;
- description: string;
- className?: string;
-}
diff --git a/src/components/change-theme.tsx b/src/components/change-theme.tsx
new file mode 100644
index 0000000..ddf6cd2
--- /dev/null
+++ b/src/components/change-theme.tsx
@@ -0,0 +1,71 @@
+"use client";
+
+import * as React from "react";
+import { Monitor, MoonIcon, Sun, SunIcon } from "lucide-react";
+import { useTheme } from "next-themes";
+
+import { Button } from "@/ui/button";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from "@/ui/dropdown-menu";
+
+export function ModeToggle() {
+ const { setTheme } = useTheme();
+
+ return (
+
+
+
+
+
+
+ Theme
+
+
+ setTheme("light")}
+ >
+
+ Light
+
+ setTheme("dark")}
+ >
+
+ Dark
+
+ setTheme("system")}
+ >
+
+ System
+
+
+
+ );
+}
diff --git a/src/components/command/index.tsx b/src/components/command/index.tsx
deleted file mode 100644
index bd94bfb..0000000
--- a/src/components/command/index.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-import { useRouter } from "next/router";
-import { useState, useEffect } from "react";
-import { BiBox, BiCommand, BiMessageSquareEdit, BiPlus } from "react-icons/bi";
-import { BsGithub, BsTwitter } from "react-icons/bs";
-import { Command, CommandInput, CommandList, CommandOption } from "superkey";
-
-const data = [
- {
- id: 1,
- name: "Create new link",
- href: "/dash/create",
- icon: ,
- },
- {
- id: 2,
- name: "Dashboard",
- href: "/dash",
- icon: ,
- },
- {
- id: 3,
- name: "Report a bug",
- href: "https://github.com/pheralb/slug/issues/new",
- icon: ,
- },
- {
- id: 4,
- name: "Repository",
- href: "https://github.com/pheralb/slug",
- icon: ,
- },
- {
- id: 5,
- name: "Twitter",
- href: "https://twitter.com/pheralb_",
- icon: ,
- },
-];
-
-const CommandMenu = () => {
- const [value, setValue] = useState("");
- const [open, setOpen] = useState(false);
- const router = useRouter();
-
- useEffect(() => {
- function handleKeyDown(event?: KeyboardEvent) {
- if (event?.key === "k" && (event?.metaKey || event?.ctrlKey)) {
- event?.preventDefault();
- setOpen(!open);
- }
- }
-
- if (typeof window !== "undefined") {
- window.addEventListener("keydown", handleKeyDown);
- return () => {
- window.removeEventListener("keydown", handleKeyDown);
- };
- }
- }, [open]);
-
- const filteredData = data.filter((doc) => {
- return doc.name?.toLowerCase().includes(value.toLowerCase());
- });
-
- return (
- <>
- setOpen(true)}
- />
- {
- setOpen(!open);
- }}
- commandFunction={(action) => {
- setOpen(false);
- router.push(`${action}`);
- }}
- className="border border-neutral-800 bg-midnight text-white"
- overlayClassName="bg-midnight/50"
- >
- {
- setValue(e.target.value);
- }}
- className="border-b border-neutral-800 bg-midnight text-white"
- />
-
- {filteredData.map((action) => (
-
-
-
{action.icon}
-
{action.name}
-
-
- ))}
-
-
- >
- );
-};
-
-export default CommandMenu;
diff --git a/src/components/commandK/index.tsx b/src/components/commandK/index.tsx
new file mode 100644
index 0000000..ca9b3b6
--- /dev/null
+++ b/src/components/commandK/index.tsx
@@ -0,0 +1,116 @@
+"use client";
+
+import {
+ CommandDialog,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "@/ui/command";
+import { useEffect, useState } from "react";
+import { Button } from "@/ui/button";
+import { SearchIcon } from "lucide-react";
+import { useRouter } from "next/navigation";
+import { useTheme } from "next-themes";
+import { toast } from "sonner";
+
+// Pages:
+import { ChangeTheme, DocumentationPages, Pages, SocialPages } from "./items";
+
+const CommandK = () => {
+ const [open, setOpen] = useState(false);
+ const router = useRouter();
+ const { setTheme } = useTheme();
+
+ useEffect(() => {
+ const down = (e: KeyboardEvent) => {
+ if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
+ e.preventDefault();
+ setOpen((open) => !open);
+ }
+ };
+
+ document.addEventListener("keydown", down);
+ return () => document.removeEventListener("keydown", down);
+ }, []);
+
+ const handleRoutePush = async (href: string) => {
+ router.push(href);
+ setOpen(false);
+ };
+
+ const handleExternalRoute = (href: string) => {
+ window.open(href, "_blank");
+ setOpen(false);
+ };
+
+ const handleChangeTheme = (theme: string) => {
+ setTheme(theme);
+ setOpen(false);
+ toast.success(`Theme changed to ${theme}`);
+ };
+
+ return (
+ <>
+
+
+
+
+ No results found
+
+ {Pages.map((page) => (
+ handleRoutePush(page.href)}
+ >
+
+ {page.name}
+
+ ))}
+
+
+ {ChangeTheme.map((theme) => (
+ handleChangeTheme(theme.param)}
+ >
+
+ {theme.name}
+
+ ))}
+
+
+ {DocumentationPages.map((doc) => (
+ handleExternalRoute(doc.href)}
+ >
+
+ {doc.name}
+
+ ))}
+
+
+ {SocialPages.map((page) => (
+ handleExternalRoute(page.href)}
+ >
+
+ {page.name}
+
+ ))}
+
+
+
+ >
+ );
+};
+
+export default CommandK;
diff --git a/src/components/commandK/items.ts b/src/components/commandK/items.ts
new file mode 100644
index 0000000..25623ca
--- /dev/null
+++ b/src/components/commandK/items.ts
@@ -0,0 +1,85 @@
+import {
+ BugIcon,
+ HeartHandshakeIcon,
+ HomeIcon,
+ LayoutDashboardIcon,
+ MonitorIcon,
+ MoonIcon,
+ SettingsIcon,
+ SproutIcon,
+ SunIcon,
+ TelescopeIcon,
+} from "lucide-react";
+import { GithubLogo, XLogo } from "@/components/icons/logos";
+
+export const Pages = [
+ {
+ name: "Home",
+ href: "/",
+ icon: HomeIcon,
+ },
+ {
+ name: "Dashboard",
+ href: "/dashboard",
+ icon: LayoutDashboardIcon,
+ },
+ {
+ name: "Settings",
+ href: "/dashboard/settings",
+ icon: SettingsIcon,
+ }
+];
+
+export const ChangeTheme = [
+ {
+ name: "Light Theme",
+ param: "light",
+ icon: SunIcon,
+ },
+ {
+ name: "Dark Theme",
+ param: "dark",
+ icon: MoonIcon,
+ },
+ {
+ name: "System Theme",
+ param: "system",
+ icon: MonitorIcon,
+ },
+];
+
+export const DocumentationPages = [
+ {
+ name: "Getting Started",
+ href: "https://github.com/pheralb/slug?tab=readme-ov-file#-getting-started",
+ icon: SproutIcon,
+ },
+ {
+ name: "Roadmap",
+ href: "https://github.com/pheralb/slug?tab=readme-ov-file#-roadmap",
+ icon: TelescopeIcon,
+ },
+ {
+ name: "Contributing",
+ href: "https://github.com/pheralb/slug?tab=readme-ov-file#%EF%B8%8F-contributing",
+ icon: HeartHandshakeIcon,
+ },
+ {
+ name: "Report a Bug",
+ href: "https://github.com/pheralb/slug/issues/new/choose",
+ icon: BugIcon,
+ }
+];
+
+export const SocialPages = [
+ {
+ name: "X (Formerly Twitter)",
+ href: "https://twitter.com/pheralb_",
+ icon: XLogo,
+ },
+ {
+ name: "GitHub Repository",
+ href: "https://github.com/pheralb/slug",
+ icon: GithubLogo,
+ },
+];
diff --git a/src/components/dashboard-routes.tsx b/src/components/dashboard-routes.tsx
new file mode 100644
index 0000000..7792b69
--- /dev/null
+++ b/src/components/dashboard-routes.tsx
@@ -0,0 +1,51 @@
+"use client";
+
+import { usePathname } from "next/navigation";
+import Link from "next/link";
+import { Link2Icon, SettingsIcon } from "lucide-react";
+import { cn } from "@/utils";
+
+const DashboardRoutes = [
+ {
+ title: "Links",
+ path: "/dashboard",
+ icon: Link2Icon,
+ },
+ {
+ title: "Settings",
+ path: "/dashboard/settings",
+ icon: SettingsIcon,
+ },
+];
+
+const DashboardRoutesComponent = () => {
+ const pathname = usePathname();
+ return (
+
+
+ {DashboardRoutes.map((route) => (
+
+
+
+ {route.title}
+
+
+ ))}
+
+
+ );
+};
+
+export default DashboardRoutesComponent;
diff --git a/src/components/footer/index.tsx b/src/components/footer/index.tsx
deleted file mode 100644
index 96f0938..0000000
--- a/src/components/footer/index.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { BiLinkExternal } from "react-icons/bi";
-import { BsTwitter } from "react-icons/bs";
-
-const Footer = () => {
- return (
-
-
-
-
⚡ Made by Pablo using
-
-
-
-
-
-
-
- );
-};
-
-export default Footer;
diff --git a/src/components/functions/create/index.tsx b/src/components/functions/create/index.tsx
deleted file mode 100644
index 38d3bc3..0000000
--- a/src/components/functions/create/index.tsx
+++ /dev/null
@@ -1,141 +0,0 @@
-import { useRouter } from "next/router";
-import { useState } from "react";
-import { useForm } from "react-hook-form";
-import { trpc } from "@/utils/trpc";
-import { CreateLinkInput } from "@/schema/link.schema";
-import { BiRefresh, BiRocket } from "react-icons/bi";
-import { nanoid } from "nanoid";
-import toast from "react-hot-toast";
-
-import Button from "@/ui/button";
-import Alert from "@/ui/alert";
-import { toastStyles } from "@/styles/toast";
-
-const Create = () => {
- const {
- handleSubmit,
- register,
- setValue,
- setError,
- formState: { errors },
- } = useForm();
- const [loading, setLoading] = useState(false);
- const router = useRouter();
-
- const { mutate } = trpc.links.createLink.useMutation({
- onSuccess: () => {
- router.push(`/dash`);
- setLoading(false);
- toast("Link created successfully", {
- icon: "🥳",
- style: toastStyles,
- });
- },
- onError: () => {
- setLoading(false);
- setError("slug", {
- type: "manual",
- message: "Slug already exists. Please try another one or click 'Randomize' button.",
- });
- },
- });
-
- const onSubmit = (values: CreateLinkInput) => {
- // Check if slug & url are equals to prevent infinite redirect =>
- if (values.slug === values.url) {
- setError("url", {
- type: "manual",
- message: "The URL and the slug cannot be the same",
- });
- return;
- }
- setLoading(true);
- mutate(values);
- };
-
- const handleGenerateRandomSlug = (e: React.MouseEvent) => {
- e.preventDefault();
- const randomSlug = nanoid(6);
- setValue("slug", randomSlug);
- };
-
- return (
-
- );
-};
-
-export default Create;
diff --git a/src/components/functions/delete/index.tsx b/src/components/functions/delete/index.tsx
deleted file mode 100644
index 3c464f4..0000000
--- a/src/components/functions/delete/index.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-import { useState, useEffect } from "react";
-import { useForm } from "react-hook-form";
-import { trpc } from "@/utils/trpc";
-import { useRouter } from "next/router";
-import { Button } from "@/ui";
-import toast from "react-hot-toast";
-import Alert from "@/ui/alert";
-import { BiTrash } from "react-icons/bi";
-import { nanoid } from "nanoid";
-import { toastStyles } from "@/styles/toast";
-
-interface DeleteProps {
- id: number;
-}
-
-const Delete = (props: DeleteProps) => {
- const {
- handleSubmit,
- register,
- getValues,
- formState: { errors },
- } = useForm();
- const [loading, setLoading] = useState(false);
- const router = useRouter();
- const [disabled, setDisabled] = useState(false);
- const [validate, setValidate] = useState(String);
-
- useEffect(() => {
- const random = nanoid(5);
- setValidate(random);
- if (validate === random) {
- setDisabled(true);
- }
- }, []);
-
- const { mutate, error } = trpc.links.deleteLink.useMutation({
- onSuccess: () => {
- router.reload();
- setLoading(false);
- toast("Link deleted successfully", {
- icon: "🥳",
- style: toastStyles,
- });
- },
- onError: () => {
- setLoading(false);
- alert("Error");
- },
- });
-
- const onSubmit = () => {
- if (validate === getValues("validate")) {
- setLoading(true);
- mutate({
- linkId: props.id,
- });
- } else {
- toast("The values do not match. Check the validation.", {
- icon: "🤔",
- style: toastStyles,
- });
- }
- };
-
- return (
-
- );
-};
-
-export default Delete;
diff --git a/src/components/functions/edit/index.tsx b/src/components/functions/edit/index.tsx
deleted file mode 100644
index 8a9e2b8..0000000
--- a/src/components/functions/edit/index.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-import { useState, useEffect } from "react";
-import { useForm } from "react-hook-form";
-import { EditLinkInput } from "@/schema/link.schema";
-import { trpc } from "@/utils/trpc";
-import { useRouter } from "next/router";
-import { Button } from "@/ui";
-import toast from "react-hot-toast";
-import Alert from "@/ui/alert";
-import { BiCheck } from "react-icons/bi";
-import { toastStyles } from "@/styles/toast";
-
-interface EditProps {
- id: number;
- slug: string;
- url: string;
- description: string;
-}
-
-const Edit = (props: EditProps) => {
- const {
- handleSubmit,
- setValue,
- register,
- formState: { errors },
- } = useForm();
- const [loading, setLoading] = useState(false);
- const router = useRouter();
- const [disabled, setDisabled] = useState(false);
-
- const { mutate, error } = trpc.links.editLink.useMutation({
- onSuccess: () => {
- router.reload();
- setLoading(false);
- toast("Link edited successfully", {
- icon: "🥳",
- style: toastStyles,
- });
- },
- onError: () => {
- setLoading(false);
- alert("Error");
- },
- });
-
- const onSubmit = (values: EditLinkInput) => {
- setValue("slug", props.slug);
- setLoading(true);
- mutate({
- slug: props.slug,
- url: values.url,
- description: values.description,
- });
- };
-
- return (
-
- );
-};
-
-export default Edit;
diff --git a/src/components/header/index.tsx b/src/components/header/index.tsx
deleted file mode 100644
index 1a051b8..0000000
--- a/src/components/header/index.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import Link from "next/link";
-import { BsGithub } from "react-icons/bs";
-import Auth from "@/components/auth";
-import IconButton from "@/ui/iconButton";
-import CommandMenu from "../command";
-
-const Header = () => {
- return (
-
-
-
-
-
-
slug
-
-
-
-
-
- );
-};
-
-export default Header;
diff --git a/src/components/icons/logo.tsx b/src/components/icons/logo.tsx
index 6cf44ce..996dfb5 100644
--- a/src/components/icons/logo.tsx
+++ b/src/components/icons/logo.tsx
@@ -1,19 +1,72 @@
-import React, { ComponentProps } from "react";
+import type { ComponentProps } from "react";
const Logo: React.FC> = (props) => {
return (
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};
diff --git a/src/components/icons/logos.tsx b/src/components/icons/logos.tsx
new file mode 100644
index 0000000..8bd9eb4
--- /dev/null
+++ b/src/components/icons/logos.tsx
@@ -0,0 +1,84 @@
+interface SharedLogoProps extends React.SVGProps {
+ className?: string;
+}
+
+export const GoogleLogo = (props: SharedLogoProps) => (
+
+
+
+
+
+
+);
+
+export const GithubLogo = (props: SharedLogoProps) => (
+
+
+
+);
+
+export const XLogo = (props: SharedLogoProps) => (
+
+
+
+);
+
+export const T3Logo = (props: SharedLogoProps) => (
+
+
+
+
+
+);
diff --git a/src/components/layout/footer.tsx b/src/components/layout/footer.tsx
new file mode 100644
index 0000000..f6c885c
--- /dev/null
+++ b/src/components/layout/footer.tsx
@@ -0,0 +1,50 @@
+import ExternalLink from "@/ui/external-link";
+import { cn } from "@/utils";
+import React from "react";
+import { T3Logo, XLogo } from "../icons/logos";
+import { ArrowUpRight, Heart } from "lucide-react";
+
+interface FooterProps {
+ className?: string;
+}
+
+const Footer = (props: FooterProps) => {
+ return (
+
+ );
+};
+
+export default Footer;
diff --git a/src/components/layout/header.tsx b/src/components/layout/header.tsx
new file mode 100644
index 0000000..98e6a1e
--- /dev/null
+++ b/src/components/layout/header.tsx
@@ -0,0 +1,60 @@
+import Link from "next/link";
+import { cn } from "@/utils";
+
+import { buttonVariants } from "@/ui/button";
+import ExternalLink from "@/ui/external-link";
+import { Badge } from "@/ui/badge";
+
+import { ModeToggle } from "@/components/change-theme";
+import UserButton from "@/components/auth/user-btn";
+import Logo from "@/components/icons/logo";
+import { GithubLogo } from "@/components/icons/logos";
+import CommandK from "@/components/commandK";
+
+const Header = () => {
+ return (
+
+ );
+};
+
+export default Header;
diff --git a/src/components/link/index.tsx b/src/components/link/index.tsx
deleted file mode 100644
index a9094a4..0000000
--- a/src/components/link/index.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from "react";
-import NextLink from "next/link";
-
-interface LinksProps {
- href: string;
- children: React.ReactNode;
-}
-
-const Link = (props: LinksProps) => {
- return (
-
- {props.children}
-
- );
-};
-
-export default Link;
diff --git a/src/components/links/card-link.tsx b/src/components/links/card-link.tsx
new file mode 100644
index 0000000..ff0c3c7
--- /dev/null
+++ b/src/components/links/card-link.tsx
@@ -0,0 +1,135 @@
+import type { Links } from "@prisma/client";
+
+import { formatDate } from "@/utils/formatDate";
+import {
+ ChevronDownIcon,
+ CopyIcon,
+ QrCodeIcon,
+ SettingsIcon,
+ TrashIcon,
+} from "lucide-react";
+
+import {
+ Collapsible,
+ CollapsibleContent,
+ CollapsibleTrigger,
+} from "@/ui/collapsible";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/ui/dropdown-menu";
+import { Dialog, DialogTrigger } from "@/ui/dialog";
+import ExternalLink from "@/ui/external-link";
+
+import CopyQR from "./copy-qr";
+import DeleteLink from "./delete-link";
+import EditLink from "./edit-link";
+import ShowClicks from "./show-clicks-link";
+import CopyLinkDropdown from "./copy-link";
+
+interface CardLinkProps {
+ linkInfo: Links;
+}
+
+const CardLink = ({ linkInfo }: CardLinkProps) => {
+ return (
+
+
+
+ /
+ {linkInfo.slug}
+
+
+
+ {/*
+ Radix Dialog + DropdownMenu bug 🥺
+ https://github.com/radix-ui/primitives/issues/1836
+ */}
+
+
+
+
+ }
+ link={linkInfo}
+ />
+
+
+
+ }
+ />
+
+
+
+ {linkInfo.url}
+
+
+
+
+ {linkInfo.description}
+
+
+
+ Info
+
+
{formatDate(linkInfo.createdAt)}
+
+
+
+
+
+ {linkInfo.description && (
+
+
+ {linkInfo.description}
+
+
+ )}
+
+
+
+ );
+};
+
+export default CardLink;
diff --git a/src/components/links/copy-link.tsx b/src/components/links/copy-link.tsx
new file mode 100644
index 0000000..a5d8978
--- /dev/null
+++ b/src/components/links/copy-link.tsx
@@ -0,0 +1,42 @@
+"use client";
+
+import { useCopyToClipboard } from "@/hooks/useCopyToClipboard";
+import { toast } from "sonner";
+import { DropdownMenuItem } from "@/ui/dropdown-menu";
+import { ClipboardIcon } from "lucide-react";
+
+interface CopyLinkProps {
+ slug: string;
+ className?: string;
+}
+
+const CopyLinkDropdown = (props: CopyLinkProps) => {
+ const [, copy] = useCopyToClipboard();
+ const url = "https://slug.vercel.app";
+
+ const handleCopy = (text: string) => () => {
+ copy(text)
+ .then(() => {
+ toast.success("Link copied to clipboard", {
+ description: `${text}`,
+ });
+ })
+ .catch((error) => {
+ toast.error(
+ "An unexpected error has occurred. Please try again later.",
+ {
+ description: error,
+ },
+ );
+ });
+ };
+
+ return (
+
+
+ Copy to clipboard
+
+ );
+};
+
+export default CopyLinkDropdown;
diff --git a/src/components/links/copy-qr.tsx b/src/components/links/copy-qr.tsx
new file mode 100644
index 0000000..0724007
--- /dev/null
+++ b/src/components/links/copy-qr.tsx
@@ -0,0 +1,99 @@
+"use client";
+
+import type { Links } from "@prisma/client";
+import QRCode from "react-qr-code";
+
+import {
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@/ui/dialog";
+import { Button } from "@/ui/button";
+import { DownloadIcon } from "lucide-react";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/ui/dropdown-menu";
+
+interface CopyQRProps {
+ linkInfo: Links;
+}
+
+const CopyQR = ({ linkInfo }: CopyQRProps) => {
+
+ const handleDownloadQRImage = (type: "png" | "svg") => {
+ const svg = document.getElementById("qr-code");
+ const svgData = new XMLSerializer().serializeToString(svg!);
+ if (type === "svg") {
+ const svgBlob = new Blob([svgData], { type: "image/svg+xml" });
+ const downloadLink = document.createElement("a");
+ downloadLink.download = `${linkInfo.slug}_slug_app.svg`;
+ downloadLink.href = window.URL.createObjectURL(svgBlob);
+ downloadLink.click();
+ } else if (type === "png") {
+ const canvas = document.createElement("canvas");
+ const ctx = canvas.getContext("2d");
+ const img = new Image();
+ img.onload = () => {
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx!.drawImage(img, 0, 0);
+ const pngFile = canvas.toDataURL("image/png");
+ const downloadLink = document.createElement("a");
+ downloadLink.download = `${linkInfo.slug}_slug_app.png`;
+ downloadLink.href = pngFile;
+ downloadLink.click();
+ };
+ img.src = `data:image/svg+xml;base64,${btoa(svgData)}`;
+ }
+ };
+
+ return (
+
+
+ Copy QR Code
+ {linkInfo.description}
+
+
+
+
+
+
{`/${linkInfo.slug}`}
+
+
+
+
+
+
+
+ handleDownloadQRImage("png")}>
+ Download as PNG
+
+ handleDownloadQRImage("svg")}>
+ Download as SVG
+
+
+
+
+
+
+
+
+ );
+};
+
+export default CopyQR;
diff --git a/src/components/links/create-link.tsx b/src/components/links/create-link.tsx
new file mode 100644
index 0000000..d2b3579
--- /dev/null
+++ b/src/components/links/create-link.tsx
@@ -0,0 +1,211 @@
+"use client";
+
+import type { z } from "zod";
+import { CreateLinkSchema } from "@/server/schemas";
+import { useState, type ReactNode } from "react";
+import { useForm } from "react-hook-form";
+import { toast } from "sonner";
+import { zodResolver } from "@hookform/resolvers/zod";
+import JSConfetti from "js-confetti";
+
+import { checkIfSlugExist, createLink } from "@/server/actions/links";
+
+import Alert from "@/ui/alert";
+import { Button } from "@/ui/button";
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/ui/dialog";
+import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/ui/form";
+import { Input, Textarea } from "@/ui/input";
+import { LoaderIcon, RocketIcon, ShuffleIcon } from "lucide-react";
+
+interface CreateLinkProps {
+ children: ReactNode;
+ slug?: string;
+}
+
+export function CreateLink(props: CreateLinkProps) {
+ const [loading, setLoading] = useState(false);
+ const [open, setOpen] = useState(false);
+ const [message, setMessage] = useState("");
+ const [isError, setError] = useState(false);
+
+ // Main form:
+ const form = useForm>({
+ resolver: zodResolver(CreateLinkSchema),
+ defaultValues: {
+ url: "",
+ slug: props.slug ?? "",
+ description: "",
+ },
+ });
+
+ // Form Submit method:
+ const onSubmit = async (values: z.infer) => {
+ // Check if slug & url are equals to prevent infinite redirect =>
+ if (values.slug === values.url) {
+ setLoading(false);
+ setError(true);
+ setMessage("The URL and the slug cannot be the same");
+ return;
+ }
+
+ try {
+ setLoading(true);
+
+ const slugExists = await checkIfSlugExist(values.slug);
+
+ if (slugExists) {
+ toast.error(
+ "The slug is already exist. Write another or generate a random slug.",
+ );
+ return;
+ }
+
+ const result = await createLink(values);
+
+ if (result.error && result.limit) {
+ toast.info(result.error);
+ return;
+ }
+
+ toast.success("Link created successfully", {
+ description: `Url: https://slug.vercel.app/${values.slug}`,
+ duration: 10000,
+ closeButton: true,
+ });
+
+ form.reset();
+ setOpen(false);
+ await generateConfetti();
+ } catch (error) {
+ toast.error("An unexpected error has occurred. Please try again later.");
+ } finally {
+ setError(false);
+ setMessage("");
+ setLoading(false);
+ }
+ };
+
+ const generateConfetti = async () => {
+ const jsConfetti = new JSConfetti();
+ await jsConfetti.addConfetti({
+ confettiColors: ["#fdd835", "#4caf50", "#2196f3", "#f44336", "#ff9800"],
+ confettiRadius: 3,
+ confettiNumber: 50,
+ });
+ };
+
+ const handleGenerateRandomSlug = (e: React.MouseEvent) => {
+ e.preventDefault();
+ const randomSlug = Math.random().toString(36).substring(7);
+ form.setValue("slug", randomSlug);
+ };
+
+ return (
+
+ );
+}
diff --git a/src/components/links/delete-link.tsx b/src/components/links/delete-link.tsx
new file mode 100644
index 0000000..7fa5621
--- /dev/null
+++ b/src/components/links/delete-link.tsx
@@ -0,0 +1,122 @@
+"use client";
+
+import type { Links } from "@prisma/client";
+import type { z } from "zod";
+import { useState, type ReactNode } from "react";
+
+import { deleteLink } from "@/server/actions/links";
+import { DeleteLinkSchema } from "@/server/schemas";
+
+import { toast } from "sonner";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/ui/dialog";
+import { Input } from "@/ui/input";
+import { Button } from "@/ui/button";
+import { LoaderIcon, TrashIcon } from "lucide-react";
+import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/ui/form";
+
+interface DeleteLinkProps {
+ link: Links;
+ trigger: ReactNode;
+}
+
+const DeleteLink = ({ link, trigger }: DeleteLinkProps) => {
+ const [open, setOpen] = useState(false);
+ const [loading, setLoading] = useState(false);
+
+ const form = useForm>({
+ resolver: zodResolver(DeleteLinkSchema),
+ });
+
+ const handleDelete = async (values: z.infer) => {
+ if (values.slug !== link.slug) {
+ toast.error("The slug does not match.");
+ return;
+ }
+
+ try {
+ setLoading(true);
+ await deleteLink(link.id);
+ setOpen(false);
+ toast.success("Link deleted successfully.", {
+ description: `The link /${link.slug} has been deleted.`,
+ });
+ } catch (error) {
+ toast.error(
+ "An error occurred while deleting the link. Please try again.",
+ );
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default DeleteLink;
diff --git a/src/components/links/download-all-links.tsx b/src/components/links/download-all-links.tsx
new file mode 100644
index 0000000..cdbc836
--- /dev/null
+++ b/src/components/links/download-all-links.tsx
@@ -0,0 +1,46 @@
+"use client";
+
+import { downloadAllLinks } from "@/server/actions/links";
+import { Button } from "@/ui/button";
+import { DownloadIcon } from "lucide-react";
+import { useState } from "react";
+import { toast } from "sonner";
+
+const DownloadAllLinks = () => {
+ const [isLoading, setIsLoading] = useState(false);
+
+ const handleDownloadLinks = async () => {
+ setIsLoading(true);
+ try {
+ const links = await downloadAllLinks();
+ const blob = new Blob([JSON.stringify(links)], {
+ type: "application/json",
+ });
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = "slug-links.json";
+ a.click();
+ URL.revokeObjectURL(url);
+ toast.success("Links exported successfully.");
+ } catch (error) {
+ toast.error("Failed to download links.");
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default DownloadAllLinks;
diff --git a/src/components/links/edit-link.tsx b/src/components/links/edit-link.tsx
new file mode 100644
index 0000000..4f019dc
--- /dev/null
+++ b/src/components/links/edit-link.tsx
@@ -0,0 +1,213 @@
+"use client";
+
+import type { Links } from "@prisma/client";
+import { useState, type ReactNode } from "react";
+import type { z } from "zod";
+
+import { zodResolver } from "@hookform/resolvers/zod";
+import { useForm } from "react-hook-form";
+import { toast } from "sonner";
+
+import { updateLink } from "@/server/actions/links";
+
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/ui/dialog";
+import { Button } from "@/ui/button";
+import { LoaderIcon, LockIcon, LockOpenIcon, SaveIcon } from "lucide-react";
+import Alert from "@/ui/alert";
+import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/ui/form";
+import { Input, Textarea } from "@/ui/input";
+import { EditLinkSchema } from "@/server/schemas";
+import { Popover, PopoverContent, PopoverTrigger } from "@/ui/popover";
+
+interface EditLinkProps {
+ trigger: ReactNode;
+ link: Links;
+}
+
+const EditLink = (props: EditLinkProps) => {
+ const [loading, setLoading] = useState(false);
+ const [open, setOpen] = useState(false);
+ const [message, setMessage] = useState("");
+ const [isError, setError] = useState(false);
+ const [unlockSlug, setUnlockSlug] = useState(true);
+
+ // Main form:
+ const form = useForm>({
+ resolver: zodResolver(EditLinkSchema),
+ defaultValues: {
+ id: props.link.id,
+ url: props.link.url,
+ slug: props.link.slug,
+ description: props.link.description ?? "",
+ },
+ });
+
+ // Form Submit method:
+ const onSubmit = async (values: z.infer) => {
+ // Check if slug & url are equals to prevent infinite redirect =>
+ if (values.slug === values.url) {
+ setLoading(false);
+ setError(true);
+ setMessage("The URL and the slug cannot be the same");
+ return;
+ }
+
+ try {
+ setLoading(true);
+ await updateLink(values);
+ toast.success("Link edited successfully.", {
+ description: `Url: https://slug.vercel.app/${values.slug}`,
+ duration: 10000,
+ closeButton: true,
+ });
+ form.reset();
+ setOpen(false);
+ } catch (error) {
+ toast.error("An unexpected error has occurred. Please try again later.");
+ } finally {
+ setError(false);
+ setMessage("");
+ setLoading(false);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default EditLink;
diff --git a/src/components/links/links-limit.tsx b/src/components/links/links-limit.tsx
new file mode 100644
index 0000000..f75c3f8
--- /dev/null
+++ b/src/components/links/links-limit.tsx
@@ -0,0 +1,58 @@
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/ui/tooltip";
+import { cn } from "@/utils";
+import { PackageIcon, TriangleAlertIcon } from "lucide-react";
+
+interface LinksLimitProps {
+ userLinks: number;
+ maxLinks: number;
+}
+
+const LinksLimit = ({ userLinks, maxLinks }: LinksLimitProps) => {
+ const max = userLinks >= maxLinks;
+ const mid = userLinks >= maxLinks / 2;
+ return (
+
+
+
+
+
+ {max ? (
+
+ ) : (
+
+ )}
+
+ {userLinks < 10 ? `0${userLinks}` : userLinks}
+ {"/"}
+ {maxLinks < 10 ? `0${maxLinks}` : maxLinks}
+ {" links "}
+
+
+
+
+
+ {max ? (
+ You have reached the maximum limit of {maxLinks} links.
+ ) : (
+
+ You have created {userLinks} out of {maxLinks} links.
+
+ )}
+
+
+
+ );
+};
+
+export default LinksLimit;
diff --git a/src/components/links/search-link.tsx b/src/components/links/search-link.tsx
new file mode 100644
index 0000000..0af5f8d
--- /dev/null
+++ b/src/components/links/search-link.tsx
@@ -0,0 +1,49 @@
+"use client";
+
+import { Input } from "@/ui/input";
+import { cn } from "@/utils";
+import { SearchIcon } from "lucide-react";
+import { usePathname, useRouter, useSearchParams } from "next/navigation";
+import { useDebouncedCallback } from "use-debounce";
+
+interface SearchLinksProps {
+ className?: string;
+}
+
+const SearchLinks = (props: SearchLinksProps) => {
+ const searchParams = useSearchParams();
+ const pathname = usePathname();
+ const router = useRouter();
+
+ const handleSearch = useDebouncedCallback(
+ (e: React.ChangeEvent) => {
+ const params = new URLSearchParams(searchParams);
+ if (e.target.value) {
+ params.set("search", e.target.value);
+ } else {
+ params.delete("search");
+ }
+ router.replace(`${pathname}?${params.toString()}`);
+ },
+ 300,
+ );
+
+ return (
+
+
+
+
+ );
+};
+
+export default SearchLinks;
diff --git a/src/components/links/show-clicks-link.tsx b/src/components/links/show-clicks-link.tsx
new file mode 100644
index 0000000..cfa6a7c
--- /dev/null
+++ b/src/components/links/show-clicks-link.tsx
@@ -0,0 +1,46 @@
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/ui/tooltip";
+import { cn } from "@/utils";
+import { formatDate } from "@/utils/formatDate";
+import { BarChartIcon } from "lucide-react";
+
+interface ShowClicksProps {
+ numberOfClicks: number;
+ lastDate: Date | null;
+ className?: string;
+}
+
+const ShowClicks = ({
+ numberOfClicks,
+ lastDate,
+ className,
+}: ShowClicksProps) => {
+ return (
+
+
+
+
+ {numberOfClicks} clicks
+
+
+ {lastDate ? (
+ Last clicked: {formatDate(lastDate)}
+ ) : (
+ No clicks yet
+ )}
+
+
+
+ );
+};
+
+export default ShowClicks;
diff --git a/src/components/providers/theme-provider.tsx b/src/components/providers/theme-provider.tsx
new file mode 100644
index 0000000..7afe882
--- /dev/null
+++ b/src/components/providers/theme-provider.tsx
@@ -0,0 +1,9 @@
+"use client";
+
+import * as React from "react";
+import { ThemeProvider as NextThemesProvider } from "next-themes";
+import { type ThemeProviderProps } from "next-themes/dist/types";
+
+export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
+ return {children};
+}
\ No newline at end of file
diff --git a/src/components/providers/toaster.tsx b/src/components/providers/toaster.tsx
new file mode 100644
index 0000000..0f433d4
--- /dev/null
+++ b/src/components/providers/toaster.tsx
@@ -0,0 +1,25 @@
+"use client";
+
+import { useTheme } from "next-themes";
+import { Toaster } from "sonner";
+
+export const ToasterComponent = () => {
+ const { theme } = useTheme();
+ return (
+
+ );
+};
diff --git a/src/components/settings/card.tsx b/src/components/settings/card.tsx
new file mode 100644
index 0000000..11af624
--- /dev/null
+++ b/src/components/settings/card.tsx
@@ -0,0 +1,25 @@
+import { TypographyH4 } from "@/ui/typography";
+import type { ReactNode } from "react";
+
+interface SettingsCardProps {
+ title: string;
+ description: string;
+ children: ReactNode;
+ className?: string;
+}
+
+const SettingsCard = (props: SettingsCardProps) => {
+ return (
+
+
+
+ {props.title}
+
+
{props.description}
+
+ {props.children}
+
+ );
+};
+
+export default SettingsCard;
diff --git a/src/components/settings/delete-account.tsx b/src/components/settings/delete-account.tsx
new file mode 100644
index 0000000..05a87db
--- /dev/null
+++ b/src/components/settings/delete-account.tsx
@@ -0,0 +1,95 @@
+"use client";
+
+import { useState, type ReactNode } from "react";
+
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/ui/dialog";
+import { deleteProfile } from "@/server/actions/profile";
+import { toast } from "sonner";
+import { Input } from "@/ui/input";
+import { LoaderIcon } from "lucide-react";
+import { Button } from "@/ui/button";
+
+interface DeleteAccountProps {
+ trigger: ReactNode;
+ email: string;
+}
+
+const DeleteAccount = (props: DeleteAccountProps) => {
+ const [confirmEmail, setConfirmEmail] = useState("");
+ const [loading, setLoading] = useState(false);
+
+ const handleDeleteAccount = async (e: React.FormEvent) => {
+ e.preventDefault();
+ if (confirmEmail !== props.email) {
+ toast.error("Email does not match.");
+ return;
+ }
+ setLoading(true);
+ toast.promise(deleteProfile, {
+ loading: "Deleting account...",
+ description: "Your account is being deleted.",
+ success: () => {
+ setLoading(false);
+ return `Your account has been deleted.`;
+ },
+ error: "Failed to delete account. Please try again or contact us.",
+ });
+ };
+
+ return (
+
+ );
+};
+
+export default DeleteAccount;
diff --git a/src/components/settings/update-name-avatar.tsx b/src/components/settings/update-name-avatar.tsx
new file mode 100644
index 0000000..0e9b9ef
--- /dev/null
+++ b/src/components/settings/update-name-avatar.tsx
@@ -0,0 +1,111 @@
+"use client";
+
+import { useForm } from "react-hook-form";
+import SettingsCard from "./card";
+import { AlertTriangleIcon, LoaderIcon, SaveIcon } from "lucide-react";
+import type { z } from "zod";
+import { UpdateProfileSchema } from "@/server/schemas";
+import { zodResolver } from "@hookform/resolvers/zod";
+import {
+ Form,
+ FormControl,
+ FormDescription,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/ui/form";
+import { Input } from "@/ui/input";
+import { Button } from "@/ui/button";
+import { useState } from "react";
+import { updateProfile } from "@/server/actions/profile";
+import { toast } from "sonner";
+
+interface UpdateNameAvatarProps {
+ name: string;
+ username: string;
+ avatar: string;
+ email: string;
+}
+
+const UpdateNameAvatar = (props: UpdateNameAvatarProps) => {
+ const [loading, setLoading] = useState(false);
+
+ const hookForm = useForm>({
+ resolver: zodResolver(UpdateProfileSchema),
+ defaultValues: {
+ name: props.name,
+ username: props.username,
+ email: props.email,
+ },
+ });
+
+ const onSubmit = async (values: z.infer) => {
+ try {
+ setLoading(true);
+ await updateProfile(values);
+ toast.success("Profile updated successfully.");
+ } catch (error) {
+ toast.error("An unexpected error has occurred. Please try again later.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
+
+
+ );
+};
+
+export default UpdateNameAvatar;
diff --git a/src/env.mjs b/src/env.mjs
new file mode 100644
index 0000000..87ce132
--- /dev/null
+++ b/src/env.mjs
@@ -0,0 +1,38 @@
+import { createEnv } from "@t3-oss/env-nextjs";
+import { z } from "zod";
+
+export const env = createEnv({
+ server: {
+ DATABASE_URL: z
+ .string()
+ .refine(
+ (str) => !str.includes("YOUR_MYSQL_URL_HERE"),
+ "You forgot to change the default URL",
+ ),
+ TURSO_DATABASE_URL: z.string(),
+ TURSO_AUTH_TOKEN: z.string(),
+ NODE_ENV: z
+ .enum(["development", "test", "production"])
+ .default("development"),
+ AUTH_SECRET: z.string(),
+ //AUTH_URL: z.string(),
+ GITHUB_ID: z.string(),
+ GITHUB_CLIENT_SECRET: z.string(),
+ GOOGLE_ID: z.string(),
+ GOOGLE_CLIENT_SECRET: z.string(),
+ },
+ runtimeEnv: {
+ TURSO_DATABASE_URL: process.env.TURSO_DATABASE_URL,
+ TURSO_AUTH_TOKEN: process.env.TURSO_AUTH_TOKEN,
+ DATABASE_URL: process.env.DATABASE_URL,
+ NODE_ENV: process.env.NODE_ENV,
+ AUTH_SECRET: process.env.AUTH_SECRET,
+ // AUTH_URL: process.env.AUTH_URL,
+ GITHUB_ID: process.env.GITHUB_ID,
+ GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET,
+ GOOGLE_ID: process.env.GOOGLE_CLIENT_ID,
+ GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,
+ },
+ skipValidation: !!process.env.SKIP_ENV_VALIDATION,
+ emptyStringAsUndefined: true,
+});
diff --git a/src/env/client.mjs b/src/env/client.mjs
deleted file mode 100644
index ec0f257..0000000
--- a/src/env/client.mjs
+++ /dev/null
@@ -1,38 +0,0 @@
-// @ts-check
-import { clientEnv, clientSchema } from "./schema.mjs";
-
-const _clientEnv = clientSchema.safeParse(clientEnv);
-
-export const formatErrors = (
- /** @type {import('zod').ZodFormattedError