diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..bffb357
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "next/core-web-vitals"
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9c3a65b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,37 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+.env
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
+
+.vercel
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..306c9cd
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,6 @@
+{
+ "semi": false,
+ "singleQuote": true,
+ "trailingComma": "none",
+ "printWidth": 120
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..4f9adb3
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+ "workbench.colorCustomizations": {
+ "activityBar.background": "#2F2F07",
+ "titleBar.activeBackground": "#41420A",
+ "titleBar.activeForeground": "#FBFBE7"
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index fb46be5..60f6837 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,48 @@
-# LaLiga-FrontEnd
+# Para mi yo futuro o a quien le pueda servir
+### Este template está creado para empezar con unos mínimos que puede ahorrarme tiempo a la hora de iniciar un proyecto personal.
+`**No te enfoques en el estilo actual, intento hacerlo de lo mas neutral posible **`
-La Liga Front End Repo
\ No newline at end of file
+This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Para empezar, aunque no hace falta ni decirlo, pero bueno por si acaso.
+
+First, run the development server: `(y a darle sin miedo)`
+
+```bash
+npm run dev
+# or
+yarn dev
+# or
+pnpm dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+# ¿Que me voy a encontrar?
+Cuando abras el proyecto, tendras un layout, con su navbar y su footer con un children para que puedas meter todo lo que quieras.
+```js
+
+```
+Entre otras cosas, que me parecen interesantes para tener ya preparadas, como es un `cambio de lenguaje`, tiene instalado **i18next**, configurado con `Inglés y español`, con la libertad para añadir los idiomas necesarios, las carpetas de locales, donde ya se irán ***`¡Ojo!`*** creando automáticamente los archivos json de las traducciones.
+
+===> Si dudas y no la conoces [i18next](https://www.i18next.com/) <==
+### Navbar responsivo
+Con su boton hamburguesa, y sus iconos, para cerrar y desplegar menu.
+
+### Componentes de ejemplos
+Para llegar y desembarcar. Modificarlo al gusto y listo.
+
+# Librerías que he instalado.
+`Libertad para borrar la que no se quiera `
+- **i18next** => Ya dicho anteriormente, para las traducciones de idioma.
+- **react-iconst** => Iconos. Ya hay alguno en el navbar.
+- **react-loading** => Para animaciones, está ya en un componente que tiene de todo, y una de las opciones usa esta librería.
+- **sass** => Ni falta hace que decirlo, pero ahí esta para darle alegría a mi estilo con tailwindcss.
+- **TailwindCSS** => Otro tanto, la clave para volar con los estilos.
+- **Typescript** => Bendiciones para tener controlado todo.
+
+Y poco más. Con esto empezar será más fácil.
\ No newline at end of file
diff --git a/next-i18next.config.js b/next-i18next.config.js
new file mode 100644
index 0000000..20bef52
--- /dev/null
+++ b/next-i18next.config.js
@@ -0,0 +1,9 @@
+/** @type {import('next-i18next').UserConfig} */
+module.exports = {
+ i18n: {
+ defaultLocale: 'es',
+ locales: ['es', 'en']
+ },
+ serializeConfig: false,
+ saveMissing: true
+}
diff --git a/next.config.js b/next.config.js
new file mode 100644
index 0000000..dad4478
--- /dev/null
+++ b/next.config.js
@@ -0,0 +1,15 @@
+/** @type {import('next').NextConfig} */
+const { i18n } = require('./next-i18next.config')
+
+const nextConfig = {
+ reactStrictMode: false,
+ i18n: {
+ defaultLocale: 'es',
+ locales: ['es', 'en']
+ },
+ images: {
+ domains: ['lh3.googleusercontent.com', 'avatars.githubusercontent.com']
+ }
+}
+
+module.exports = nextConfig
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..eed2c4f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "next-tailwind-boilerplate",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint"
+
+ },
+ "dependencies": {
+ "@auth/prisma-adapter": "^1.0.12",
+ "@headlessui/react": "^1.7.18",
+ "@hookform/resolvers": "^3.3.3",
+ "@prisma/client": "^5.8.1",
+ "@types/node": "20.4.1",
+ "@types/react": "18.2.14",
+ "@types/react-dom": "18.2.6",
+ "autoprefixer": "10.4.14",
+ "eslint": "8.44.0",
+ "eslint-config-next": "13.4.9",
+ "i18next": "^23.2.10",
+ "next": "13.4.9",
+ "next-auth": "^4.24.5",
+ "next-i18next": "^14.0.0",
+ "postcss": "8.4.25",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-hook-form": "^7.49.2",
+ "react-i18next": "^13.0.2",
+ "react-icons": "^4.11.0",
+ "react-loading": "^2.0.3",
+ "sass": "^1.63.6",
+ "swr": "^2.2.4",
+ "tailwindcss": "3.3.2",
+ "typescript": "5.1.6",
+ "yup": "^1.3.3"
+ },
+ "devDependencies": {
+ "prisma": "^5.8.1"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..33ad091
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/prisma/comment.ts b/prisma/comment.ts
new file mode 100644
index 0000000..cddc2f4
--- /dev/null
+++ b/prisma/comment.ts
@@ -0,0 +1,42 @@
+import { PrismaClient } from '@prisma/client'
+const prisma = new PrismaClient()
+
+export const getAllComments = async (postSlug?: string) => {
+ try {
+ const comments = await prisma.comment.findMany({
+ orderBy: [{ createdAt: 'desc' }],
+ where: {
+ ...(postSlug && { postSlug: postSlug })
+ },
+ include: { user: true }
+ })
+ return comments
+ } catch (error) {
+ console.error('Error fetching comments:', error)
+ throw new Error('Error fetching comments')
+ }
+}
+
+export const createComment = async (body: any, userEmail: any, session: any) => {
+ if (!session) {
+ throw new Error('Not Authenticated')
+ }
+
+ try {
+ const comment = await prisma.comment.create({
+ data: { description: body.description, postSlug: body.postSlug, userEmail: userEmail }
+ })
+ return comment
+ } catch (error) {
+ console.error('Error creating comment:', error)
+ throw new Error('Error creating comment')
+ }
+}
+
+export const deleteComment = async (id: string) => {
+ await prisma.comment.delete({
+ where: {
+ id: id
+ }
+ })
+}
diff --git a/prisma/favorite.ts b/prisma/favorite.ts
new file mode 100644
index 0000000..a9ed72c
--- /dev/null
+++ b/prisma/favorite.ts
@@ -0,0 +1,59 @@
+import { PrismaClient } from '@prisma/client'
+const prisma = new PrismaClient()
+
+export const addFavorite = async (postId: any, userEmail: any, session: any) => {
+ try {
+ if (!session) {
+ throw new Error('Not Authenticated')
+ }
+ const existingFavorite = await prisma.favorite.findUnique({
+ where: { postId_userEmail: { postId, userEmail } }
+ })
+ if (existingFavorite) {
+ throw new Error('El usuario ya marcó este post como favorito.')
+ }
+ await prisma.favorite.create({
+ data: {
+ postId,
+ userEmail
+ }
+ })
+ const updatedFavorites = await prisma.post
+ .findUnique({
+ where: { id: postId }
+ })
+ .Favorite()
+
+ return updatedFavorites
+ } catch (error) {
+ console.error('Error al añadir a favoritos:', error)
+ throw new Error('Error al añadir a favoritos')
+ }
+}
+
+export const deleteFavorite = async (postId: any, userEmail: string, session: any) => {
+ try {
+ // Verificar si el usuario ha marcado el post como favorito
+ const existingFavorite = await prisma.favorite.findUnique({
+ where: { postId_userEmail: { postId, userEmail } }
+ })
+ if (!existingFavorite) {
+ throw new Error('El usuario no ha marcado este post como favorito.')
+ }
+ // Eliminar de favoritos
+ await prisma.favorite.delete({
+ where: { postId_userEmail: { postId, userEmail } }
+ })
+
+ const updatedFavorites = await prisma.post
+ .findUnique({
+ where: { id: postId }
+ })
+ .Favorite()
+
+ return updatedFavorites
+ } catch (error) {
+ console.error('Error al quitar de favoritos:', error)
+ throw new Error('Error al quitar de favoritos')
+ }
+}
diff --git a/prisma/like.ts b/prisma/like.ts
new file mode 100644
index 0000000..28c701a
--- /dev/null
+++ b/prisma/like.ts
@@ -0,0 +1,59 @@
+import { PrismaClient } from '@prisma/client'
+const prisma = new PrismaClient()
+
+export const addLike = async (postId: any, userEmail: any, session: any) => {
+ try {
+ if (!session) {
+ throw new Error('Not Authenticated')
+ }
+ const existingLike = await prisma.like.findUnique({
+ where: { postId_userEmail: { postId, userEmail } }
+ })
+ if (existingLike) {
+ throw new Error('El usuario ya dio like a este post.')
+ }
+ await prisma.like.create({
+ data: {
+ postId,
+ userEmail
+ }
+ })
+ const updatedLikes = await prisma.post
+ .findUnique({
+ where: { id: postId }
+ })
+ .Like()
+
+ return updatedLikes
+ } catch (error) {
+ console.error('Error al añadir el like:', error)
+ throw new Error('Error al añadir el like')
+ }
+}
+
+export const deleteLike = async (postId: any, userEmail: string, session: any) => {
+ try {
+ // Verificar si el usuario ha dado like al post
+ const existingLike = await prisma.like.findUnique({
+ where: { postId_userEmail: { postId, userEmail } }
+ })
+ if (!existingLike) {
+ throw new Error('El usuario no ha dado like a este post.')
+ }
+ // Eliminar el like
+ await prisma.like.delete({
+ where: { postId_userEmail: { postId, userEmail } }
+ })
+
+ const updatedLikes = await prisma.post
+ .findUnique({
+ where: { id: postId }
+ })
+ .Like()
+
+ return updatedLikes
+ } catch (error) {
+ console.error('Error al quitar el like:', error)
+ throw new Error('Error al quitar el like')
+ }
+}
diff --git a/prisma/post.ts b/prisma/post.ts
new file mode 100644
index 0000000..449bc04
--- /dev/null
+++ b/prisma/post.ts
@@ -0,0 +1,68 @@
+import { PrismaClient } from '@prisma/client'
+const prisma = new PrismaClient()
+
+export const deletePost = async (slug: string) => {
+ try {
+ const post = await prisma.post.findUnique({
+ where: {
+ slug: slug
+ },
+ include: {
+ comments: true
+ }
+ })
+ if (!post) {
+ throw new Error('Post not found')
+ }
+ await prisma.like.deleteMany({
+ where: {
+ postId: post.id
+ }
+ })
+ await prisma.comment.deleteMany({
+ where: {
+ postSlug: slug
+ }
+ })
+ await prisma.post.delete({
+ where: {
+ slug: slug
+ }
+ })
+ } catch (error) {
+ console.error(error, 'Error deleting post')
+ throw new Error('Error deleting post')
+ }
+}
+
+export const editPost = async (slug: string, newData: any) => {
+ try {
+ // Buscar el post que se va a editar
+ const existingPost = await prisma.post.findUnique({
+ where: {
+ slug: slug
+ }
+ })
+ // Verificar si el post existe
+ if (!existingPost) {
+ throw new Error('Post not found')
+ }
+ // Actualizar el post con los nuevos datos
+ const updatedPost = await prisma.post.update({
+ where: {
+ slug: slug
+ },
+ data: {
+ ...newData
+ // Tags: {
+ // set: newData.Tags.map((tag: any) => ({ id: tag.id }))
+ // }
+ }
+ })
+
+ return updatedPost
+ } catch (error) {
+ console.error(error, 'Error editing post')
+ throw new Error('Error editing post')
+ }
+}
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
new file mode 100644
index 0000000..2d1e268
--- /dev/null
+++ b/prisma/schema.prisma
@@ -0,0 +1,156 @@
+// This is your Prisma schema file,
+// learn more about it in the docs: https://pris.ly/d/prisma-schema
+
+generator client {
+ provider = "prisma-client-js"
+}
+
+datasource db {
+ provider = "mongodb"
+ url = env("MONGODB_URI")
+}
+
+// datasource db {
+// provider = "mongodb"
+// url = env("DATABASE_URL")
+// }
+
+model Account {
+ id String @id @default(cuid()) @map("_id")
+ userId String
+ type String
+ provider String
+ providerAccountId String
+ refresh_token String?
+ access_token String?
+ expires_at Int?
+ token_type String?
+ scope String?
+ id_token String?
+ session_state String?
+
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+
+ @@unique([provider, providerAccountId])
+}
+
+model Session {
+ id String @id @default(cuid()) @map("_id")
+ sessionToken String @unique
+ userId String
+ expires DateTime
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+}
+
+model User {
+ id String @id @default(cuid()) @map("_id")
+ name String?
+ email String @unique
+ emailVerified DateTime?
+ image String?
+ isAdmin Boolean @unique @default(false)
+ accounts Account[]
+ sessions Session[]
+ Post Post[]
+ Like Like[]
+ Comment Comment[]
+ Favorite Favorite[]
+}
+
+model VerificationToken {
+ identifier String @id @map("_id")
+ token String @unique
+ expires DateTime
+
+ @@unique([identifier, token])
+}
+
+model Category {
+ id String @id @default(cuid()) @map("_id")
+ slug String @unique
+ title String
+ img String?
+ color String?
+ Posts Post[]
+ Comment Comment[]
+}
+
+// model Tag {
+// id String @id @default(cuid()) @map("_id")
+// name String @unique
+// slug String @unique
+// color String?
+// // Posts PostTag[]
+// Post Post? @relation(fields: [postId], references: [id])
+// postId String?
+// }
+
+// model PostTag {
+// id String @id @default(cuid()) @map("_id")
+// postId String
+// tagId String
+// post Post @relation(fields: [postId], references: [id])
+// tag Tag @relation(fields: [tagId], references: [id])
+
+// @@unique([postId, tagId])
+// }
+
+model Post {
+ id String @id @default(cuid()) @map("_id")
+ slug String @unique
+ title String
+ description String
+ img String?
+ views Int @default(0)
+ catSlug String?
+ Category Category? @relation(fields: [catSlug], references: [slug])
+ userEmail String
+ user User @relation(fields: [userEmail], references: [email], onDelete: Cascade)
+ Like Like[]
+ comments Comment[]
+ url String?
+ twitterShareCount Int @default(0)
+ whatsappShareCount Int @default(0)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ Favorite Favorite[]
+ // PostTag PostTag[]
+ // Tags Tag[]
+}
+
+model Like {
+ id String @id @default(cuid()) @map("_id")
+ postId String
+ post Post @relation(fields: [postId], references: [id])
+ userEmail String
+ user User @relation(fields: [userEmail], references: [email], onDelete: Cascade)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ @@unique([postId, userEmail])
+}
+
+model Favorite {
+ id String @id @default(cuid()) @map("_id")
+ postId String
+ post Post @relation(fields: [postId], references: [id])
+ userEmail String
+ user User @relation(fields: [userEmail], references: [email], onDelete: Cascade)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ @@unique([postId, userEmail])
+}
+
+model Comment {
+ id String @id @default(cuid()) @map("_id")
+ createdAt DateTime @default(now())
+ description String
+ userEmail String
+ user User @relation(fields: [userEmail], references: [email], onDelete: Cascade)
+ postSlug String
+ post Post @relation(fields: [postSlug], references: [slug])
+
+ Category Category? @relation(fields: [categoryId], references: [id])
+ categoryId String?
+}
diff --git a/prisma/stats.ts b/prisma/stats.ts
new file mode 100644
index 0000000..c7fdc41
--- /dev/null
+++ b/prisma/stats.ts
@@ -0,0 +1,25 @@
+import { PrismaClient } from '@prisma/client'
+const prisma = new PrismaClient()
+
+export const getAllStats = async () => {
+ try {
+ const totalPosts = await prisma.post.count()
+ const totalUsers = await prisma.user.count()
+ const totalViews = await prisma.post.aggregate({ _sum: { views: true } })
+ const totalShares = await prisma.post.aggregate({
+ _sum: { twitterShareCount: true, whatsappShareCount: true }
+ })
+
+ return {
+ totalPosts,
+ totalUsers,
+ totalViews: totalViews._sum || 0,
+ totalShares: totalShares._sum || 0
+ }
+ } catch (error) {
+ console.error('Error fetching statistics:', error)
+ throw new Error('Error fetching statistics')
+ } finally {
+ await prisma.$disconnect()
+ }
+}
diff --git a/prisma/tag.ts b/prisma/tag.ts
new file mode 100644
index 0000000..eb69423
--- /dev/null
+++ b/prisma/tag.ts
@@ -0,0 +1,82 @@
+// import { PrismaClient } from '@prisma/client'
+// const prisma = new PrismaClient()
+
+// //CREAR NUEVO TAG
+
+// export const createTag = async (tagData: { name: string; slug: string; color?: string }) => {
+// try {
+// const normalizedTagSlug = tagData.slug.toLowerCase()
+// const existingTagMinus = await prisma.tag.findUnique({
+// where: { slug: normalizedTagSlug }
+// })
+
+// if (existingTagMinus) {
+// console.error(`Error al crear el Tag: El SLUG "${tagData.slug}" ya está en uso.`)
+// throw new Error(`Error al crear el Tag: El SLUG "${tagData.slug}" ya está en uso.`)
+// }
+
+// const newTag = await prisma.tag.create({
+// data: { ...tagData, slug: normalizedTagSlug }
+// })
+
+// return newTag
+// } catch (error) {
+// console.error('Error al crear el Tag:', error)
+// throw new Error('Error al crear el Tag')
+// }
+// }
+
+// // OBTENER TODOS LOS TAGS
+
+// export const getAllTags = async () => {
+// try {
+// const tags = await prisma.tag.findMany()
+// return tags
+// } catch (error) {
+// console.error('Error al obtener todos los Tags:', error)
+// throw new Error('Error al obtener todos los Tags')
+// }
+// }
+
+// // OBTENER UN TAG POR SU ID
+
+// export const getTagById = async (tagId: string) => {
+// try {
+// const tag = await prisma.tag.findUnique({
+// where: { id: tagId }
+// })
+// return tag
+// } catch (error) {
+// console.error('Error al obtener el Tag por ID:', error)
+// throw new Error('Error al obtener el Tag por ID')
+// }
+// }
+
+// //ACTUALIZAR UN TAG
+
+// export const updateTag = async (tagData: { id: string; name?: string; slug?: string; color?: string }) => {
+// try {
+// const updatedTag = await prisma.tag.update({
+// where: { id: tagData.id },
+// data: { name: tagData.name, slug: tagData.slug, color: tagData.color }
+// })
+// return updatedTag
+// } catch (error) {
+// console.error('Error al actualizar el Tag:', error)
+// throw new Error('Error al actualizar el Tag')
+// }
+// }
+
+// // ELIMINAR UN TAG
+
+// export const deleteTag = async (tagId: string) => {
+// try {
+// const deletedTag = await prisma.tag.delete({
+// where: { id: tagId }
+// })
+// return deletedTag
+// } catch (error) {
+// console.error('Error al eliminar el Tag:', error)
+// throw new Error('Error al eliminar el Tag')
+// }
+// }
diff --git a/prisma/user.ts b/prisma/user.ts
new file mode 100644
index 0000000..b504f7f
--- /dev/null
+++ b/prisma/user.ts
@@ -0,0 +1,93 @@
+import { PrismaClient } from '@prisma/client'
+const prisma = new PrismaClient()
+
+export const getAllUsers = async () => {
+ try {
+ const users = await prisma.user.findMany()
+ return users
+ } catch (error) {
+ console.error('Error fetching users:', error)
+ throw new Error('Error fetching users')
+ }
+}
+export const getUserByEmail = async (email: string) => {
+ try {
+ const user = await prisma.user.findUnique({
+ where: {
+ email: email
+ },
+ include: {
+ Like: true,
+ Favorite: true
+ }
+ })
+ return user
+ } catch (error) {
+ console.error('Error fetching user by ID:', error)
+ throw new Error('Error fetching user by ID')
+ }
+}
+
+export const deleteUserByEmail = async (email: string) => {
+ try {
+ const userDeleted = await prisma.user.delete({
+ where: {
+ email: email
+ },
+ include: {
+ Like: true,
+ Comment: true,
+ sessions: true,
+ accounts: true
+ }
+ })
+
+ return userDeleted
+ } catch (error) {
+ console.error(`Error deleting user with email ${email}:`, error)
+ throw new Error(`Unable to delete user with email ${email}`)
+ }
+}
+
+export const updateUserByEmail = async (email: string, newData: any) => {
+ try {
+ const { name } = newData
+ if (name) {
+ const existingUserWithSameName = await prisma.user.findFirst({
+ where: {
+ name: name,
+ email: { not: email }
+ }
+ })
+
+ if (existingUserWithSameName) {
+ return { success: false, status: 409, error: `Name ${name} is already in use by another user` }
+ }
+ }
+ // Verificar si el usuario existe
+ const existingUser = await prisma.user.findUnique({
+ where: {
+ email: email
+ }
+ })
+
+ if (!existingUser) {
+ return { status: 404, error: `User with email ${email} not found` }
+ }
+
+ // Actualizar el usuario con los nuevos datos
+ const updatedUser = await prisma.user.update({
+ where: {
+ email: email
+ },
+ data: newData
+ })
+
+ return updatedUser
+ } catch (error) {
+ console.error(`Error updating user with email ${email}:`, error)
+ return { status: 500, error: `Unable to update user with email ${email}` }
+ } finally {
+ await prisma.$disconnect()
+ }
+}
diff --git a/public/images/IconWhatsapp.svg b/public/images/IconWhatsapp.svg
new file mode 100644
index 0000000..bcb34c0
--- /dev/null
+++ b/public/images/IconWhatsapp.svg
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/React.png b/public/images/React.png
new file mode 100644
index 0000000..e9ef2ad
Binary files /dev/null and b/public/images/React.png differ
diff --git a/public/images/alert.svg b/public/images/alert.svg
new file mode 100644
index 0000000..8e00850
--- /dev/null
+++ b/public/images/alert.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/avatar-hombre.svg b/public/images/avatar-hombre.svg
new file mode 100644
index 0000000..f5a8db1
--- /dev/null
+++ b/public/images/avatar-hombre.svg
@@ -0,0 +1,2 @@
+
+Artboards_Diversity_Avatars_by_Netguru
\ No newline at end of file
diff --git a/public/images/avatar-mujer.svg b/public/images/avatar-mujer.svg
new file mode 100644
index 0000000..30f4afe
--- /dev/null
+++ b/public/images/avatar-mujer.svg
@@ -0,0 +1,2 @@
+
+Artboards_Diversity_Avatars_by_Netguru
\ No newline at end of file
diff --git a/public/images/back.svg b/public/images/back.svg
new file mode 100644
index 0000000..f429c02
--- /dev/null
+++ b/public/images/back.svg
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/backRoute.svg b/public/images/backRoute.svg
new file mode 100644
index 0000000..c5a0f19
--- /dev/null
+++ b/public/images/backRoute.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/css.png b/public/images/css.png
new file mode 100644
index 0000000..90bdbde
Binary files /dev/null and b/public/images/css.png differ
diff --git a/public/images/css.svg b/public/images/css.svg
new file mode 100644
index 0000000..79c47a9
--- /dev/null
+++ b/public/images/css.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/images/cursos.svg b/public/images/cursos.svg
new file mode 100644
index 0000000..28d9e11
--- /dev/null
+++ b/public/images/cursos.svg
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/devWorldResources-removebg.png b/public/images/devWorldResources-removebg.png
new file mode 100644
index 0000000..4c5e191
Binary files /dev/null and b/public/images/devWorldResources-removebg.png differ
diff --git a/public/images/devWorldResources-removebg.svg b/public/images/devWorldResources-removebg.svg
new file mode 100644
index 0000000..1580460
--- /dev/null
+++ b/public/images/devWorldResources-removebg.svg
@@ -0,0 +1,1492 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/devWorldResources.jpeg b/public/images/devWorldResources.jpeg
new file mode 100644
index 0000000..ef17cd6
Binary files /dev/null and b/public/images/devWorldResources.jpeg differ
diff --git a/public/images/error.svg b/public/images/error.svg
new file mode 100644
index 0000000..609e669
--- /dev/null
+++ b/public/images/error.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/front.svg b/public/images/front.svg
new file mode 100644
index 0000000..30302a4
--- /dev/null
+++ b/public/images/front.svg
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/github.svg b/public/images/github.svg
new file mode 100644
index 0000000..2dfec51
--- /dev/null
+++ b/public/images/github.svg
@@ -0,0 +1,19 @@
+
+
+
+
+ github [#142]
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/herramientas.svg b/public/images/herramientas.svg
new file mode 100644
index 0000000..2183e72
--- /dev/null
+++ b/public/images/herramientas.svg
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/iconDevWorld.jpeg b/public/images/iconDevWorld.jpeg
new file mode 100644
index 0000000..c3a6162
Binary files /dev/null and b/public/images/iconDevWorld.jpeg differ
diff --git a/public/images/javascript.svg b/public/images/javascript.svg
new file mode 100644
index 0000000..58b9768
--- /dev/null
+++ b/public/images/javascript.svg
@@ -0,0 +1,19 @@
+
+
+
+
+ javascript [#155]
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/javascript1.svg b/public/images/javascript1.svg
new file mode 100644
index 0000000..1f203d3
--- /dev/null
+++ b/public/images/javascript1.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/images/library.png b/public/images/library.png
new file mode 100644
index 0000000..20b2320
Binary files /dev/null and b/public/images/library.png differ
diff --git a/public/images/library.svg b/public/images/library.svg
new file mode 100644
index 0000000..dc01194
--- /dev/null
+++ b/public/images/library.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/linkedin.svg b/public/images/linkedin.svg
new file mode 100644
index 0000000..0b3291e
--- /dev/null
+++ b/public/images/linkedin.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/manuelcebreiro.jpg b/public/images/manuelcebreiro.jpg
new file mode 100644
index 0000000..fc233bd
Binary files /dev/null and b/public/images/manuelcebreiro.jpg differ
diff --git a/public/images/react.svg b/public/images/react.svg
new file mode 100644
index 0000000..9a25a8c
--- /dev/null
+++ b/public/images/react.svg
@@ -0,0 +1,21 @@
+
+
+
+
+ frameworks-and-libraries/react
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/share.svg b/public/images/share.svg
new file mode 100644
index 0000000..e9dea33
--- /dev/null
+++ b/public/images/share.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/shared1.svg b/public/images/shared1.svg
new file mode 100644
index 0000000..480a68a
--- /dev/null
+++ b/public/images/shared1.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/tutorials.png b/public/images/tutorials.png
new file mode 100644
index 0000000..bb04b03
Binary files /dev/null and b/public/images/tutorials.png differ
diff --git a/public/images/tutorials.svg b/public/images/tutorials.svg
new file mode 100644
index 0000000..b708827
--- /dev/null
+++ b/public/images/tutorials.svg
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/typescript.png b/public/images/typescript.png
new file mode 100644
index 0000000..a855ee8
Binary files /dev/null and b/public/images/typescript.png differ
diff --git a/public/images/typescript.svg b/public/images/typescript.svg
new file mode 100644
index 0000000..d1a483e
--- /dev/null
+++ b/public/images/typescript.svg
@@ -0,0 +1,29 @@
+
+
+
+
+ build-tools/typescript
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/userIcon.svg b/public/images/userIcon.svg
new file mode 100644
index 0000000..802a58c
--- /dev/null
+++ b/public/images/userIcon.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/videotutos.svg b/public/images/videotutos.svg
new file mode 100644
index 0000000..2f5750e
--- /dev/null
+++ b/public/images/videotutos.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/images/xSocial.svg b/public/images/xSocial.svg
new file mode 100644
index 0000000..b144d78
--- /dev/null
+++ b/public/images/xSocial.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
new file mode 100644
index 0000000..19775b3
--- /dev/null
+++ b/public/locales/en/common.json
@@ -0,0 +1,7 @@
+{
+ "TodoTest": "Doing Tests",
+ "HomePage": "Home",
+ "contact": "Contact",
+ "about": "About",
+ "login": "Login"
+}
\ No newline at end of file
diff --git a/public/locales/es/common.json b/public/locales/es/common.json
new file mode 100644
index 0000000..36bb374
--- /dev/null
+++ b/public/locales/es/common.json
@@ -0,0 +1,7 @@
+{
+ "TodoTest": "Haciendo pruebas",
+ "HomePage": "Página principal",
+ "contact": "Contacto",
+ "about": "Acerca de la página",
+ "login": "Identificarse"
+}
\ No newline at end of file
diff --git a/public/locales/es/common.missing.json b/public/locales/es/common.missing.json
new file mode 100644
index 0000000..812be4c
--- /dev/null
+++ b/public/locales/es/common.missing.json
@@ -0,0 +1,6 @@
+{
+ "HomePage": "HomePage",
+ "contact": "contact",
+ "about": "about",
+ "login": "login"
+}
\ No newline at end of file
diff --git a/src/api/auth/[...nextauth]/route.js b/src/api/auth/[...nextauth]/route.js
new file mode 100644
index 0000000..285256e
--- /dev/null
+++ b/src/api/auth/[...nextauth]/route.js
@@ -0,0 +1,4 @@
+// import NextAuth from 'next-auth'
+// import { authOptions } from '../../../utils/auth'
+
+// export default NextAuth(authOptions)
diff --git a/src/api/hello.ts b/src/api/hello.ts
new file mode 100644
index 0000000..f8bcc7e
--- /dev/null
+++ b/src/api/hello.ts
@@ -0,0 +1,13 @@
+// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
+import type { NextApiRequest, NextApiResponse } from 'next'
+
+type Data = {
+ name: string
+}
+
+export default function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ res.status(200).json({ name: 'John Doe' })
+}
diff --git a/src/components/atoms/AutoCompleteInput.tsx b/src/components/atoms/AutoCompleteInput.tsx
new file mode 100644
index 0000000..e425352
--- /dev/null
+++ b/src/components/atoms/AutoCompleteInput.tsx
@@ -0,0 +1,75 @@
+import { useRouter } from 'next/router'
+import { useState } from 'react'
+import { FaSearch } from 'react-icons/fa'
+import { Post } from '../../../type'
+
+const AutoCompleteInput = ({
+ textSearched,
+ setTextSearched,
+ posts
+}: {
+ textSearched: string
+ setTextSearched: (text: string) => void
+ posts: Post[]
+}) => {
+ const [showPosts, setShowPosts] = useState(false)
+ const router = useRouter()
+ const filteredPosts = posts.filter((post) => {
+ const searchText = textSearched.toLowerCase()
+ const postTitle = post.title.toLowerCase()
+ const searchWords = searchText.split(' ')
+
+ return searchWords.every((word) => postTitle.includes(word))
+ })
+ const handleInputChange = (e: React.ChangeEvent) => {
+ setTextSearched(e.target.value)
+ setShowPosts(!!e.target.value)
+ }
+ const highlightMatches = (text: string) => {
+ const searchText = textSearched.toLowerCase()
+ const regex = new RegExp(`(${searchText})`, 'gi')
+ return text.replace(regex, '$1 ')
+ }
+ const handlePostClick = (slug: string) => {
+ router.push(`/post/${slug}`)
+ setShowPosts(false)
+ }
+ const noResults = showPosts && filteredPosts.length === 0
+
+ return (
+
+
+
+
+
+
+
+ {noResults && (
+
+ No hay coincidencias.
+
+ )}
+ {showPosts && (
+
+ {filteredPosts.map((post) => (
+
handlePostClick(post.slug)}
+ >
+
+
+ ))}
+
+ )}
+
+ )
+}
+
+export default AutoCompleteInput
diff --git a/src/components/atoms/Button.tsx b/src/components/atoms/Button.tsx
new file mode 100644
index 0000000..5f49988
--- /dev/null
+++ b/src/components/atoms/Button.tsx
@@ -0,0 +1,26 @@
+import ReactLoading from 'react-loading'
+
+type ButtonProps = {
+ children: React.ReactNode
+ className?: string
+ buttonClassName?: string
+ icon?: React.ReactNode
+ loading?: boolean
+ [others: string]: any
+}
+
+export const Button = ({ children, className, icon, loading, buttonClassName, ...others }: ButtonProps) => {
+ return (
+
+ {loading && (
+
+
+
+ )}
+
+ {children}
+ {icon && {icon} }
+
+
+ )
+}
diff --git a/src/components/atoms/DisclosureIndividual.tsx b/src/components/atoms/DisclosureIndividual.tsx
new file mode 100644
index 0000000..a66db01
--- /dev/null
+++ b/src/components/atoms/DisclosureIndividual.tsx
@@ -0,0 +1,34 @@
+import { Disclosure } from '@headlessui/react'
+import { IoIosArrowForward } from 'react-icons/io'
+
+export default function DisclosureIndividual({
+ classNameArrow,
+ className,
+ text,
+ children
+}: {
+ classNameArrow?: string
+ className?: string
+ text?: string
+ children: React.ReactNode
+}) {
+ return (
+
+
+
+ {({ open }) => (
+ <>
+
+ {text}
+
+
+ {children}
+ >
+ )}
+
+
+
+ )
+}
diff --git a/src/components/atoms/DropDownShare.tsx b/src/components/atoms/DropDownShare.tsx
new file mode 100644
index 0000000..854419c
--- /dev/null
+++ b/src/components/atoms/DropDownShare.tsx
@@ -0,0 +1,131 @@
+import { Menu, Transition } from '@headlessui/react'
+import Image from 'next/image'
+import { Fragment, useEffect, useState } from 'react'
+import ShareWhatsapp from '../../../public/images/IconWhatsapp.svg'
+import Share from '../../../public/images/shared1.svg'
+import ShareTwitter from '../../../public/images/xSocial.svg'
+
+export const DropDownShare = ({
+ slug,
+ id,
+ counTwitter,
+ countWhatsapp
+}: {
+ slug?: string
+ id: string
+ counTwitter?: number
+ countWhatsapp?: number
+}) => {
+ const [textShare, setTextShare] = useState('')
+ useEffect(() => {
+ if (slug) {
+ setTextShare(
+ 'Tienes que ver este recurso, ' +
+ location.href +
+ 'post/' +
+ slug +
+ ' lo he encontrado aquí, pásate hay más ' +
+ location.origin
+ )
+ } else {
+ setTextShare(
+ 'Tienes que ver este recurso, ' + location.href + ' lo he encontrado aquí, pásate hay más ' + location.origin
+ )
+ }
+ }, [])
+
+ {
+ /*
+
+
*/
+ }
+ const sharePost = async (postId, platform) => {
+ try {
+ const response = await fetch('/api/share', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ postId, platform })
+ })
+
+ if (response.ok) {
+ const data = await response.json()
+ // Actualiza la interfaz de usuario según sea necesario
+ } else {
+ console.error('Error sharing post:', response.statusText)
+ }
+ } catch (error) {
+ console.error('Error sharing post:', error.message)
+ }
+ }
+
+ return (
+
+ <>
+
+ {/* */}
+ {/* */}
+
+ {/*
*/}
+
+
+
+
+
+ {({ active }) => (
+ {
+ sharePost(id, 'twitter')
+ }}
+ >
+
+
+ Twitter
+
+ {counTwitter}
+
+ )}
+
+
+ {({ active }) => (
+ {
+ sharePost(id, 'whatsapp')
+ }}
+ >
+
+
+ Whatsapp
+
+ {countWhatsapp}
+
+ )}
+
+
+
+
+ >
+
+ )
+}
diff --git a/src/components/atoms/Modal.tsx b/src/components/atoms/Modal.tsx
new file mode 100644
index 0000000..f718064
--- /dev/null
+++ b/src/components/atoms/Modal.tsx
@@ -0,0 +1,70 @@
+import { Dialog } from '@headlessui/react'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import AlertIcon from '../../../public/images/alert.svg'
+
+const Modal = ({
+ setIsOpen,
+ isOpen,
+ icon,
+ tittle,
+ description,
+ textTrue,
+ textFalse = 'Cancelar',
+ functionTrue,
+ functionFalse
+}: {
+ isOpen: boolean
+ setIsOpen: (value: boolean) => void
+ icon: boolean
+ tittle: string
+ description: string
+ textTrue: string
+ textFalse?: string
+ functionTrue: () => void
+ functionFalse: () => void
+}) => {
+ const router = useRouter()
+ return (
+ setIsOpen(false)}
+ className="fixed inset-0 flex items-center justify-center z-50"
+ >
+
+ {icon && (
+
+
+
+ )}
+ {tittle}
+
+
{description}
+
+ {
+ // router.back()
+ setIsOpen(false)
+ functionFalse()
+ }}
+ >
+ {textFalse}
+
+ {
+ setIsOpen(false)
+ functionTrue()
+ }}
+ >
+ {textTrue}
+
+
+
+
+
+ )
+}
+
+export default Modal
diff --git a/src/components/atoms/ModalCreateTag.tsx b/src/components/atoms/ModalCreateTag.tsx
new file mode 100644
index 0000000..3871f14
--- /dev/null
+++ b/src/components/atoms/ModalCreateTag.tsx
@@ -0,0 +1,138 @@
+import { Dialog } from '@headlessui/react'
+import { useSession } from 'next-auth/react'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { SubmitHandler, useForm } from 'react-hook-form'
+import AlertIcon from '../../../public/images/alert.svg'
+
+interface FormData {
+ name: string
+ slug: string
+ color: string
+}
+
+const ModalCreateTag = ({
+ setIsOpen,
+ isOpen,
+ icon,
+ tittle,
+ description,
+ textTrue,
+ textFalse = 'Cancelar',
+ functionTrue,
+ functionFalse
+}: {
+ isOpen: boolean
+ setIsOpen: (value: boolean) => void
+ icon?: boolean
+ tittle: string
+ description?: string
+ textTrue: string
+ textFalse?: string
+ functionTrue: () => void
+ functionFalse: () => void
+}) => {
+ const router = useRouter()
+ const { data: session } = useSession()
+
+ const {
+ register,
+ handleSubmit,
+ watch,
+ getValues,
+ formState: { errors }
+ } = useForm()
+
+ const onSubmit: SubmitHandler = async (dataForm) => {
+ const { name, slug, color } = dataForm
+
+ // try {
+ // const response = await fetch('/api/tag', {
+ // method: 'POST',
+ // headers: {
+ // 'Content-Type': 'application/json'
+ // },
+
+ // body: JSON.stringify({
+ // name,
+ // slug: slugify(name),
+ // color,
+ // userEmail: session?.user?.email
+ // })
+ // })
+ // // if (!response.ok) {
+ // // throw new Error('You have already used this title')
+ // // }
+ // if (!response.ok) {
+ // const errorData = await response.json()
+ // }
+ // const data = await response.json()
+ // setIsOpen(false)
+ // } catch (error) {
+ // console.error(error, 'Error fetching data')
+ // const errorMessage = (error as { message?: string })?.message || 'Error creating post'
+ // }
+ }
+ return (
+ setIsOpen(false)}
+ className="fixed inset-0 flex items-center justify-center z-50"
+ >
+
+ {icon && (
+
+
+
+ )}
+ {tittle}
+
+
+
+ )
+}
+
+export default ModalCreateTag
diff --git a/src/components/atoms/StatIndividual.tsx b/src/components/atoms/StatIndividual.tsx
new file mode 100644
index 0000000..b550777
--- /dev/null
+++ b/src/components/atoms/StatIndividual.tsx
@@ -0,0 +1,10 @@
+const StatIndividual = ({ stat, tittle }: { stat: number; tittle: string }) => {
+ return (
+
+ )
+}
+
+export default StatIndividual
diff --git a/src/components/atoms/Tab.tsx b/src/components/atoms/Tab.tsx
new file mode 100644
index 0000000..8be515b
--- /dev/null
+++ b/src/components/atoms/Tab.tsx
@@ -0,0 +1,39 @@
+import { languageRedirect } from '@/helpers/changeLanguage'
+import { useRouter } from 'next/router'
+import { useState } from 'react'
+
+export const Tab = ({ className }: { className?: string }) => {
+ const router = useRouter()
+ const currentLanguage = router.locale || 'es'
+ const [selectedTab, setSelectedTab] = useState(currentLanguage)
+ const handleTabClick = (tab: string) => {
+ languageRedirect(router, tab)
+ setSelectedTab(tab)
+ }
+ return (
+
+
+ handleTabClick('es')}
+ >
+ Es
+
+ handleTabClick('en')}
+ >
+ En
+
+
+
+ )
+}
diff --git a/src/components/atoms/Tag.tsx b/src/components/atoms/Tag.tsx
new file mode 100644
index 0000000..2512abd
--- /dev/null
+++ b/src/components/atoms/Tag.tsx
@@ -0,0 +1,21 @@
+type Tag = {
+ color: string
+ name: string
+ className?: string
+ [others: string]: any
+}
+
+const Tag = ({ color, name, className, others }: Tag) => {
+ return (
+
+ )
+}
+
+export default Tag
diff --git a/src/components/layouts/Layout.tsx b/src/components/layouts/Layout.tsx
new file mode 100644
index 0000000..9c9c067
--- /dev/null
+++ b/src/components/layouts/Layout.tsx
@@ -0,0 +1,16 @@
+import React from 'react'
+import { Footer } from '../organism/Footer'
+import { Navbar } from '../organism/Navbar'
+
+type LayoutProps = {
+ children: React.ReactNode
+}
+export const Layout = ({ children }: LayoutProps) => {
+ return (
+
+ )
+}
diff --git a/src/components/molecules/Card.tsx b/src/components/molecules/Card.tsx
new file mode 100644
index 0000000..3de641b
--- /dev/null
+++ b/src/components/molecules/Card.tsx
@@ -0,0 +1,301 @@
+import Image from 'next/image'
+import Link from 'next/link'
+import { FaRegComment } from 'react-icons/fa'
+// import { FaLink } from 'react-icons/fa6'
+// import { MdDelete, MdEdit } from 'react-icons/md'
+import { useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { CgLoadbarSound } from 'react-icons/cg'
+import { FaRegStar, FaStar } from 'react-icons/fa'
+import { FcLike } from 'react-icons/fc'
+import { FiHeart } from 'react-icons/fi'
+import { Post } from '../../../type'
+import { DropDownShare } from '../atoms/DropDownShare'
+import Modal from '../atoms/Modal'
+
+interface CardProps {
+ post: Post
+}
+
+export function Card({ post }: CardProps) {
+ // const { postData, updatePostData } = usePostContext()
+ const {
+ description,
+ title,
+ Category,
+ slug,
+ url,
+ Like,
+ id,
+ comments,
+ views,
+ twitterShareCount,
+ whatsappShareCount,
+ Favorite
+ // Tags
+ } = post
+ const { data: session } = useSession()
+ // const likeOfUser = Like?.some((user) => user.userEmail === session?.user?.email)
+ const [isLike, setIsLike] = useState()
+ const [isFavorite, setIsFavorite] = useState()
+ const [likesCount, setLikesCount] = useState(Like?.length || 0)
+ const [favoriteCount, setFavoriteCount] = useState(Favorite?.length || 0)
+ let [isOpen, setIsOpen] = useState(false)
+ const router = useRouter()
+
+ useEffect(() => {
+ if (session && Like?.some((like) => like?.userEmail === session?.user?.email)) {
+ setIsLike(true)
+ } else {
+ setIsLike(false)
+ }
+ }, [Like, session])
+
+ useEffect(() => {
+ if (session && Favorite?.some((fav) => fav?.userEmail === session?.user?.email)) {
+ setIsFavorite(true)
+ } else {
+ setIsFavorite(false)
+ }
+ }, [Favorite, session])
+
+ const handleAddLike = async () => {
+ if (!session) {
+ setIsOpen(true)
+ return
+ }
+ const response = await fetch(`/api/like`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: id,
+ session: session
+ })
+ })
+ const data = await response.json()
+ if (response.ok) {
+ data && setIsLike(true)
+ setLikesCount((prevCount) => prevCount + 1)
+ } else {
+ console.error('Error al dar like:', data.error)
+ }
+ }
+ const handleDeleteLike = async () => {
+ if (!session) {
+ setIsOpen(true)
+ return
+ }
+ const response = await fetch('/api/like', {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: id,
+ session: session
+ })
+ })
+
+ const data = await response.json()
+
+ if (response.ok) {
+ setIsLike(false)
+ setLikesCount((prevCount) => Math.max(0, prevCount - 1))
+ } else {
+ console.error('Error al quitar like:', data.error)
+ }
+ }
+ const handleAddFavorite = async () => {
+ if (!session) {
+ setIsOpen(true)
+ return
+ }
+ const response = await fetch(`/api/favorite`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: id,
+ session: session
+ })
+ })
+ const data = await response.json()
+ if (response.ok) {
+ data && setIsFavorite(true)
+ setFavoriteCount((prevCount) => prevCount + 1)
+ } else {
+ console.error('Error al dar like:', data.error)
+ }
+ }
+ const handleDeleteFavorite = async () => {
+ if (!session) {
+ setIsOpen(true)
+ return
+ }
+ const response = await fetch('/api/favorite', {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: id,
+ session: session
+ })
+ })
+
+ const data = await response.json()
+
+ if (response.ok) {
+ setIsFavorite(false)
+ setFavoriteCount((prevCount) => Math.max(0, prevCount - 1))
+ } else {
+ console.error('Error al quitar like:', data.error)
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
{title}
+
+
+
+
+ {description?.length > 80 ? `${description.substring(0, 80)}...` : description}
+
{' '}
+ {description?.length > 80 && (
+
+ ver más
+
+ )}
+
+
+
+ {/*
+ {Tags &&
+ Tags?.slice(0, 4).map((tag) => (
+
+ ))}
+
*/}
+
+ {/*
*/}
+
+
{
+ isLike ? handleDeleteLike() : handleAddLike()
+ }}
+ >
+ {isLike ? (
+
+ ) : (
+
+ )}
+
+ {/*
*/}
+
+
+ {likesCount}
+
+
+
+
{
+ isFavorite ? handleDeleteFavorite() : handleAddFavorite()
+ }}
+ >
+ {isFavorite ? (
+
+ ) : (
+
+ )}
+
+ {favoriteCount}
+
+
+
+
+
+
+
+
+
+
+ {comments?.length}
+ {' '}
+
+
+
+
+
+
+ {twitterShareCount + whatsappShareCount}
+ {' '}
+
+
+
+
+ {views}
+ {' '}
+
+
+
+
+
router.push('/login')}
+ functionFalse={() => router.back()}
+ />
+
+ )
+}
diff --git a/src/components/molecules/CardList.tsx b/src/components/molecules/CardList.tsx
new file mode 100644
index 0000000..ed524f9
--- /dev/null
+++ b/src/components/molecules/CardList.tsx
@@ -0,0 +1,48 @@
+import { usePostContext } from '@/context/PostContext'
+import { Card } from './Card'
+import Pagination from './Pagination'
+
+export function CardList({ page, cat, count }: any) {
+ // const [dataCards, setDataCards] = useState([])
+ // const [countN, setCount] = useState(count)
+ const { postData, updatePostData } = usePostContext()
+
+ // const getData = async (page: any, cat: any) => {
+ // console.log('funciona')
+
+ // try {
+ // const response = await fetch(`http://localhost:3000/api/posts?page=${page || 1}&cat=${cat || ''}`, {
+ // cache: 'no-store'
+ // })
+ // console.log(response)
+
+ // if (!response.ok) {
+ // throw new Error('Failed')
+ // }
+ // const result = await response.json()
+ // updatePostData(result.posts)
+ // // setCount(result.count)
+ // } catch (error) {
+ // console.error(error)
+ // }
+ // }
+ // useEffect(() => {
+ // getData(page, cat)
+ // }, [page, cat])
+
+ // NO LO TENGO MUY CLARO PERO CREO QUE ESTO NO ME HACE FALTA, TENGO QUE REVISARLO CON CALMA
+
+ const POST_PER_PAGE = 4
+ const hasPrev = POST_PER_PAGE * (page - 1) > 0
+ const hasNext = POST_PER_PAGE * (page - 1) + POST_PER_PAGE < count
+ return (
+ <>
+
+ {Array.isArray(postData) && postData?.map((item) => )}
+
+
+ >
+ )
+}
diff --git a/src/components/molecules/CardPerfil.tsx b/src/components/molecules/CardPerfil.tsx
new file mode 100644
index 0000000..3aae3b7
--- /dev/null
+++ b/src/components/molecules/CardPerfil.tsx
@@ -0,0 +1,279 @@
+import Link from 'next/link'
+import { FaRegComment } from 'react-icons/fa'
+// import { FaLink } from 'react-icons/fa6'
+// import { MdDelete, MdEdit } from 'react-icons/md'
+import { useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { CgLoadbarSound } from 'react-icons/cg'
+import { FaRegStar, FaStar } from 'react-icons/fa'
+import { FcLike } from 'react-icons/fc'
+import { FiHeart } from 'react-icons/fi'
+import { Post } from '../../../type'
+import { DropDownShare } from '../atoms/DropDownShare'
+import Modal from '../atoms/Modal'
+
+interface CardPerfilProps {
+ post: Post
+}
+
+export function CardPerfil({ post }: CardPerfilProps) {
+ // const { postData, updatePostData } = usePostContext()
+ const {
+ description,
+ title,
+ Category,
+ slug,
+ url,
+ Like,
+ id,
+ comments,
+ views,
+ twitterShareCount,
+ whatsappShareCount,
+ Favorite
+ } = post
+ const { data: session } = useSession()
+ // const likeOfUser = Like?.some((user) => user.userEmail === session?.user?.email)
+ const [isLike, setIsLike] = useState()
+ const [isFavorite, setIsFavorite] = useState()
+ const [likesCount, setLikesCount] = useState(Like?.length || 0)
+ const [favoriteCount, setFavoriteCount] = useState(Favorite?.length || 0)
+ let [isOpen, setIsOpen] = useState(false)
+ const router = useRouter()
+
+ useEffect(() => {
+ if (session && Like?.some((like) => like?.userEmail === session?.user?.email)) {
+ setIsLike(true)
+ } else {
+ setIsLike(false)
+ }
+ }, [Like, session])
+
+ useEffect(() => {
+ if (session && Favorite?.some((fav) => fav?.userEmail === session?.user?.email)) {
+ setIsFavorite(true)
+ } else {
+ setIsFavorite(false)
+ }
+ }, [Favorite, session])
+
+ const handleAddLike = async () => {
+ if (!session) {
+ setIsOpen(true)
+ return
+ }
+ const response = await fetch(`/api/like`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: id,
+ session: session
+ })
+ })
+ const data = await response.json()
+ if (response.ok) {
+ data && setIsLike(true)
+ setLikesCount((prevCount) => prevCount + 1)
+ } else {
+ console.error('Error al dar like:', data.error)
+ }
+ }
+ const handleDeleteLike = async () => {
+ if (!session) {
+ setIsOpen(true)
+ return
+ }
+ const response = await fetch('/api/like', {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: id,
+ session: session
+ })
+ })
+
+ const data = await response.json()
+
+ if (response.ok) {
+ setIsLike(false)
+ setLikesCount((prevCount) => Math.max(0, prevCount - 1))
+ } else {
+ console.error('Error al quitar like:', data.error)
+ }
+ }
+ const handleAddFavorite = async () => {
+ if (!session) {
+ setIsOpen(true)
+ return
+ }
+ const response = await fetch(`/api/favorite`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: id,
+ session: session
+ })
+ })
+ const data = await response.json()
+ if (response.ok) {
+ data && setIsFavorite(true)
+ setFavoriteCount((prevCount) => prevCount + 1)
+ } else {
+ console.error('Error al dar like:', data.error)
+ }
+ }
+ const handleDeleteFavorite = async () => {
+ if (!session) {
+ setIsOpen(true)
+ return
+ }
+ const response = await fetch('/api/favorite', {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: id,
+ session: session
+ })
+ })
+
+ const data = await response.json()
+
+ if (response.ok) {
+ setIsFavorite(false)
+ setFavoriteCount((prevCount) => Math.max(0, prevCount - 1))
+ } else {
+ console.error('Error al quitar like:', data.error)
+ }
+ }
+ return (
+
+ {/*
*/}
+
+
+
+
+
+ {/*
*/}
+
+
{
+ isLike ? handleDeleteLike() : handleAddLike()
+ }}
+ >
+ {isLike ? (
+
+ ) : (
+
+ )}
+
+ {/*
*/}
+
+
+ {likesCount}
+
+
+
+
{
+ isFavorite ? handleDeleteFavorite() : handleAddFavorite()
+ }}
+ >
+ {isFavorite ? (
+
+ ) : (
+
+ )}
+
+ {favoriteCount}
+
+
+
+
+
+
+
+
+
+
+ {comments?.length}
+ {' '}
+
+
+
+
+
+
+ {twitterShareCount + whatsappShareCount}
+ {' '}
+
+
+
+
+ {views}
+ {' '}
+
+
+
+
+
router.push('/login')}
+ functionFalse={() => router.back()}
+ />
+
+ )
+}
diff --git a/src/components/molecules/Coment.tsx b/src/components/molecules/Coment.tsx
new file mode 100644
index 0000000..4853183
--- /dev/null
+++ b/src/components/molecules/Coment.tsx
@@ -0,0 +1,107 @@
+'use client'
+
+import { useSession } from 'next-auth/react'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { useState } from 'react'
+import { MdDelete } from 'react-icons/md'
+import useSWR from 'swr'
+import { Comment } from '../../../type'
+import Modal from '../atoms/Modal'
+
+interface CommentProps {
+ postSlug?: string | string[] | undefined
+ // comments?: Comment[] | [] | undefined
+ // setComments: React.Dispatch>
+}
+export default function Comment({
+ postSlug
+}: // comments, setComments
+CommentProps) {
+ const router = useRouter()
+ const session = useSession()
+ const [showModalComment, setShowModalComment] = useState(false)
+ const fetcher = async (url: string) => {
+ const res = await fetch(url)
+ const data = await res.json()
+ if (!res.ok) {
+ throw new Error('Failed to fetch comments')
+ }
+ return data
+ }
+ // const [comments, setComments] = useState([])
+ // const [loading, setLoading] = useState(true)
+ const { data, mutate, isLoading } = useSWR(`/api/comments/?postSlug=${postSlug}`, fetcher)
+ const formatDate = (dateString: string) => {
+ const options: Intl.DateTimeFormatOptions = {
+ year: 'numeric',
+ month: 'long',
+ day: 'numeric'
+ }
+ return new Date(dateString).toLocaleDateString('en-US', options)
+ }
+ const deleteComment = async (commentId: string) => {
+ try {
+ const response = await fetch(`/api/comments`, {
+ method: 'DELETE',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ id: commentId })
+ })
+ if (!response.ok) {
+ throw new Error('Failed to delete comment')
+ }
+ mutate()
+ } catch (error) {}
+ }
+ return (
+
+
+ {isLoading
+ ? '...loading'
+ : data?.map((comment: Comment) => (
+
+
+
+
+ {comment?.user?.image && (
+
+
+
+ )}
+
+
{comment?.user?.name}
+
{formatDate(comment?.createdAt)}
+
+
+ {comment?.user?.email === session.data?.user?.email && (
+
setShowModalComment(true)}>
+
+
+ )}
+
+
{comment.description}
+
+ {/* MODAL PARA ELIMINAR COMENTARIO */}
+
deleteComment(comment?.id)}
+ functionFalse={() => setShowModalComment(false)}
+ />
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/molecules/CommentWrite.tsx b/src/components/molecules/CommentWrite.tsx
new file mode 100644
index 0000000..61583d5
--- /dev/null
+++ b/src/components/molecules/CommentWrite.tsx
@@ -0,0 +1,60 @@
+import { useSession } from 'next-auth/react'
+import { useState } from 'react'
+import { useSWRConfig } from 'swr'
+import { Button } from '../atoms/Button'
+
+export default function CommentWrite({ postSlug }: any) {
+ const [description, setDesc] = useState('')
+ const { data: session } = useSession()
+ const [loading, setLoading] = useState(false)
+ const { mutate } = useSWRConfig()
+
+ const handleChange = (e: React.ChangeEvent) => {
+ setDesc(e.target.value)
+ }
+ const handleSubmit = async () => {
+ try {
+ setLoading(true)
+
+ const response = await fetch('/api/comments', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ description, postSlug, session })
+ })
+
+ if (!response.ok) {
+ throw new Error('Failed to create comment')
+ }
+
+ setDesc('')
+ mutate(`/api/comments/?postSlug=${postSlug}`)
+ } catch (error) {
+ console.error(error)
+ } finally {
+ setLoading(false)
+ }
+ }
+ return (
+
+
Comments
+
+
+
+ Send
+
+
+
+ )
+}
diff --git a/src/components/molecules/CreatePostForm.tsx b/src/components/molecules/CreatePostForm.tsx
new file mode 100644
index 0000000..55831f9
--- /dev/null
+++ b/src/components/molecules/CreatePostForm.tsx
@@ -0,0 +1,240 @@
+import { useSession } from 'next-auth/react'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { SubmitHandler, useForm } from 'react-hook-form'
+import { Category } from '../../../type'
+import { Button } from '../atoms/Button'
+
+interface FormData {
+ title: string
+ description: string
+ url: string
+ catSlug: string
+ // tag?: string[]
+}
+
+export function CreatePostForm() {
+ const {
+ register,
+ handleSubmit,
+ watch,
+ getValues,
+ formState: { errors }
+ } = useForm()
+ // console.log(errors)
+
+ const router = useRouter()
+ // const session = useSession()
+ const { data: session } = useSession()
+ const [categories, setCategories] = useState([])
+ const [categorySelected, setCategorySelected] = useState()
+ const [error, setError] = useState()
+ // const [showCreateTag, setShowCreateTag] = useState(false)
+
+ useEffect(() => {
+ const getData = async () => {
+ try {
+ const response = await fetch('api/categories', {
+ cache: 'no-store'
+ })
+
+ if (!response.ok) {
+ throw new Error('Failed')
+ }
+
+ const result = await response.json()
+ setCategories(result)
+ } catch (error) {
+ console.error(error)
+ }
+ }
+
+ getData()
+ }, [])
+ const slugify = (str: string) => {
+ return str
+ .toLowerCase()
+ .trim()
+ .replace(/[^\w\s-]/g, '')
+ .replace(/[\s_-]+/g, '-')
+ .replace(/^-+|-+$/g, '')
+ }
+ const onSubmit: SubmitHandler = async (dataForm) => {
+ const { title, description, url, catSlug } = dataForm
+ try {
+ const response = await fetch('/api/post', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+
+ body: JSON.stringify({
+ title,
+ description,
+ slug: slugify(title),
+ catSlug: catSlug,
+ url,
+ userEmail: session?.user?.email
+ })
+ })
+ // if (!response.ok) {
+ // throw new Error('You have already used this title')
+ // }
+ if (!response.ok) {
+ const errorData = await response.json()
+ if (errorData.type === 'duplicate') throw new Error(error)
+ if (errorData.type === 'unAuthorized') throw new Error(error)
+ }
+ const data = await response.json()
+ router.push('/')
+ } catch (error) {
+ console.error(error, 'Error fetching data')
+ const errorMessage = (error as { message?: string })?.message || 'Error creating post'
+ setError(errorMessage)
+ }
+ }
+ useEffect(() => {
+ const category = getValues('catSlug')
+ const categorySelect = categories.find((cat) => cat.slug === category)
+ categorySelect && setCategorySelected(categorySelect)
+ }, [watch('catSlug')])
+
+ useEffect(() => {
+ // hago esto para comprobar si el usuario logeado (session) es admin.
+ // Para eso hago un get del usuario para traerme los datos de este y ver si es admin.
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(`/api/user?email=${session?.user?.email}`)
+ const userData = await response.json()
+ !userData.isAdmin && router.push('/')
+ } catch (error: any) {
+ console.error('Error fetching user:', error.message)
+ }
+ }
+
+ fetchUser()
+ }, [])
+
+ return (
+
+ )
+}
diff --git a/src/components/molecules/EditPost.tsx b/src/components/molecules/EditPost.tsx
new file mode 100644
index 0000000..d851bb9
--- /dev/null
+++ b/src/components/molecules/EditPost.tsx
@@ -0,0 +1,291 @@
+import { useSession } from 'next-auth/react'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { SubmitHandler, useForm } from 'react-hook-form'
+import { Category, Post } from '../../../type'
+import { Button } from '../atoms/Button'
+
+interface FormData {
+ title: string
+ description: string
+ url: string
+ catSlug: string
+ // Tags?: Tag[]
+}
+type EditProps = {
+ dataPost: Post
+}
+export function EditPost({ dataPost }: EditProps) {
+ const {
+ register,
+ handleSubmit,
+ watch,
+ getValues,
+ reset,
+ formState: { errors }
+ } = useForm()
+ // console.log(errors)
+
+ const router = useRouter()
+ // const session = useSession()
+ const { data: session } = useSession()
+ const [categories, setCategories] = useState([])
+ // const [tags, setTags] = useState()
+ const [categorySelected, setCategorySelected] = useState()
+ // const [selectedTags, setSelectedTags] = useState()
+
+ const [error, setError] = useState()
+ useEffect(() => {
+ const getData = async () => {
+ try {
+ const response = await fetch('/api/categories', {
+ cache: 'no-store'
+ })
+
+ if (!response.ok) {
+ throw new Error('Failed')
+ }
+
+ const result = await response.json()
+ setCategories(result)
+ } catch (error) {
+ console.error(error)
+ }
+ }
+
+ getData()
+ }, [])
+
+ // const slugify = (str: string) => {
+ // return str
+ // .toLowerCase()
+ // .trim()
+ // .replace(/[^\w\s-]/g, '')
+ // .replace(/[\s_-]+/g, '-')
+ // .replace(/^-+|-+$/g, '')
+ // }
+ const onSubmit: SubmitHandler = async (dataForm) => {
+ const { title, description, url, catSlug } = dataForm
+ try {
+ const response = await fetch(`/api/post/${dataPost?.slug}`, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+
+ body: JSON.stringify({
+ title,
+ description,
+ // slug: slugify(title),
+ catSlug: catSlug,
+ url
+ // Tags: selectedTags
+ // userEmail: session?.user?.email
+ })
+ })
+ // if (!response.ok) {
+ // throw new Error('You have already used this title')
+ // }
+ if (!response.ok) {
+ const errorData = await response.json()
+ if (errorData.type === 'duplicate') throw new Error(error)
+ if (errorData.type === 'unAuthorized') throw new Error(error)
+ }
+ const data = await response.json()
+ router.push('/')
+ } catch (error) {
+ console.error(error, 'Error fetching data')
+ const errorMessage = (error as { message?: string })?.message || 'Error creating post'
+ setError(errorMessage)
+ }
+ }
+ useEffect(() => {
+ const category = getValues('catSlug')
+ const categorySelect = categories.find((cat) => cat.slug === category)
+ categorySelect && setCategorySelected(categorySelect)
+ }, [watch('catSlug')])
+
+ useEffect(() => {
+ // hago esto para comprobar si el usuario logeado (session) es admin.
+ // Para eso hago un get del usuario para traerme los datos de este y ver si es admin.
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(`/api/user?email=${session?.user?.email}`)
+ const userData = await response.json()
+ !userData.isAdmin && router.push('/')
+ } catch (error: any) {
+ console.error('Error fetching user:', error.message)
+ }
+ }
+
+ fetchUser()
+ }, [session])
+
+ useEffect(() => {
+ reset({
+ title: dataPost?.title,
+ catSlug: dataPost?.catSlug,
+ description: dataPost?.description,
+ url: dataPost?.url
+ // Tags: dataPost?.Tags
+ })
+ // setSelectedTags(dataPost?.Tags?.map((tag) => tag) || [])
+ }, [dataPost])
+
+ return (
+
+
+
Editar post
+
+
+
+
+
+
+
+
+
+
+ Seleccionar categoría
+ {categories.map((category: Category) => (
+
+ {category.title}
+
+ ))}
+
+
+ {/*
+
+ Seleccionar tag
+ {tags?.map((tag: Tag) => (
+
+ {tag.name}
+
+ ))}
+
+
*/}
+ {/*
+ {
+ const selectedTag = e.target.value
+ setSelectedTags((prevTags) => [...prevTags, selectedTag]) // Permite seleccionar múltiples tags
+ }}
+ >
+ Seleccionar tag
+ {tags?.map((tag: Tag) => (
+
+ {tag.name}
+
+ ))}
+
+
*/}
+
+
+ {/* {tags?.map((tag) => (
+
+ tag.slug).includes(tag.slug)}
+ onChange={(e) => {
+ const tagSlug = e.target.value
+ const selectedTag = tags.find((tag) => tag.slug === tagSlug)
+ setSelectedTags((prevTags) => {
+ if (prevTags.some((prevTag) => prevTag.slug === tagSlug)) {
+ // Si el tag ya está seleccionado, quítalo de la lista
+ return prevTags.filter((prevTag) => prevTag.slug !== tagSlug)
+ } else {
+ // Si el tag no está seleccionado, agrégalo a la lista
+ return [...prevTags, selectedTag]
+ }
+ })
+ }}
+ />
+
+ {tag?.name}
+
+ ))} */}
+
+
+
+
+
+
+
+
+
+ {errors && errors.title && (
+
+
{errors.title.message}
+
+ )}
+ {errors && errors.description && (
+
+
{errors.description.message}
+
+ )}
+ {errors && errors.url && (
+
+ )}
+ {error && (
+
+ )}
+
+
+ Editar
+ {' '}
+
+
+ )
+}
diff --git a/src/components/molecules/EditUser.tsx b/src/components/molecules/EditUser.tsx
new file mode 100644
index 0000000..9157b9a
--- /dev/null
+++ b/src/components/molecules/EditUser.tsx
@@ -0,0 +1,136 @@
+import { useSession } from 'next-auth/react'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { SubmitHandler, useForm } from 'react-hook-form'
+import { User } from '../../../type'
+import { Button } from '../atoms/Button'
+
+type EditProps = {
+ user: User
+}
+export function EditUser({ user }: EditProps) {
+ const {
+ register,
+ handleSubmit,
+ watch,
+ getValues,
+ reset,
+ setError,
+ formState: { errors }
+ } = useForm({
+ defaultValues: {}
+ })
+ const router = useRouter()
+ // const [userData, setUser] = useState()
+
+ const { data: session, status } = useSession()
+ const [errorShow, setShowError] = useState('')
+ const onSubmit: SubmitHandler = async (dataForm) => {
+ try {
+ const response = await fetch(`/api/user/?email=${user?.email}`, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+
+ body: JSON.stringify({
+ name: dataForm.name
+ })
+ })
+
+ if (response.status === 409) {
+ const errorData = await response.json()
+ setError('name', { type: 'manual', message: errorData.message })
+ return
+ }
+ if (!response.ok) {
+ throw new Error('Error updating user. Please try again later.')
+ }
+ const data = await response.json()
+ setShowError(data?.message)
+ // router.push('/')
+ } catch (error) {
+ console.error(error, 'Error fetching data')
+ }
+ }
+ useEffect(() => {
+ status === 'unauthenticated' && router.push('/')
+ }, [session, status, router])
+ useEffect(() => {
+ reset({
+ name: user?.name,
+ email: user?.email
+ })
+ }, [user])
+
+ return (
+
+
+
Editar usuario
+
+
+ {errors && errors.name && (
+
+
{errors.name.message}
+
+ )}
+ {errors && errors.email && (
+
+
{errors.email.message}
+
+ )}
+ {errorShow && (
+
+ )}
+
+
+
+ Guardar
+ {' '}
+
+
+ )
+}
diff --git a/src/components/molecules/MenuNavbar.tsx b/src/components/molecules/MenuNavbar.tsx
new file mode 100644
index 0000000..b364944
--- /dev/null
+++ b/src/components/molecules/MenuNavbar.tsx
@@ -0,0 +1,77 @@
+import { signOut, useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { User } from '../../../type'
+import { Button } from '../atoms/Button'
+interface MenuNavbarProps {
+ // userCurrent: User | undefined
+ dataUserCurrent: User
+}
+
+export const MenuNavbar = ({ dataUserCurrent }: MenuNavbarProps) => {
+ const router = useRouter()
+ const { status, data: session } = useSession()
+
+ return (
+
+ {
+ router.push('/')
+ }}
+ >
+ Home
+
+ {dataUserCurrent && dataUserCurrent.isAdmin && (
+ {
+ router.push('/create')
+ }}
+ >
+ Create
+
+ )}
+ {dataUserCurrent && (
+ {
+ router.push('/perfil')
+ }}
+ >
+ Perfil
+
+ )}
+ {status === 'authenticated' ? (
+ {
+ signOut()
+ }}
+ >
+ Logout
+
+ ) : (
+ {
+ router.push('/login')
+ }}
+ >
+ Login
+
+ )}
+ {!dataUserCurrent && (
+ {
+ router.push('/register')
+ }}
+ >
+ Register
+
+ )}
+ {/* */}
+
+ )
+}
diff --git a/src/components/molecules/Pagination.tsx b/src/components/molecules/Pagination.tsx
new file mode 100644
index 0000000..74c79e8
--- /dev/null
+++ b/src/components/molecules/Pagination.tsx
@@ -0,0 +1,33 @@
+import { useRouter } from 'next/router'
+import { Button } from '../atoms/Button'
+
+const Pagination = ({ page, hasPrev, hasNext }: any) => {
+ const router = useRouter()
+
+ return (
+
+ {
+ router.push(`?page=${Number(page) - 1}`)
+ }}
+ >
+ Previous
+
+ {
+ router.push(`?page=${Number(page) + 1}`)
+ }}
+ >
+ Next
+
+
+ )
+}
+
+export default Pagination
diff --git a/src/components/molecules/Stats.tsx b/src/components/molecules/Stats.tsx
new file mode 100644
index 0000000..4194e4e
--- /dev/null
+++ b/src/components/molecules/Stats.tsx
@@ -0,0 +1,58 @@
+import { useEffect, useState } from 'react'
+import { Stats } from '../../../type'
+
+const Stats = () => {
+ const [stats, setStats] = useState(null)
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const response = await fetch('/api/stats')
+ if (!response.ok) {
+ throw new Error('Failed to fetch data')
+ }
+ const data = await response.json()
+ setStats(data)
+ } catch (error) {
+ console.error('Error fetching stats:', error)
+ }
+ }
+ fetchData()
+ }, [])
+ return (
+
+ {stats ? (
+
+
+
{stats.totalPosts}
+
Recursos totales
+
+
+
{stats.totalUsers}
+
Usuarios totales
+
+
+
+
+ {stats.totalShares.twitterShareCount + stats.totalShares.whatsappShareCount}
+
+
+
+ Recursos compartidos
+
+
+
+
{stats.totalViews.views}
+
+ Vistas totales de recursos
+
+
+
+ ) : (
+
Loading...
+ )}
+
+ )
+}
+
+export default Stats
diff --git a/src/components/organism/Footer.tsx b/src/components/organism/Footer.tsx
new file mode 100644
index 0000000..a1cc881
--- /dev/null
+++ b/src/components/organism/Footer.tsx
@@ -0,0 +1,59 @@
+import { useTranslation } from 'next-i18next'
+import Image from 'next/image'
+import Link from 'next/link'
+import { useRouter } from 'next/router'
+import github from '../../../public/images/github.svg'
+import linkedin from '../../../public/images/linkedin.svg'
+
+export function Footer() {
+ const { t } = useTranslation()
+ const router = useRouter()
+
+ return (
+
+
+
+
+ Encuentra recursos, guarda, y compartelos.
+
+
+ {/*
+
+ Titulo Footer
+ Texto footer 1
+ Texto footer 2
+
+
*/}
+ {/*
+
+ Titulo Footer 2
+ Texto footer 1
+ Texto footer 2
+
+
*/}
+ {/*
+
+ Titulo Footer 3
+ Texto footer 1
+ Texto footer 2
+
+
*/}
+
+
+
+ )
+}
diff --git a/src/components/organism/FormLogin.tsx b/src/components/organism/FormLogin.tsx
new file mode 100644
index 0000000..8352234
--- /dev/null
+++ b/src/components/organism/FormLogin.tsx
@@ -0,0 +1,73 @@
+import { Button } from '@/components/atoms/Button'
+import { signIn, useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { SubmitHandler, useForm } from 'react-hook-form'
+
+type FormData = {
+ email: string
+ password: string
+}
+
+export default function FormLogin() {
+ const {
+ register,
+ handleSubmit,
+ formState: { errors }
+ } = useForm()
+ const onSubmit: SubmitHandler = (data) => {}
+ const router = useRouter()
+ const { data, status } = useSession()
+
+ if (status === 'loading') {
+ return ...loading
+ }
+ status === 'authenticated' && router.push('/')
+
+ return (
+ <>
+
+
Login
+ {/*
Estamos en proceso de añadir mas maneras de registrarse y logearse...
*/}
+ {/*
+
+ Email
+
+ Password
+
+
+
+ Send
+
+ */}
+ {/*
+
+ or
+
+ {' '} */}
+
+
+ signIn('github')}
+ >
+ Sign in with Github
+
+
+
+ signIn('google')}
+ >
+ Sign in with Google
+
+
+
+
+ >
+ )
+}
diff --git a/src/components/organism/Navbar.tsx b/src/components/organism/Navbar.tsx
new file mode 100644
index 0000000..7971b3f
--- /dev/null
+++ b/src/components/organism/Navbar.tsx
@@ -0,0 +1,123 @@
+import { signOut, useSession } from 'next-auth/react'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { GiHamburgerMenu } from 'react-icons/gi'
+import { GrClose } from 'react-icons/gr'
+import iconWorldResource from '../../../public/images/devWorldResources-removebg.svg'
+import { User } from '../../../type'
+import { Button } from '../atoms/Button'
+import { MenuNavbar } from '../molecules/MenuNavbar'
+
+export function Navbar() {
+ const router = useRouter()
+ const [open, setOpen] = useState()
+ // const [users, setUsers] = useState()
+ const [dataUserCurrent, setDataUserCurrent] = useState()
+ const { status, data: session } = useSession()
+
+ useEffect(() => {
+ // Hago un get del usuario para traerme los datos de este.
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(`/api/user?email=${session?.user?.email}`)
+ const userData = await response.json()
+ setDataUserCurrent(userData)
+ } catch (error: any) {
+ console.error('Error fetching user:', error.message)
+ }
+ }
+
+ if (session?.user?.email) {
+ fetchUser()
+ }
+ }, [session])
+
+ return (
+ <>
+
+
+ {
+ router.push('/')
+ }}
+ />
+
+
{}
+
+
+
{
+ setOpen(!open)
+ }}
+ >
+ {open && }
+ {!open && }
+
+ {open ? (
+
+
+ {
+ router.push('/')
+ }}
+ >
+ Home
+
+ {dataUserCurrent?.isAdmin && (
+ {
+ router.push('/create')
+ }}
+ >
+ Create
+
+ )}
+ {dataUserCurrent && (
+ {
+ router.push('/perfil')
+ }}
+ >
+ Perfil
+
+ )}
+ {!dataUserCurrent && Register }
+ {status === 'authenticated' ? (
+ {
+ signOut()
+ }}
+ >
+ Logout
+
+ ) : (
+ {
+ router.push('/login')
+ }}
+ >
+ Login
+
+ )}
+
+
+ ) : (
+ ''
+ )}
+
+
+ >
+ )
+}
diff --git a/src/components/sections/SectionCategories.tsx b/src/components/sections/SectionCategories.tsx
new file mode 100644
index 0000000..9894a9c
--- /dev/null
+++ b/src/components/sections/SectionCategories.tsx
@@ -0,0 +1,156 @@
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { FaFilterCircleXmark } from 'react-icons/fa6'
+import { Post } from '../../../type'
+import AutoCompleteInput from '../atoms/AutoCompleteInput'
+import { Button } from '../atoms/Button'
+
+// type SectionCategoryProps = {
+// onCategoryClick: (value: string) => void
+// caterogySelect: string
+// page: number
+// selectedTags: string[]
+// onTagClick: (value: string) => void
+// }
+
+export function SectionCategories({
+ onCategoryClick,
+ caterogySelect,
+ page
+}: // selectedTags,
+// onTagClick
+// setSelectedTags
+any) {
+ const [category, setCategory] = useState([])
+ const [textSearched, setTextSearched] = useState('')
+ const [posts, setPosts] = useState([])
+
+ // const [tags, setTags] = useState([])
+ const router = useRouter()
+ useEffect(() => {
+ const getData = async () => {
+ try {
+ const responseCategory = await fetch('api/categories', {
+ cache: 'no-store'
+ })
+ if (!responseCategory.ok) {
+ throw new Error('Failed')
+ }
+
+ const resultCategory = await responseCategory.json()
+ setCategory(resultCategory)
+ } catch (error) {
+ console.error(error)
+ }
+ }
+
+ getData()
+ }, [caterogySelect])
+ useEffect(() => {
+ const getData = async () => {
+ try {
+ const response = await fetch(`api/allPosts?category=${caterogySelect}`, {
+ cache: 'no-store'
+ })
+ // router.push(`?page=1`)
+ if (!response.ok) {
+ throw new Error('Failed')
+ }
+ const result = await response.json()
+ setPosts(result)
+ } catch (error) {
+ console.error(error)
+ }
+ }
+
+ getData()
+ }, [caterogySelect])
+ return (
+
+
+ {category?.map((cat: any) => (
+
onCategoryClick(cat.slug)}
+ className={`cursor-pointer ${caterogySelect === cat.slug ? 'opacity-50 cursor-not-allowed' : ''}`}
+ >
+
+
+ {/* bg-white rounded-full */}
+
+
+
+
+
+ ))}
+
+ {caterogySelect && (
+
+
+ {caterogySelect && (
+
{
+ // setSelectedTags('')
+ onCategoryClick('')
+ }}
+ disabled={!caterogySelect}
+ >
+ {/* Quitar filtros
*/}
+
+
+ )}
+
+ )}
+ {/* {caterogySelect && (
+
+ {tags.map((tag) => (
+ <>
+
{
+ console.log('Clicked')
+
+ onTagClick(tag.slug)
+ }}
+ className="cursor-pointer"
+ />
+
+
{
+ console.log('Clicked')
+ onTagClick(tag.slug)
+ }}
+ >
+
{tag.name}
+
+
+ >
+ ))}
+
+ )} */}
+
+ )
+}
diff --git a/src/constants.ts b/src/constants.ts
new file mode 100644
index 0000000..3fd8add
--- /dev/null
+++ b/src/constants.ts
@@ -0,0 +1,9 @@
+export const slugify = (str: string) => {
+ return str
+ .trim()
+ .toLowerCase()
+ .normalize('NFD')
+ .replace(/[\u0300-\u036f]/g, '')
+ .replace(/[^a-zA-Z0-9\s]/g, '')
+ .replace(/\s+/g, '-')
+}
diff --git a/src/context/PostContext.js b/src/context/PostContext.js
new file mode 100644
index 0000000..beb0a3d
--- /dev/null
+++ b/src/context/PostContext.js
@@ -0,0 +1,18 @@
+import { createContext, useContext, useState } from 'react'
+
+const AppContext = createContext()
+
+export const PostContext = ({ children }) => {
+ const [postData, setPostData] = useState([])
+
+ const updatePostData = (newData) => {
+ setPostData(newData)
+ }
+
+ return {children}
+}
+
+export const usePostContext = () => {
+ return useContext(AppContext)
+}
+
diff --git a/src/helpers/changeLanguage.ts b/src/helpers/changeLanguage.ts
new file mode 100644
index 0000000..81ab05b
--- /dev/null
+++ b/src/helpers/changeLanguage.ts
@@ -0,0 +1,6 @@
+import { NextRouter } from 'next/router'
+
+export const languageRedirect = (router: NextRouter, language: string) => {
+ const { pathname, asPath, query } = router
+ router.push({ pathname, query }, asPath, { locale: language })
+}
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
new file mode 100644
index 0000000..86e6070
--- /dev/null
+++ b/src/pages/_app.tsx
@@ -0,0 +1,18 @@
+import AuthProvider from '@/providers/AuthProvider'
+import '@/styles/globals.scss'
+import { appWithTranslation } from 'next-i18next'
+import type { AppProps } from 'next/app'
+import { PostContext } from '../context/PostContext'
+const i18nextConfig = require('../../next-i18next.config')
+
+const App = ({ Component, pageProps }: AppProps) => {
+ return (
+
+
+
+
+
+ )
+}
+
+export default appWithTranslation(App, i18nextConfig)
diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx
new file mode 100644
index 0000000..ddc3d65
--- /dev/null
+++ b/src/pages/_document.tsx
@@ -0,0 +1,14 @@
+import { Head, Html, Main, NextScript } from 'next/document'
+
+export default function Document() {
+ return (
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/pages/api/allPosts/index.ts b/src/pages/api/allPosts/index.ts
new file mode 100644
index 0000000..d59d165
--- /dev/null
+++ b/src/pages/api/allPosts/index.ts
@@ -0,0 +1,50 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import prisma from '../../../utils/connect'
+
+export default async function allPosts(req: NextApiRequest, res: NextApiResponse) {
+ const { category } = req.query
+
+ if (req.method === 'GET') {
+ try {
+ let posts
+
+ if (category) {
+ const categoryFilter = typeof category === 'string' ? category : category[0]
+
+ posts = await prisma.post.findMany({
+ where: {
+ Category: {
+ slug: categoryFilter
+ }
+ },
+ orderBy: { createdAt: 'desc' },
+ include: {
+ Category: true,
+ Like: true,
+ comments: true,
+ Favorite: true
+ }
+ })
+ } else {
+ // Si no se proporciona una categoría, obtenemos todos los posts
+ posts = await prisma.post.findMany({
+ orderBy: { createdAt: 'desc' },
+ include: {
+ Category: true,
+ Like: true,
+ comments: true,
+ Favorite: true
+ }
+ })
+ }
+
+ res.status(200).json(posts)
+ } catch (error: any) {
+ console.error(error)
+ res.status(500).json({ message: 'Something went wrong', error: error.message })
+ }
+ } else {
+ res.setHeader('Allow', ['GET'])
+ res.status(405).end(`Method ${req.method} Not Allowed`)
+ }
+}
diff --git a/src/pages/api/auth/[...nextauth].js b/src/pages/api/auth/[...nextauth].js
new file mode 100644
index 0000000..aaa8d05
--- /dev/null
+++ b/src/pages/api/auth/[...nextauth].js
@@ -0,0 +1,4 @@
+import NextAuth from 'next-auth'
+import { authOptions } from '../../../utils/auth'
+
+export default NextAuth(authOptions)
diff --git a/src/pages/api/categories.ts b/src/pages/api/categories.ts
new file mode 100644
index 0000000..dcd16e4
--- /dev/null
+++ b/src/pages/api/categories.ts
@@ -0,0 +1,12 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import prisma from '../../utils/connect'
+
+export default async function GET(req: NextApiRequest, res: NextApiResponse) {
+ try {
+ const categories = await prisma.category.findMany()
+ res.status(200).json(categories)
+ } catch (error: any) {
+ console.error(error)
+ res.status(500).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/categories/routes.ts b/src/pages/api/categories/routes.ts
new file mode 100644
index 0000000..1edfbba
--- /dev/null
+++ b/src/pages/api/categories/routes.ts
@@ -0,0 +1,40 @@
+// import { NextApiRequest, NextApiResponse } from 'next'
+// import { createComment, deleteComment, getAllComments } from '../../../../prisma/comment'
+
+// export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+// try {
+// switch (req.method) {
+// case 'GET': {
+// const comments = await getAllComments(req.query.postSlug as string)
+// console.log(comments, 'comments')
+
+// res.status(200).json(comments)
+// break
+// }
+// case 'POST': {
+// console.log('EMPIEZA')
+// // Manejar la lógica para el método POST
+// // const session = await getAuthSession()
+
+// console.log(req.body.session, 'session')
+// await createComment(req.body, req.body.session?.user?.email, req.body.session)
+// console.log('aqui llega?')
+// res.status(200).json({ message: 'Comment created successfully' })
+// break
+// }
+// case 'DELETE': {
+// console.log('DELETE')
+// await deleteComment(req.body.id)
+// res.status(200).json({ message: 'Comment deleted successfully ' })
+// }
+// default:
+// // Manejar otros métodos HTTP si es necesario
+// res.status(405).json({ message: 'Method Not Allowed' })
+// break
+// }
+// } catch (error: any) {
+// console.error(error)
+// const status = error.message === 'Not Authenticated' ? 401 : 500
+// res.status(status).json({ message: 'Something went wrong', error: error.message })
+// }
+// }
diff --git a/src/pages/api/comments/index.ts b/src/pages/api/comments/index.ts
new file mode 100644
index 0000000..3e713f9
--- /dev/null
+++ b/src/pages/api/comments/index.ts
@@ -0,0 +1,31 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import { createComment, deleteComment, getAllComments } from '../../../../prisma/comment'
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ try {
+ switch (req.method) {
+ case 'GET': {
+ const comments = await getAllComments(req.query.postSlug as string)
+
+ res.status(200).json(comments)
+ break
+ }
+ case 'POST': {
+ await createComment(req.body, req.body.session?.user?.email, req.body.session)
+ res.status(200).json({ message: 'Comment created successfully' })
+ break
+ }
+ case 'DELETE': {
+ await deleteComment(req.body.id)
+ res.status(200).json({ message: 'Comment deleted successfully ' })
+ }
+ default:
+ res.status(405).json({ message: 'Method Not Allowed' })
+ break
+ }
+ } catch (error: any) {
+ console.error(error)
+ const status = error.message === 'Not Authenticated' ? 401 : 500
+ res.status(status).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/favorite/index.ts b/src/pages/api/favorite/index.ts
new file mode 100644
index 0000000..85a622c
--- /dev/null
+++ b/src/pages/api/favorite/index.ts
@@ -0,0 +1,58 @@
+import { addFavorite, deleteFavorite } from '../../../../prisma/favorite'
+import { getUserByEmail } from '../../../../prisma/user'
+
+export default async function handler(req, res) {
+ try {
+ switch (req.method) {
+ case 'POST': {
+ const { email, postId, session } = req.body
+ if (!email) {
+ res.status(400).json({ message: 'User email is required' })
+ return
+ }
+ if (!postId) {
+ res.status(400).json({ message: 'Post ID is required' })
+ return
+ }
+ const user = await getUserByEmail(email as string)
+ if (!user) {
+ res.status(404).json({ message: 'User not found' })
+ return
+ }
+ const newFavorite = await addFavorite(postId, user.email, session)
+ res.status(200).json(newFavorite)
+ break
+ }
+ case 'DELETE': {
+ const { email, postId, session } = req.body
+ if (!email) {
+ res.status(400).json({ message: 'User email is required' })
+ return
+ }
+ if (!postId) {
+ res.status(400).json({ message: 'Post ID is required' })
+ return
+ }
+ const user = await getUserByEmail(email as string)
+ if (!user) {
+ res.status(404).json({ message: 'User not found' })
+ return
+ }
+ try {
+ await deleteFavorite(postId, user.email, session)
+ res.status(200).json({ message: 'Favorite removed successfully.' })
+ } catch (error) {
+ res.status(500).json({ message: 'Error removing favorite', error: error.message })
+ }
+ break
+ }
+ default:
+ res.status(405).json({ message: 'Method Not Allowed' })
+ break
+ }
+ } catch (error: any) {
+ console.error(error)
+ const status = error.message === 'Not Authenticated' ? 401 : 500
+ res.status(status).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/like/index.ts b/src/pages/api/like/index.ts
new file mode 100644
index 0000000..1eed825
--- /dev/null
+++ b/src/pages/api/like/index.ts
@@ -0,0 +1,60 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import { addLike, deleteLike } from '../../../../prisma/like'
+import { getUserByEmail } from '../../../../prisma/user'
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ try {
+ switch (req.method) {
+ case 'POST': {
+ const { email, postId, session } = req.body
+ if (!email) {
+ res.status(400).json({ message: 'User email is required' })
+ return
+ }
+ if (!postId) {
+ res.status(400).json({ message: 'Post ID is required' })
+ return
+ }
+ const user = await getUserByEmail(email as string)
+ if (!user) {
+ res.status(404).json({ message: 'User not found' })
+ return
+ }
+ const newLike = await addLike(postId, user.email, session)
+ res.status(200).json(newLike)
+ break
+ }
+ case 'DELETE': {
+ const { email, postId, session } = req.body
+ if (!email) {
+ res.status(400).json({ message: 'User email is required' })
+ return
+ }
+ if (!postId) {
+ res.status(400).json({ message: 'Post ID is required' })
+ return
+ }
+ const user = await getUserByEmail(email as string)
+ if (!user) {
+ res.status(404).json({ message: 'User not found' })
+ return
+ }
+ try {
+ await deleteLike(postId, user.email, session)
+ res.status(200).json({ message: 'Like eliminado correctamente.' })
+ } catch (error) {
+ res.status(500).json({ message: 'Error al quitar el like', error: error.message })
+ }
+ break
+ }
+
+ default:
+ res.status(405).json({ message: 'Method Not Allowed' })
+ break
+ }
+ } catch (error: any) {
+ console.error(error)
+ const status = error.message === 'Not Authenticated' ? 401 : 500
+ res.status(status).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/post.ts b/src/pages/api/post.ts
new file mode 100644
index 0000000..44aaad6
--- /dev/null
+++ b/src/pages/api/post.ts
@@ -0,0 +1,39 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import prisma from '../../utils/connect'
+
+export default async function POST(req: NextApiRequest, res: NextApiResponse) {
+ const { userEmail, slug } = req.body
+ if (!userEmail) {
+ res.status(401).json({ error: 'Not Authenticated' })
+ return
+ }
+ const user = await prisma.user.findUnique({
+ where: {
+ email: userEmail
+ }
+ })
+
+ if (!user || !user.isAdmin) {
+ res.status(403).json({ error: 'Not Authorized', type: 'unAuthorized' })
+ return
+ }
+ try {
+ const existingPost = await prisma.post.findUnique({
+ where: {
+ slug: slug
+ }
+ })
+ if (existingPost) {
+ res.status(400).json({ error: 'Post with this slug already exists', type: 'duplicate' })
+ return
+ }
+
+ const post = await prisma.post.create({
+ data: { ...req.body }
+ })
+ res.status(200).json(post)
+ } catch (error) {
+ console.error('Error creating post:', error)
+ res.status(500).json({ error: 'Error creating post' })
+ }
+}
diff --git a/src/pages/api/post/[slug].ts b/src/pages/api/post/[slug].ts
new file mode 100644
index 0000000..0a9f603
--- /dev/null
+++ b/src/pages/api/post/[slug].ts
@@ -0,0 +1,67 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import { deletePost, editPost } from '../../../../prisma/post'
+import prisma from '../../../utils/connect'
+
+//GET SINGLE POST
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ // try {
+ // const { slug } = req.query
+
+ // const post = await prisma.post.update({
+ // where: { slug: String(slug) },
+ // data: { views: { increment: 1 } },
+ // include: { user: true }
+ // // include: {
+ // // comments: {
+ // // include: {
+ // // user: true
+ // // }
+ // // }
+ // // }
+ // })
+ // // console.log(post, 'POST BACK')
+
+ // res.status(200).json(post)
+ // } catch (error: any) {
+ // console.error(error)
+ // res.status(500).json({ message: 'Something went wrong', error: error.message })
+ // }
+ try {
+ const { slug } = req.query
+ const { body } = req
+ switch (req.method) {
+ case 'GET': {
+ const post = await prisma.post.update({
+ where: { slug: String(slug) },
+ data: { views: { increment: 1 } },
+ include: {
+ user: true,
+ Category: true,
+ Like: true,
+ comments: true,
+ Favorite: true
+ // , Tags: true
+ }
+ })
+ res.status(200).json(post)
+ break
+ }
+ case 'DELETE': {
+ await deletePost(String(slug))
+ res.status(200).json({ message: 'Post deleted successfully' })
+ break
+ }
+ case 'PUT': {
+ await editPost(String(slug), body)
+ res.status(200).json({ message: 'Post updated successfully' })
+ break
+ }
+ default:
+ res.status(405).json({ message: 'Method Not Allowed' })
+ break
+ }
+ } catch (error: any) {
+ console.error(error)
+ res.status(500).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/posts.ts b/src/pages/api/posts.ts
new file mode 100644
index 0000000..9ae825e
--- /dev/null
+++ b/src/pages/api/posts.ts
@@ -0,0 +1,54 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import { resolve } from 'url'
+import prisma from '../../utils/connect'
+
+export default async function GET(req: NextApiRequest, res: NextApiResponse) {
+ const url = resolve(`${process.env.NEXTAUTH_URL_INTERNAL}`, req.url || 'page=1') //pendiente de quitar /api/posts?page=1 ESTO ES UNA PRUEBA QUITALO SI NO VA
+ const { searchParams } = new URL(url)
+ const page = searchParams.get('page')
+ let cat = searchParams.get('cat')
+ // let tags = searchParams.get('tags')
+
+ const POST_PER_PAGE = 4
+ const pageNumber = page ? parseInt(page, 10) : 1
+
+ const query = {
+ take: POST_PER_PAGE,
+ skip: POST_PER_PAGE * (pageNumber - 1),
+ where: {
+ ...(cat && { catSlug: cat })
+ // ...(tags && {
+ // Tags: {
+ // some: {
+ // slug: {
+ // in: tags.split(',')
+ // }
+ // }
+ // }
+ // })
+ },
+ orderBy: { createdAt: 'desc' },
+ include: {
+ Category: true,
+ Like: true,
+ comments: true,
+ Favorite: true
+ // Tags: true
+ }
+ }
+ try {
+ // const [posts, count] = await prisma.$transaction([
+ // prisma.post.findMany(query),
+ // prisma.post.count({ where: query.where })
+ // ])
+ const posts = await prisma.post.findMany({
+ ...query,
+ orderBy: { createdAt: 'desc' }
+ })
+ const count = await prisma.post.count({ where: query.where })
+ res.status(200).json({ posts, count })
+ } catch (error: any) {
+ console.error(error)
+ res.status(500).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/postsFavoriteByUser/index.ts b/src/pages/api/postsFavoriteByUser/index.ts
new file mode 100644
index 0000000..b98956e
--- /dev/null
+++ b/src/pages/api/postsFavoriteByUser/index.ts
@@ -0,0 +1,45 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import prisma from '../../../utils/connect'
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ if (req.method !== 'GET') {
+ return res.status(405).json({ message: 'Method Not Allowed' })
+ }
+
+ const userEmail = req.query.userEmail as string
+ if (!userEmail) {
+ return res.status(400).json({ message: 'User email is required' })
+ }
+
+ try {
+ const user = await prisma.user.findUnique({
+ where: { email: userEmail },
+ include: {
+ Favorite: {
+ include: {
+ post: {
+ include: {
+ Like: true,
+ Favorite: true,
+ Category: true,
+ comments: true
+ // _count: true
+ }
+ }
+ }
+ }
+ }
+ })
+
+ if (!user) {
+ return res.status(404).json({ message: 'User not found' })
+ }
+
+ const favoritePosts = user.Favorite.map((favorite) => favorite.post)
+
+ return res.status(200).json(favoritePosts)
+ } catch (error: any) {
+ console.error(error)
+ res.status(500).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/postsLikeByUser/index.ts b/src/pages/api/postsLikeByUser/index.ts
new file mode 100644
index 0000000..5e48df4
--- /dev/null
+++ b/src/pages/api/postsLikeByUser/index.ts
@@ -0,0 +1,45 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import prisma from '../../../utils/connect'
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ if (req.method !== 'GET') {
+ return res.status(405).json({ message: 'Method Not Allowed' })
+ }
+
+ const userEmail = req.query.userEmail as string
+ if (!userEmail) {
+ return res.status(400).json({ message: 'User email is required' })
+ }
+
+ try {
+ const user = await prisma.user.findUnique({
+ where: { email: userEmail },
+ include: {
+ Like: {
+ include: {
+ post: {
+ include: {
+ Like: true,
+ Category: true,
+ Favorite: true,
+ comments: true
+ // _count: true
+ }
+ }
+ }
+ }
+ }
+ })
+
+ if (!user) {
+ return res.status(404).json({ message: 'User not found' })
+ }
+
+ const favoritePosts = user.Like.map((favorite) => favorite.post)
+
+ return res.status(200).json(favoritePosts)
+ } catch (error: any) {
+ console.error(error)
+ res.status(500).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/share.ts b/src/pages/api/share.ts
new file mode 100644
index 0000000..dabf9f2
--- /dev/null
+++ b/src/pages/api/share.ts
@@ -0,0 +1,25 @@
+import { PrismaClient } from '@prisma/client'
+const prisma = new PrismaClient()
+
+export default async function handler(req, res) {
+ if (req.method !== 'POST') {
+ return res.status(405).json({ message: 'Method Not Allowed' })
+ }
+
+ const { postId, platform } = req.body
+
+ try {
+ const updatedPost = await prisma.post.update({
+ where: { id: postId },
+ data: {
+ whatsappShareCount: platform === 'whatsapp' ? { increment: 1 } : undefined,
+ twitterShareCount: platform === 'twitter' ? { increment: 1 } : undefined
+ }
+ })
+
+ return res.status(200).json({ message: 'Post shared successfully', post: updatedPost })
+ } catch (error) {
+ console.error('Error sharing post:', error)
+ return res.status(500).json({ message: 'Internal Server Error' })
+ }
+}
diff --git a/src/pages/api/stats/index.ts b/src/pages/api/stats/index.ts
new file mode 100644
index 0000000..46f7564
--- /dev/null
+++ b/src/pages/api/stats/index.ts
@@ -0,0 +1,22 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import { getAllStats } from '../../../../prisma/stats'
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ try {
+ const { method } = req
+
+ switch (method) {
+ case 'GET':
+ const stats = await getAllStats()
+ res.status(200).json(stats)
+ break
+
+ default:
+ res.status(405).json({ message: 'Method Not Allowed' })
+ break
+ }
+ } catch (error: any) {
+ console.error(error)
+ res.status(500).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/tag/index.ts b/src/pages/api/tag/index.ts
new file mode 100644
index 0000000..f671381
--- /dev/null
+++ b/src/pages/api/tag/index.ts
@@ -0,0 +1,49 @@
+// // pages/api/tags/[tagId].ts
+
+// import { NextApiRequest, NextApiResponse } from 'next'
+// import { createTag, deleteTag, getAllTags, getTagById, updateTag } from '../../../../prisma/tag'
+
+// export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+// try {
+// const { method, body, query } = req
+// const { tagId } = body as { tagId: string }
+
+// switch (method) {
+// case 'GET':
+// if (tagId) {
+// const tag = await getTagById(tagId)
+// if (tag) {
+// res.status(200).json(tag)
+// } else {
+// res.status(404).json({ message: 'Tag not found' })
+// }
+// } else {
+// const tags = await getAllTags()
+// res.status(200).json(tags)
+// }
+// break
+
+// case 'POST':
+// const newTag = await createTag(body)
+// res.status(201).json(newTag)
+// break
+
+// case 'PUT':
+// const updatedTag = await updateTag(body)
+// res.status(200).json(updatedTag)
+// break
+
+// case 'DELETE':
+// console.log(tagId, 'TAGID')
+// await deleteTag(tagId)
+// res.status(200).json({ message: 'Tag eliminado correctamente.' })
+// break
+// default:
+// res.status(405).json({ message: 'Method Not Allowed' })
+// break
+// }
+// } catch (error: any) {
+// console.error(error)
+// res.status(500).json({ message: 'Something went wrong', error: error.message })
+// }
+// }
diff --git a/src/pages/api/user/index.ts b/src/pages/api/user/index.ts
new file mode 100644
index 0000000..c29e480
--- /dev/null
+++ b/src/pages/api/user/index.ts
@@ -0,0 +1,65 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import { deleteUserByEmail, getUserByEmail, updateUserByEmail } from '../../../../prisma/user'
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ try {
+ switch (req.method) {
+ case 'GET': {
+ const { email } = req.query
+ if (!email) {
+ res.status(400).json({ message: 'User email is required' })
+ return
+ }
+ const user = await getUserByEmail(email as string)
+ if (user) {
+ res.status(200).json(user)
+ } else {
+ res.status(404).json({ message: 'User not found' })
+ }
+ break
+ }
+ case 'DELETE': {
+ const { email } = req.query
+ if (!email) {
+ res.status(400).json({ message: 'User email is required' })
+ return
+ }
+ const deletedUser = await deleteUserByEmail(email as string)
+ if (deletedUser) {
+ res.status(200).json({ message: 'User deleted successfully' })
+ } else {
+ res.status(404).json({ message: 'User not found' })
+ }
+ break
+ }
+ case 'PUT': {
+ const { email } = req.query
+ const newData = req.body
+ if (!email) {
+ res.status(400).json({ message: 'User email is required' })
+ return
+ }
+ const existingUser = await getUserByEmail(email as string)
+ if (!existingUser) {
+ res.status(404).json({ message: 'User not found' })
+ return
+ }
+ try {
+ const updatedUser = await updateUserByEmail(email as string, newData)
+ res.status(200).json({ message: 'User updated successfully', user: updatedUser })
+ } catch (error) {
+ console.error(`Error updating user with email ${email}:`, error)
+ res.status(500).json({ message: 'Unable to update user', error: error.message })
+ }
+ }
+
+ default:
+ res.status(405).json({ message: 'Method Not Allowed' })
+ break
+ }
+ } catch (error: any) {
+ console.error(error)
+ const status = error.message === 'Not Authenticated' ? 401 : 500
+ res.status(status).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/api/users/index.ts b/src/pages/api/users/index.ts
new file mode 100644
index 0000000..519d1fa
--- /dev/null
+++ b/src/pages/api/users/index.ts
@@ -0,0 +1,26 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import { deleteComment } from '../../../../prisma/comment'
+import { getAllUsers } from '../../../../prisma/user'
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ try {
+ switch (req.method) {
+ case 'GET': {
+ const users = await getAllUsers()
+ res.status(200).json(users)
+ break
+ }
+ case 'DELETE': {
+ await deleteComment(req.body.id)
+ res.status(200).json({ message: 'Comment deleted successfully ' })
+ }
+ default:
+ res.status(405).json({ message: 'Method Not Allowed' })
+ break
+ }
+ } catch (error: any) {
+ console.error(error)
+ const status = error.message === 'Not Authenticated' ? 401 : 500
+ res.status(status).json({ message: 'Something went wrong', error: error.message })
+ }
+}
diff --git a/src/pages/create.tsx b/src/pages/create.tsx
new file mode 100644
index 0000000..121cf5b
--- /dev/null
+++ b/src/pages/create.tsx
@@ -0,0 +1,19 @@
+import { Layout } from '@/components/layouts/Layout'
+import { CreatePostForm } from '@/components/molecules/CreatePostForm'
+import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
+
+export default function Create() {
+ return (
+
+
+
+
+
+ )
+}
+
+export const getStaticProps = async ({ locale }: { locale: string }) => ({
+ props: {
+ ...(await serverSideTranslations(locale, ['common']))
+ }
+})
diff --git a/src/pages/edit/[slug].tsx b/src/pages/edit/[slug].tsx
new file mode 100644
index 0000000..ecbcdf8
--- /dev/null
+++ b/src/pages/edit/[slug].tsx
@@ -0,0 +1,49 @@
+import { Layout } from '@/components/layouts/Layout'
+import { EditPost } from '@/components/molecules/EditPost'
+import { useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { Post } from '../../../type'
+
+export default function Edit() {
+ const router = useRouter()
+ const { status } = useSession()
+ const [dataPost, setDataPost] = useState()
+ // const { postData, updatePostData } = usePostContext()
+
+ const { slug } = router.query
+ const getData = async (slug: any) => {
+ try {
+ const response = await fetch(`/api/post/${slug}`, {
+ cache: 'no-store'
+ })
+ if (!response.ok) {
+ throw new Error('Failed')
+ }
+ const data = await response.json()
+ return data
+ } catch (error) {
+ console.error(error)
+ }
+ }
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const data = await getData(slug)
+ setDataPost(data)
+ } catch (error) {
+ console.log(error)
+ }
+ }
+
+ fetchData()
+ }, [slug])
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/src/pages/editUser/[userId].tsx b/src/pages/editUser/[userId].tsx
new file mode 100644
index 0000000..afae1b7
--- /dev/null
+++ b/src/pages/editUser/[userId].tsx
@@ -0,0 +1,42 @@
+import { Layout } from '@/components/layouts/Layout'
+import { EditUser } from '@/components/molecules/EditUser'
+import { useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { User } from '../../../type'
+
+export default function Edit() {
+ const router = useRouter()
+ const [user, setUser] = useState()
+ const { data: session } = useSession()
+
+ const getUser = async () => {
+ try {
+ const response = await fetch(`/api/user?email=${session?.user?.email}`)
+ const userData = await response.json()
+ !userData && router.push('/')
+ return userData
+ } catch (error: any) {
+ console.error('Error fetching user:', error.message)
+ }
+ }
+ useEffect(() => {
+ const fetcher = async () => {
+ try {
+ const data = await getUser()
+ setUser(data)
+ } catch (error) {
+ console.log(error)
+ }
+ }
+ fetcher()
+ }, [session])
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
new file mode 100644
index 0000000..18bddca
--- /dev/null
+++ b/src/pages/index.tsx
@@ -0,0 +1,69 @@
+import { Layout } from '@/components/layouts/Layout'
+import { CardList } from '@/components/molecules/CardList'
+import Stats from '@/components/molecules/Stats'
+import { SectionCategories } from '@/components/sections/SectionCategories'
+import { usePostContext } from '@/context/PostContext'
+import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+
+export default function Home() {
+ const router = useRouter()
+ const { page } = router.query ?? { page: 1 }
+ // const [selectedCategory, setSelectedCategory] = useState(cat || null)
+
+ const pageNumber = page ? page : 1
+ const selectedCategory = router.query.cat?.toString() || null
+ const [caterogySelect, setCategory] = useState('')
+ // const [selectedTags, setSelectedTags] = useState([])
+ const [count, setCount] = useState(0)
+ const { updatePostData } = usePostContext()
+
+ const getData = async (page: any, cat: any) => {
+ try {
+ const response = await fetch(`/api/posts?page=${page || 1}&cat=${cat || ''}`, {
+ cache: 'no-store'
+ })
+ if (!response.ok) {
+ throw new Error('Failed')
+ }
+
+ const result = await response.json()
+ updatePostData(result.posts)
+ setCount(result.count)
+ } catch (error) {
+ console.error(error)
+ }
+ }
+ useEffect(() => {
+ getData(page, caterogySelect)
+ }, [page, caterogySelect])
+
+ const handleCategoryClick = (categorySlug: string) => {
+ setCategory(categorySlug)
+ router.push({
+ pathname: '/',
+ query: { cat: categorySlug, page: 1 }
+ })
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export const getStaticProps = async ({ locale }: { locale: string }) => ({
+ props: {
+ ...(await serverSideTranslations(locale, ['common']))
+ }
+})
diff --git a/src/pages/login.tsx b/src/pages/login.tsx
new file mode 100644
index 0000000..206a0d5
--- /dev/null
+++ b/src/pages/login.tsx
@@ -0,0 +1,32 @@
+import { Layout } from '@/components/layouts/Layout'
+import FormLogin from '@/components/organism/FormLogin'
+import { useSession } from 'next-auth/react'
+import { useRouter } from 'next/router'
+import { SubmitHandler, useForm } from 'react-hook-form'
+
+type FormData = {
+ email: string
+ password: string
+}
+
+export default function Login() {
+ const {
+ register,
+ handleSubmit,
+ formState: { errors }
+ } = useForm()
+ const onSubmit: SubmitHandler = () => {}
+ const router = useRouter()
+ const { status } = useSession()
+
+ // if (status === 'loading') {
+ // return ...loading
+ // }
+ // status === 'authenticated' && router.push('/')
+
+ return (
+
+
+
+ )
+}
diff --git a/src/pages/perfil.tsx b/src/pages/perfil.tsx
new file mode 100644
index 0000000..5177b76
--- /dev/null
+++ b/src/pages/perfil.tsx
@@ -0,0 +1,227 @@
+import { Button } from '@/components/atoms/Button'
+import DisclosureIndividual from '@/components/atoms/DisclosureIndividual'
+import { Layout } from '@/components/layouts/Layout'
+import { CardPerfil } from '@/components/molecules/CardPerfil'
+import { Dialog } from '@headlessui/react'
+import { useSession } from 'next-auth/react'
+import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
+import Image from 'next/image'
+import Link from 'next/link'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { FaStar } from 'react-icons/fa'
+import { FcLike } from 'react-icons/fc'
+import { MdDelete, MdEdit } from 'react-icons/md'
+import { Post, User } from '../../type'
+
+export default function Perfil() {
+ const [dataUserCurrent, setDataUserCurrent] = useState()
+ const [dataPostLiked, setDataPostLiked] = useState()
+ const [dataPostFavorite, setDataFavorite] = useState()
+ const { data: session, status } = useSession()
+ const router = useRouter()
+ const [showModal, setShowModal] = useState(false)
+
+ useEffect(() => {
+ // Hago un get del usuario para traerme los datos de este.
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(`/api/user?email=${session?.user?.email}`)
+ const userData = await response.json()
+ setDataUserCurrent(userData)
+ !session && router.push('/')
+ } catch (error: any) {
+ console.error('Error fetching user:', error.message)
+ }
+ }
+
+ if (session?.user?.email) {
+ fetchUser()
+ }
+ }, [session, status])
+ useEffect(() => {
+ status === 'unauthenticated' && router.push('/')
+ }, [session, status])
+ const { name, image, email, Like, id, Favorite } = dataUserCurrent || {}
+
+ const handleDeleteUser = async () => {
+ try {
+ const response = await fetch(`/api/user?email=${session?.user?.email}`, {
+ method: 'DELETE'
+ })
+
+ if (response.ok) {
+ router.push('/')
+ } else {
+ const errorData = await response.json()
+ console.error('Error al eliminar usuario:', errorData)
+ }
+ } catch (error) {
+ console.error('Error al eliminar usuario:', error)
+ }
+ }
+
+ useEffect(() => {
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(`/api/postsLikeByUser?userEmail=${session?.user?.email}`)
+ const userData = await response.json()
+ setDataPostLiked(userData)
+ !session && router.push('/')
+ } catch (error: any) {
+ console.error('Error fetching user:', error.message)
+ }
+ }
+
+ if (session?.user?.email) {
+ fetchUser()
+ }
+ }, [session, status, router])
+
+ useEffect(() => {
+ const fetchUser = async () => {
+ try {
+ const response = await fetch(`/api/postsFavoriteByUser?userEmail=${session?.user?.email}`)
+ const userData = await response.json()
+ setDataFavorite(userData)
+ !session && router.push('/')
+ } catch (error: any) {
+ console.error('Error fetching user:', error.message)
+ }
+ }
+
+ if (session?.user?.email) {
+ fetchUser()
+ }
+ }, [session, status, router])
+
+ useEffect(() => {
+ status === 'unauthenticated' && router.push('/')
+ }, [session, status, router])
+
+ return (
+
+
+ {dataUserCurrent && (
+
+
+
+
+
+
+
+ Name:
+ {name}
+
+
+ Email:
+ {email}
+
+
+
Posts que te gustan:
+
{Like?.length}
+
+
+
+
Tus Post favoritos:
+
{Favorite?.length}
+
+
+
+
+
+
+ )}
+
+
setShowModal(false)}
+ className="fixed inset-0 flex items-center justify-center z-50"
+ >
+
+ ¿Estás seguro de borrar?
+
+
No puedes recuperar esta cuenta una vez borrada.
+
+ {
+ // router.back()
+ setShowModal(false)
+ }}
+ >
+ Cancelar
+
+ {
+ router.push('/login')
+ handleDeleteUser()
+ }}
+ >
+ Borrar
+
+
+
+
+
+
+
+
+ {dataPostLiked?.map((post: Post) => (
+
+ ))}
+
+
+
+
+ {dataPostFavorite?.map((post: Post) => (
+
+ ))}
+
+
+
+
+
¿Quieres eliminar la cuenta?
+
setShowModal(true)}>
+ Eliminar
+
+
+
+
+
+ )
+}
+
+export const getStaticProps = async ({ locale }: { locale: string }) => ({
+ props: {
+ ...(await serverSideTranslations(locale, ['common']))
+ }
+})
diff --git a/src/pages/post/[slug].tsx b/src/pages/post/[slug].tsx
new file mode 100644
index 0000000..14e5618
--- /dev/null
+++ b/src/pages/post/[slug].tsx
@@ -0,0 +1,399 @@
+import { DropDownShare } from '@/components/atoms/DropDownShare'
+import Modal from '@/components/atoms/Modal'
+import { Layout } from '@/components/layouts/Layout'
+import Comment from '@/components/molecules/Coment'
+import CommentWrite from '@/components/molecules/CommentWrite'
+import { usePostContext } from '@/context/PostContext'
+import { useSession } from 'next-auth/react'
+import Image from 'next/image'
+import Link from 'next/link'
+import { useRouter } from 'next/router'
+import { useEffect, useState } from 'react'
+import { CgLoadbarSound } from 'react-icons/cg'
+import { FaRegComment, FaRegStar, FaStar } from 'react-icons/fa'
+import { FcLike } from 'react-icons/fc'
+import { FiExternalLink, FiHeart } from 'react-icons/fi'
+import { MdDelete, MdEdit } from 'react-icons/md'
+import { TiArrowBack } from 'react-icons/ti'
+import { User } from '../../../type'
+
+const getData = async (slug: any) => {
+ try {
+ const response = await fetch(`/api/post/${slug}`, {
+ cache: 'no-store'
+ })
+ if (!response.ok) {
+ throw new Error('Failed')
+ }
+ const data = await response.json()
+ return data
+ } catch (error) {
+ console.error(error)
+ }
+}
+const Posts = () => {
+ const router = useRouter()
+ const { status } = useSession()
+ const { slug } = router.query
+ const [users, setUsers] = useState()
+ const { data: session } = useSession()
+ const { postData, updatePostData } = usePostContext()
+ const [isLike, setIsLike] = useState()
+ const [likesCount, setLikesCount] = useState(postData?.Like?.length || 0)
+ const [showModal, setShowModal] = useState(false)
+ const [showModalNeedLogin, setShowModalNeedLogin] = useState(false)
+ const [isFavorite, setIsFavorite] = useState()
+ const [favoriteCount, setFavoriteCount] = useState(postData?.Favorite?.length || 0)
+
+ useEffect(() => {
+ if (session && postData?.Like?.some((like) => like?.userEmail === session?.user?.email)) {
+ setIsLike(true)
+ } else {
+ setIsLike(false)
+ }
+ }, [postData?.Like, session, postData])
+
+ useEffect(() => {
+ if (session && postData?.Favorite?.some((fav) => fav?.userEmail === session?.user?.email)) {
+ setIsFavorite(true)
+ } else {
+ setIsFavorite(false)
+ }
+ }, [postData?.Favorite, session])
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const data = await getData(slug)
+ updatePostData(data)
+ setLikesCount(data?.Like?.length || 0)
+ setFavoriteCount(data?.Favorite?.length || 0)
+ } catch (error) {
+ console.log(error)
+ }
+ }
+
+ fetchData()
+ }, [slug])
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const response = await fetch(`/api/users`, {
+ method: 'GET',
+ headers: { 'Content-Type': 'application/json' }
+ })
+ if (!response.ok) {
+ throw new Error('Failed to fetch data')
+ return
+ }
+ const data = await response.json()
+ data && setUsers(data)
+ } catch (error) {}
+ }
+ fetchData()
+ }, [])
+ const deletePost = async (slug: string) => {
+ try {
+ const response = await fetch(`/api/post/${slug}`, {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ })
+
+ if (!response.ok) {
+ throw new Error('Failed to create comment')
+ }
+ router.push('/')
+ } catch (error) {
+ console.error(error)
+ }
+ }
+ const handleAddLike = async () => {
+ if (!session) {
+ setShowModalNeedLogin(true)
+ return
+ }
+ const response = await fetch('/api/like', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session?.user.email,
+ postId: postData.id,
+ session: session
+ })
+ })
+ const data = await response.json()
+ if (response.ok) {
+ data && setIsLike(true)
+ setLikesCount((prevCount) => prevCount + 1)
+ } else {
+ console.error('Error al dar like:', data.error)
+ }
+ }
+ const handleDeleteLike = async () => {
+ if (!session) {
+ setShowModalNeedLogin(true)
+ return
+ }
+ const response = await fetch('/api/like', {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: postData.id,
+ session: session
+ })
+ })
+
+ const data = await response.json()
+
+ if (response.ok) {
+ setIsLike(false)
+ setLikesCount((prevCount) => Math.max(0, prevCount - 1))
+ } else {
+ console.error('Error al quitar like:', data.error)
+ }
+ }
+ const handleAddFavorite = async () => {
+ if (!session) {
+ setShowModalNeedLogin(true)
+ return
+ }
+ const response = await fetch(`/api/favorite`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: postData.id,
+ session: session
+ })
+ })
+ const data = await response.json()
+ if (response.ok) {
+ data && setIsFavorite(true)
+ setFavoriteCount((prevCount) => prevCount + 1)
+ } else {
+ console.error('Error al dar like:', data.error)
+ }
+ }
+ const handleDeleteFavorite = async () => {
+ if (!session) {
+ setShowModalNeedLogin(true)
+ return
+ }
+ const response = await fetch('/api/favorite', {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ email: session.user.email,
+ postId: postData.id,
+ session: session
+ })
+ })
+
+ const data = await response.json()
+
+ if (response.ok) {
+ setIsFavorite(false)
+ setFavoriteCount((prevCount) => Math.max(0, prevCount - 1))
+ } else {
+ console.error('Error al quitar like:', data.error)
+ }
+ }
+
+ const userCurrent = users && users.find((user) => user.email === session?.user?.email)
+ return (
+
+
+ {postData ? (
+
+
+
+ {postData.Category && postData.Category.img && (
+
+ )}
+
+
+
+
+
{postData?.title}
+
{postData?.description}
+
+
+
+ {/*
+
+
+
+
Acceso al recurso
+
*/}
+
+
+
{
+ isLike ? handleDeleteLike() : handleAddLike()
+ }}
+ >
+ {isLike ? (
+
+ ) : (
+
+ )}
+
+ {/*
*/}
+
+
+ {likesCount}
+
+
+
+
+
{
+ isFavorite ? handleDeleteFavorite() : handleAddFavorite()
+ }}
+ >
+ {isFavorite ? (
+
+ ) : (
+
+ )}
+
+ {favoriteCount}
+
+
+
+
+
+
+
+
+ {postData?.comments?.length}
+
+
+
+
+
+
+
+
+ {postData?.twitterShareCount + postData?.whatsappShareCount}
+
+
+
+
+
+ {postData?.views}
+ {' '}
+
+
+
+
+
+
+
+
+ ) : (
+
Cargando...
+ )}
+
+
router.back()}
+ >
+
+
+ {userCurrent && userCurrent.isAdmin && (
+
+
+
+
+
+
+
{
+ setShowModal(true)
+ }}
+ >
+
+
+
+ )}
+
+ {/*MODAL PARA BORRAR */}
+
deletePost(postData?.slug)}
+ functionFalse={() => setShowModal(false)}
+ />
+ {/*MODAL PARA AVISAR DE NECESIDAD DE ESTAR LOGEADO */}
+ router.push('/login')}
+ functionFalse={() => setShowModalNeedLogin(false)}
+ />
+
+ {status === 'authenticated' ? (
+ <>
+
+
+ >
+ ) : (
+
+
+ You need to be logged in to post or view comments.
+
+
+ )}
+
+
+ )
+}
+export default Posts
diff --git a/src/pages/register.tsx b/src/pages/register.tsx
new file mode 100644
index 0000000..d619314
--- /dev/null
+++ b/src/pages/register.tsx
@@ -0,0 +1,104 @@
+import { Button } from '@/components/atoms/Button'
+import { Layout } from '@/components/layouts/Layout'
+import { yupResolver } from '@hookform/resolvers/yup'
+import { signIn, useSession } from 'next-auth/react'
+import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
+import { useRouter } from 'next/router'
+import { SubmitHandler, useForm } from 'react-hook-form'
+
+import * as yup from 'yup'
+
+const schema = yup.object({
+ userName: yup.string().required('User name is required'),
+ email: yup.string().required('Email is required'),
+ password: yup.string().min(4, 'Password must be at least 4 characters').max(20).required('Password is required'),
+ confirmPassword: yup
+ .string()
+ .oneOf([yup.ref('password')], 'Passwords must match')
+ .required('Confirm Password is required')
+})
+
+type FormData = {
+ userName: string
+ email: string
+ password: string
+ confirmPassword: string
+}
+export default function Register() {
+ const {
+ register,
+ handleSubmit,
+ formState: { errors }
+ /*@ts-ignore*/
+ } = useForm({ resolver: yupResolver(schema) })
+ const onSubmit: SubmitHandler = (data) => {
+ console.log(errors)
+ }
+ const router = useRouter()
+ const { data, status } = useSession()
+ if (status === 'loading') {
+ return ...loading
+ }
+ status === 'authenticated' && router.push('/')
+ return (
+
+
+
Register
+
Estamos en proceso de añadir mas maneras de registrarse y logearse...
+ {/*
+
+ User name
+
+ {errors.userName && {errors.userName.message} }
+ Email
+
+ {errors.email && {errors.email.message} }
+ Password
+
+ {errors.password && {errors.password.message} }
+ Repeat Password
+
+ {errors.confirmPassword && {errors.confirmPassword.message} }
+
+
+ Send
+
+ */}
+ {/*
+
+ or
+
+ {' '} */}
+
+
+ signIn('github')}
+ >
+ Sign in with Github
+
+
+
+ signIn('google')}
+ >
+ Sign in with Google
+
+
+
+
+
+ )
+}
+
+export const getStaticProps = async ({ locale }: { locale: string }) => ({
+ props: {
+ ...(await serverSideTranslations(locale, ['common']))
+ }
+})
diff --git a/src/providers/AuthProvider.jsx b/src/providers/AuthProvider.jsx
new file mode 100644
index 0000000..5330c59
--- /dev/null
+++ b/src/providers/AuthProvider.jsx
@@ -0,0 +1,7 @@
+import { SessionProvider } from 'next-auth/react'
+
+const AuthProvider = ({ children }) => {
+ return {children}
+}
+
+export default AuthProvider
diff --git a/src/styles/buttons.scss b/src/styles/buttons.scss
new file mode 100644
index 0000000..0168183
--- /dev/null
+++ b/src/styles/buttons.scss
@@ -0,0 +1,13 @@
+button {
+ @apply font-medium py-2 px-4 rounded-md flex justify-center w-full;
+ &.btn-alternate {
+ @apply bg-transparent;
+ }
+ &.btn-big {
+ @apply text-lg py-2 px-4;
+ }
+ &:disabled {
+ cursor: not-allowed;
+ opacity: 0.5;
+ }
+}
\ No newline at end of file
diff --git a/src/styles/fonts.scss b/src/styles/fonts.scss
new file mode 100644
index 0000000..45f1d7c
--- /dev/null
+++ b/src/styles/fonts.scss
@@ -0,0 +1,6 @@
+h1 { @apply text-5xl;}
+h2 { @apply text-4xl;}
+h3 { @apply text-3xl;}
+h4 { @apply text-2xl;}
+h5 { @apply text-xl;}
+h6 { @apply text-lg;}
diff --git a/src/styles/globals.scss b/src/styles/globals.scss
new file mode 100644
index 0000000..379beaf
--- /dev/null
+++ b/src/styles/globals.scss
@@ -0,0 +1,20 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+@import 'fonts.scss';
+@import 'buttons.scss';
+
+body {
+ // background-color: #D1D5DB;
+}
+@layer utilities {
+ /* Hide scrollbar for Chrome, Safari and Opera */
+ .no-scrollbar::-webkit-scrollbar {
+ display: none;
+ }
+ /* Hide scrollbar for IE, Edge and Firefox */
+ .no-scrollbar {
+ -ms-overflow-style: none; /* IE and Edge */
+ scrollbar-width: none; /* Firefox */
+}
+}
\ No newline at end of file
diff --git a/src/utils/auth.js b/src/utils/auth.js
new file mode 100644
index 0000000..c065e67
--- /dev/null
+++ b/src/utils/auth.js
@@ -0,0 +1,23 @@
+import { PrismaAdapter } from '@auth/prisma-adapter'
+// import { Prisma } from '@prisma/client'
+import GithubProvider from 'next-auth/providers/github'
+import GoogleProvider from 'next-auth/providers/google'
+import { getServerSession } from 'next-auth/react'
+import prisma from './connect'
+
+export const authOptions = {
+ adapter: PrismaAdapter(prisma),
+ providers: [
+ GoogleProvider({
+ clientId: process.env.GOOGLE_ID,
+ clientSecret: process.env.GOOGLE_SECRET
+ }),
+ GithubProvider({
+ clientId: process.env.GITHUB_ID,
+ clientSecret: process.env.GITHUB_SECRET
+ })
+ ],
+ secret: process.env.NEXTAUTH_SECRET
+}
+
+export const getAuthSession = () => getServerSession(authOptions)
diff --git a/src/utils/connect.ts b/src/utils/connect.ts
new file mode 100644
index 0000000..6224d58
--- /dev/null
+++ b/src/utils/connect.ts
@@ -0,0 +1,15 @@
+import { PrismaClient } from '@prisma/client'
+
+const prismaClientSingleton = () => {
+ return new PrismaClient()
+}
+
+declare global {
+ var prisma: undefined | ReturnType
+}
+
+const prisma = globalThis.prisma ?? prismaClientSingleton()
+
+export default prisma
+
+if (process.env.NODE_ENV === 'production') globalThis.prisma = prisma
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 0000000..6753f5c
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,24 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/components/**/*.{js,ts,jsx,tsx,mdx}',
+ './src/app/**/*.{js,ts,jsx,tsx,mdx}'
+ ],
+ theme: {
+ extend: {
+ colors: {
+ primary: '#90b9ff',
+ secondary: { 400: '#4087ff', 800: '#087BEA' }
+ },
+ backgroundImage: {
+ // 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
+ // 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'
+ },
+ screens: {
+ mobile: '350px'
+ }
+ }
+ },
+ plugins: []
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..addc921
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "src/pages/api/categories/routes.ts", "src/pages/api/route.js", "src/utils/auth.js", "src/context/PostContext.js", ],
+ "exclude": ["node_modules"]
+}
diff --git a/type.ts b/type.ts
new file mode 100644
index 0000000..5470478
--- /dev/null
+++ b/type.ts
@@ -0,0 +1,126 @@
+export interface Post {
+ id: string
+ slug: string
+ title: string
+ description: string
+ img?: string
+ views?: string
+ catSlug?: string
+ userEmail: string
+ comments?: Comment[]
+ Category?: Category
+ Like?: Like[]
+ url?: string
+ twitterShareCount?: number
+ whatsappShareCount?: number
+ createdAt?: string
+ updatedAt?: string
+ Favorite?: Favorite[]
+ // Tags?: Tag[]
+}
+
+export interface Category {
+ id: string
+ slug: string
+ title: string
+ img?: string
+ color?: string
+ Posts?: Post[]
+ Comment?: Comment
+}
+
+export interface Like {
+ id: string
+ postId: string
+ post: Post
+ userEmail: string
+ user: User
+ createdAt: string
+ updatedAt: string
+}
+
+export interface Favorite {
+ id: string
+ postId: string
+ post: Post
+ userEmail: string
+ user: User
+ createdAt: string
+ updatedAt: string
+}
+
+export interface Comment {
+ id: string
+ createdAt: string
+ description: string
+ userEmail: string
+ user: User
+ postSlug: string
+ post: Post
+ Category?: Category
+ categoryId?: string
+}
+
+export interface User {
+ id: string
+ name?: string
+ email: string
+ emailVerified?: string
+ image?: string
+ accounts?: Account[]
+ sessions?: Session[]
+ Post?: Post[]
+ Like?: Like[]
+ Comment?: Comment[]
+ isAdmin: boolean
+ Favorite?: Favorite[]
+}
+
+export interface Account {
+ id: string
+ userId: string
+ type: string
+ provider: string
+ providerAccountId: string
+ refresh_token?: string
+ access_token?: string
+ expires_at?: number
+ token_type?: string
+ scope?: string
+ id_token?: string
+ session_state?: string
+ user: User
+}
+
+export interface Session {
+ id: string
+ sessionToken: string
+ userId: string
+ expires: string
+ user: User
+}
+
+export interface VerificationToken {
+ identifier: string
+ token: string
+ expires: string
+}
+
+// export type Tag = {
+// id: string
+// name: string
+// color: string
+// slug: string
+// }
+
+export type Stats = {
+ totalPosts: number
+ totalUsers: number
+ totalViews: {
+ views: number
+ }
+ totalShares: {
+ twitterShareCount: number
+ whatsappShareCount: number
+ }
+}
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..f906284
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,2823 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@aashutoshrathi/word-wrap@^1.2.3":
+ version "1.2.6"
+ resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz"
+ integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==
+
+"@alloc/quick-lru@^5.2.0":
+ version "5.2.0"
+ resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz"
+ integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
+
+"@auth/core@0.19.0":
+ version "0.19.0"
+ resolved "https://registry.npmjs.org/@auth/core/-/core-0.19.0.tgz"
+ integrity sha512-BkFg2SoNftMN6A2Sn2g1lLFLTO74qMtFKsZmSCEF9d1csqSaEXIv50k6OrfniODWi5tZP8bcfSxGodv75khlOA==
+ dependencies:
+ "@panva/hkdf" "^1.1.1"
+ "@types/cookie" "0.6.0"
+ cookie "0.6.0"
+ jose "^5.1.3"
+ oauth4webapi "^2.4.0"
+ preact "10.11.3"
+ preact-render-to-string "5.2.3"
+
+"@auth/prisma-adapter@^1.0.12":
+ version "1.0.12"
+ resolved "https://registry.npmjs.org/@auth/prisma-adapter/-/prisma-adapter-1.0.12.tgz"
+ integrity sha512-vLsbIgvpJUVpQLCDvSG16bg/uisf6y2TYHzgR1zriwMu3WdrhuG2RxrypNHNdhJZoGW0mL57QEvGVh+C9AtsRA==
+ dependencies:
+ "@auth/core" "0.19.0"
+
+"@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2":
+ version "7.23.6"
+ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz"
+ integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
+"@eslint-community/eslint-utils@^4.2.0":
+ version "4.4.0"
+ resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
+ integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
+ dependencies:
+ eslint-visitor-keys "^3.3.0"
+
+"@eslint-community/regexpp@^4.4.0":
+ version "4.5.1"
+ resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz"
+ integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==
+
+"@eslint/eslintrc@^2.1.0":
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz"
+ integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==
+ dependencies:
+ ajv "^6.12.4"
+ debug "^4.3.2"
+ espree "^9.6.0"
+ globals "^13.19.0"
+ ignore "^5.2.0"
+ import-fresh "^3.2.1"
+ js-yaml "^4.1.0"
+ minimatch "^3.1.2"
+ strip-json-comments "^3.1.1"
+
+"@eslint/js@8.44.0":
+ version "8.44.0"
+ resolved "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz"
+ integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==
+
+"@headlessui/react@^1.7.18":
+ version "1.7.18"
+ resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.18.tgz#30af4634d2215b2ca1aa29d07f33d02bea82d9d7"
+ integrity sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ==
+ dependencies:
+ "@tanstack/react-virtual" "^3.0.0-beta.60"
+ client-only "^0.0.1"
+
+"@hookform/resolvers@^3.3.3":
+ version "3.3.3"
+ resolved "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.3.tgz"
+ integrity sha512-bOMxKkSD3zWcS11TKoUQ8O0ZqKslFohvUsPKSrdCHiuEuMjRo/u3cq9YRJD/+xtNGYup++XD2LkjhegP5XENiw==
+
+"@humanwhocodes/config-array@^0.11.10":
+ version "0.11.10"
+ resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz"
+ integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==
+ dependencies:
+ "@humanwhocodes/object-schema" "^1.2.1"
+ debug "^4.1.1"
+ minimatch "^3.0.5"
+
+"@humanwhocodes/module-importer@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz"
+ integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
+
+"@humanwhocodes/object-schema@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz"
+ integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
+
+"@jridgewell/gen-mapping@^0.3.2":
+ version "0.3.3"
+ resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz"
+ integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==
+ dependencies:
+ "@jridgewell/set-array" "^1.0.1"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@jridgewell/resolve-uri@3.1.0":
+ version "3.1.0"
+ resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz"
+ integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
+
+"@jridgewell/set-array@^1.0.1":
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz"
+ integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
+
+"@jridgewell/sourcemap-codec@1.4.14":
+ version "1.4.14"
+ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz"
+ integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
+
+"@jridgewell/sourcemap-codec@^1.4.10":
+ version "1.4.15"
+ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
+ integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
+
+"@jridgewell/trace-mapping@^0.3.9":
+ version "0.3.18"
+ resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz"
+ integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==
+ dependencies:
+ "@jridgewell/resolve-uri" "3.1.0"
+ "@jridgewell/sourcemap-codec" "1.4.14"
+
+"@next/env@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.npmjs.org/@next/env/-/env-13.4.9.tgz"
+ integrity sha512-vuDRK05BOKfmoBYLNi2cujG2jrYbEod/ubSSyqgmEx9n/W3eZaJQdRNhTfumO+qmq/QTzLurW487n/PM/fHOkw==
+
+"@next/eslint-plugin-next@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.9.tgz"
+ integrity sha512-nDtGpa992tNyAkT/KmSMy7QkHfNZmGCBYhHtafU97DubqxzNdvLsqRtliQ4FU04CysRCtvP2hg8rRC1sAKUTUA==
+ dependencies:
+ glob "7.1.7"
+
+"@next/swc-darwin-arm64@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.9.tgz#0ed408d444bbc6b0a20f3506a9b4222684585677"
+ integrity sha512-TVzGHpZoVBk3iDsTOQA/R6MGmFp0+17SWXMEWd6zG30AfuELmSSMe2SdPqxwXU0gbpWkJL1KgfLzy5ReN0crqQ==
+
+"@next/swc-darwin-x64@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.9.tgz#a08fccdee68201522fe6618ec81f832084b222f8"
+ integrity sha512-aSfF1fhv28N2e7vrDZ6zOQ+IIthocfaxuMWGReB5GDriF0caTqtHttAvzOMgJgXQtQx6XhyaJMozLTSEXeNN+A==
+
+"@next/swc-linux-arm64-gnu@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.9.tgz#1798c2341bb841e96521433eed00892fb24abbd1"
+ integrity sha512-JhKoX5ECzYoTVyIy/7KykeO4Z2lVKq7HGQqvAH+Ip9UFn1MOJkOnkPRB7v4nmzqAoY+Je05Aj5wNABR1N18DMg==
+
+"@next/swc-linux-arm64-musl@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.9.tgz#cee04c51610eddd3638ce2499205083656531ea0"
+ integrity sha512-OOn6zZBIVkm/4j5gkPdGn4yqQt+gmXaLaSjRSO434WplV8vo2YaBNbSHaTM9wJpZTHVDYyjzuIYVEzy9/5RVZw==
+
+"@next/swc-linux-x64-gnu@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.9.tgz#1932d0367916adbc6844b244cda1d4182bd11f7a"
+ integrity sha512-iA+fJXFPpW0SwGmx/pivVU+2t4zQHNOOAr5T378PfxPHY6JtjV6/0s1vlAJUdIHeVpX98CLp9k5VuKgxiRHUpg==
+
+"@next/swc-linux-x64-musl@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.9.tgz#a66aa8c1383b16299b72482f6360facd5cde3c7a"
+ integrity sha512-rlNf2WUtMM+GAQrZ9gMNdSapkVi3koSW3a+dmBVp42lfugWVvnyzca/xJlN48/7AGx8qu62WyO0ya1ikgOxh6A==
+
+"@next/swc-win32-arm64-msvc@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.9.tgz#39482ee856c867177a612a30b6861c75e0736a4a"
+ integrity sha512-5T9ybSugXP77nw03vlgKZxD99AFTHaX8eT1ayKYYnGO9nmYhJjRPxcjU5FyYI+TdkQgEpIcH7p/guPLPR0EbKA==
+
+"@next/swc-win32-ia32-msvc@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.9.tgz#29db85e34b597ade1a918235d16a760a9213c190"
+ integrity sha512-ojZTCt1lP2ucgpoiFgrFj07uq4CZsq4crVXpLGgQfoFq00jPKRPgesuGPaz8lg1yLfvafkU3Jd1i8snKwYR3LA==
+
+"@next/swc-win32-x64-msvc@13.4.9":
+ version "13.4.9"
+ resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.9.tgz"
+ integrity sha512-QbT03FXRNdpuL+e9pLnu+XajZdm/TtIXVYY4lA9t+9l0fLZbHXDYEKitAqxrOj37o3Vx5ufxiRAniaIebYDCgw==
+
+"@nodelib/fs.scandir@2.1.5":
+ version "2.1.5"
+ resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
+ integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
+ dependencies:
+ "@nodelib/fs.stat" "2.0.5"
+ run-parallel "^1.1.9"
+
+"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
+ version "2.0.5"
+ resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
+ integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
+
+"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8":
+ version "1.2.8"
+ resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz"
+ integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
+ dependencies:
+ "@nodelib/fs.scandir" "2.1.5"
+ fastq "^1.6.0"
+
+"@panva/hkdf@^1.0.2", "@panva/hkdf@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz"
+ integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==
+
+"@pkgr/utils@^2.3.1":
+ version "2.4.2"
+ resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz"
+ integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==
+ dependencies:
+ cross-spawn "^7.0.3"
+ fast-glob "^3.3.0"
+ is-glob "^4.0.3"
+ open "^9.1.0"
+ picocolors "^1.0.0"
+ tslib "^2.6.0"
+
+"@prisma/client@^5.8.1":
+ version "5.8.1"
+ resolved "https://registry.npmjs.org/@prisma/client/-/client-5.8.1.tgz"
+ integrity sha512-xQtMPfbIwLlbm0VVIVQY2yqQVOxPwRQhvIp7Z3m2900g1bu/zRHKhYZJQWELqmjl6d8YwBy0K2NvMqh47v1ubw==
+
+"@prisma/debug@5.8.1":
+ version "5.8.1"
+ resolved "https://registry.npmjs.org/@prisma/debug/-/debug-5.8.1.tgz"
+ integrity sha512-tjuw7eA0Us3T42jx9AmAgL58rzwzpFGYc3R7Y4Ip75EBYrKMBA1YihuWMcBC92ILmjlQ/u3p8VxcIE0hr+fZfg==
+
+"@prisma/engines-version@5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2":
+ version "5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2"
+ resolved "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2.tgz"
+ integrity sha512-f5C3JM3l9yhGr3cr4FMqWloFaSCpNpMi58Om22rjD2DOz3owci2mFdFXMgnAGazFPKrCbbEhcxdsRfspEYRoFQ==
+
+"@prisma/engines@5.8.1":
+ version "5.8.1"
+ resolved "https://registry.npmjs.org/@prisma/engines/-/engines-5.8.1.tgz"
+ integrity sha512-TJgYLRrZr56uhqcXO4GmP5be+zjCIHtLDK20Cnfg+o9d905hsN065QOL+3Z0zQAy6YD31Ol4u2kzSfRmbJv/uA==
+ dependencies:
+ "@prisma/debug" "5.8.1"
+ "@prisma/engines-version" "5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2"
+ "@prisma/fetch-engine" "5.8.1"
+ "@prisma/get-platform" "5.8.1"
+
+"@prisma/fetch-engine@5.8.1":
+ version "5.8.1"
+ resolved "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.8.1.tgz"
+ integrity sha512-+bgjjoSFa6uYEbAPlklfoVSStOEfcpheOjoBoNsNNSQdSzcwE2nM4Q0prun0+P8/0sCHo18JZ9xqa8gObvgOUw==
+ dependencies:
+ "@prisma/debug" "5.8.1"
+ "@prisma/engines-version" "5.8.1-1.78caf6feeaed953168c64e15a249c3e9a033ebe2"
+ "@prisma/get-platform" "5.8.1"
+
+"@prisma/get-platform@5.8.1":
+ version "5.8.1"
+ resolved "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.8.1.tgz"
+ integrity sha512-wnA+6HTFcY+tkykMokix9GiAkaauPC5W/gg0O5JB0J8tCTNWrqpnQ7AsaGRfkYUbeOIioh6woDjQrGTTRf1Zag==
+ dependencies:
+ "@prisma/debug" "5.8.1"
+
+"@rushstack/eslint-patch@^1.1.3":
+ version "1.3.2"
+ resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz"
+ integrity sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==
+
+"@swc/helpers@0.5.1":
+ version "0.5.1"
+ resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz"
+ integrity sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==
+ dependencies:
+ tslib "^2.4.0"
+
+"@tanstack/react-virtual@^3.0.0-beta.60":
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.0.2.tgz#e5a979f2585d3f583944840319cddf2c2d1b0e51"
+ integrity sha512-9XbRLPKgnhMwwmuQMnJMv+5a9sitGNCSEtf/AZXzmJdesYk7XsjYHaEDny+IrJzvPNwZliIIDwCRiaUqR3zzCA==
+ dependencies:
+ "@tanstack/virtual-core" "3.0.0"
+
+"@tanstack/virtual-core@3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.0.0.tgz#637bee36f0cabf96a1d436887c90f138a7e9378b"
+ integrity sha512-SYXOBTjJb05rXa2vl55TTwO40A6wKu0R5i1qQwhJYNDIqaIGF7D0HsLw+pJAyi2OvntlEIVusx3xtbbgSUi6zg==
+
+"@types/cookie@0.6.0":
+ version "0.6.0"
+ resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz"
+ integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==
+
+"@types/hoist-non-react-statics@^3.3.1":
+ version "3.3.5"
+ resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz"
+ integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
+ dependencies:
+ "@types/react" "*"
+ hoist-non-react-statics "^3.3.0"
+
+"@types/json5@^0.0.29":
+ version "0.0.29"
+ resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
+ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
+
+"@types/node@20.4.1":
+ version "20.4.1"
+ resolved "https://registry.npmjs.org/@types/node/-/node-20.4.1.tgz"
+ integrity sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg==
+
+"@types/prop-types@*":
+ version "15.7.5"
+ resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
+ integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
+
+"@types/react-dom@18.2.6":
+ version "18.2.6"
+ resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.6.tgz"
+ integrity sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react@*", "@types/react@18.2.14":
+ version "18.2.14"
+ resolved "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz"
+ integrity sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
+"@types/scheduler@*":
+ version "0.16.3"
+ resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz"
+ integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==
+
+"@typescript-eslint/parser@^5.42.0":
+ version "5.62.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz"
+ integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==
+ dependencies:
+ "@typescript-eslint/scope-manager" "5.62.0"
+ "@typescript-eslint/types" "5.62.0"
+ "@typescript-eslint/typescript-estree" "5.62.0"
+ debug "^4.3.4"
+
+"@typescript-eslint/scope-manager@5.62.0":
+ version "5.62.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz"
+ integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==
+ dependencies:
+ "@typescript-eslint/types" "5.62.0"
+ "@typescript-eslint/visitor-keys" "5.62.0"
+
+"@typescript-eslint/types@5.62.0":
+ version "5.62.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz"
+ integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==
+
+"@typescript-eslint/typescript-estree@5.62.0":
+ version "5.62.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz"
+ integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==
+ dependencies:
+ "@typescript-eslint/types" "5.62.0"
+ "@typescript-eslint/visitor-keys" "5.62.0"
+ debug "^4.3.4"
+ globby "^11.1.0"
+ is-glob "^4.0.3"
+ semver "^7.3.7"
+ tsutils "^3.21.0"
+
+"@typescript-eslint/visitor-keys@5.62.0":
+ version "5.62.0"
+ resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz"
+ integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==
+ dependencies:
+ "@typescript-eslint/types" "5.62.0"
+ eslint-visitor-keys "^3.3.0"
+
+acorn-jsx@^5.3.2:
+ version "5.3.2"
+ resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
+ integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
+
+acorn@^8.9.0:
+ version "8.10.0"
+ resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz"
+ integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
+
+ajv@^6.10.0, ajv@^6.12.4:
+ version "6.12.6"
+ resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
+ integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
+ dependencies:
+ fast-deep-equal "^3.1.1"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.4.1"
+ uri-js "^4.2.2"
+
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-styles@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
+any-promise@^1.0.0:
+ version "1.3.0"
+ resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz"
+ integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==
+
+anymatch@~3.1.2:
+ version "3.1.3"
+ resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz"
+ integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
+ dependencies:
+ normalize-path "^3.0.0"
+ picomatch "^2.0.4"
+
+arg@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz"
+ integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
+
+argparse@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
+ integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+
+aria-query@^5.1.3:
+ version "5.3.0"
+ resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz"
+ integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==
+ dependencies:
+ dequal "^2.0.3"
+
+array-buffer-byte-length@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz"
+ integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==
+ dependencies:
+ call-bind "^1.0.2"
+ is-array-buffer "^3.0.1"
+
+array-includes@^3.1.6:
+ version "3.1.6"
+ resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz"
+ integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ get-intrinsic "^1.1.3"
+ is-string "^1.0.7"
+
+array-union@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz"
+ integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+
+array.prototype.flat@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz"
+ integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ es-shim-unscopables "^1.0.0"
+
+array.prototype.flatmap@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz"
+ integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ es-shim-unscopables "^1.0.0"
+
+array.prototype.tosorted@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz"
+ integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ es-shim-unscopables "^1.0.0"
+ get-intrinsic "^1.1.3"
+
+ast-types-flow@^0.0.7:
+ version "0.0.7"
+ resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz"
+ integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==
+
+autoprefixer@10.4.14:
+ version "10.4.14"
+ resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz"
+ integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==
+ dependencies:
+ browserslist "^4.21.5"
+ caniuse-lite "^1.0.30001464"
+ fraction.js "^4.2.0"
+ normalize-range "^0.1.2"
+ picocolors "^1.0.0"
+ postcss-value-parser "^4.2.0"
+
+available-typed-arrays@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz"
+ integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
+
+axe-core@^4.6.2:
+ version "4.7.2"
+ resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz"
+ integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==
+
+axobject-query@^3.1.1:
+ version "3.2.1"
+ resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz"
+ integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==
+ dependencies:
+ dequal "^2.0.3"
+
+balanced-match@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
+ integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+big-integer@^1.6.44:
+ version "1.6.51"
+ resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz"
+ integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==
+
+binary-extensions@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
+ integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
+
+bplist-parser@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz"
+ integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==
+ dependencies:
+ big-integer "^1.6.44"
+
+brace-expansion@^1.1.7:
+ version "1.1.11"
+ resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
+ integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
+braces@^3.0.2, braces@~3.0.2:
+ version "3.0.2"
+ resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
+ integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+ dependencies:
+ fill-range "^7.0.1"
+
+browserslist@^4.21.5:
+ version "4.21.9"
+ resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz"
+ integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==
+ dependencies:
+ caniuse-lite "^1.0.30001503"
+ electron-to-chromium "^1.4.431"
+ node-releases "^2.0.12"
+ update-browserslist-db "^1.0.11"
+
+bundle-name@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz"
+ integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==
+ dependencies:
+ run-applescript "^5.0.0"
+
+busboy@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz"
+ integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
+ dependencies:
+ streamsearch "^1.1.0"
+
+call-bind@^1.0.0, call-bind@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz"
+ integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
+ dependencies:
+ function-bind "^1.1.1"
+ get-intrinsic "^1.0.2"
+
+callsites@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
+ integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
+
+camelcase-css@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz"
+ integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
+
+caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001503:
+ version "1.0.30001577"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001577.tgz"
+ integrity sha512-rs2ZygrG1PNXMfmncM0B5H1hndY5ZCC9b5TkFaVNfZ+AUlyqcMyVIQtc3fsezi0NUCk5XZfDf9WS6WxMxnfdrg==
+
+chalk@^4.0.0:
+ version "4.1.2"
+ resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
+"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3:
+ version "3.5.3"
+ resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz"
+ integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
+ dependencies:
+ anymatch "~3.1.2"
+ braces "~3.0.2"
+ glob-parent "~5.1.2"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.6.0"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
+client-only@0.0.1, client-only@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz"
+ integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
+
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+commander@^4.0.0:
+ version "4.1.1"
+ resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz"
+ integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+
+cookie@0.6.0:
+ version "0.6.0"
+ resolved "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz"
+ integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
+
+cookie@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz"
+ integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
+
+core-js@^3:
+ version "3.34.0"
+ resolved "https://registry.npmjs.org/core-js/-/core-js-3.34.0.tgz"
+ integrity sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==
+
+cross-spawn@^7.0.2, cross-spawn@^7.0.3:
+ version "7.0.3"
+ resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
+ integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
+ dependencies:
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
+
+cssesc@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
+ integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+
+csstype@^3.0.2:
+ version "3.1.2"
+ resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz"
+ integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
+
+damerau-levenshtein@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz"
+ integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
+
+debug@^3.2.7:
+ version "3.2.7"
+ resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
+ integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
+ dependencies:
+ ms "^2.1.1"
+
+debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
+ version "4.3.4"
+ resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
+ integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
+ dependencies:
+ ms "2.1.2"
+
+deep-is@^0.1.3:
+ version "0.1.4"
+ resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
+ integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
+
+default-browser-id@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz"
+ integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==
+ dependencies:
+ bplist-parser "^0.2.0"
+ untildify "^4.0.0"
+
+default-browser@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz"
+ integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==
+ dependencies:
+ bundle-name "^3.0.0"
+ default-browser-id "^3.0.0"
+ execa "^7.1.1"
+ titleize "^3.0.0"
+
+define-lazy-prop@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz"
+ integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==
+
+define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz"
+ integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==
+ dependencies:
+ has-property-descriptors "^1.0.0"
+ object-keys "^1.1.1"
+
+dequal@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz"
+ integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
+
+didyoumean@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz"
+ integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
+
+dir-glob@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz"
+ integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
+ dependencies:
+ path-type "^4.0.0"
+
+dlv@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz"
+ integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
+
+doctrine@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz"
+ integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
+ dependencies:
+ esutils "^2.0.2"
+
+doctrine@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
+ integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
+ dependencies:
+ esutils "^2.0.2"
+
+electron-to-chromium@^1.4.431:
+ version "1.4.457"
+ resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.457.tgz"
+ integrity sha512-/g3UyNDmDd6ebeWapmAoiyy+Sy2HyJ+/X8KyvNeHfKRFfHaA2W8oF5fxD5F3tjBDcjpwo0iek6YNgxNXDBoEtA==
+
+emoji-regex@^9.2.2:
+ version "9.2.2"
+ resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz"
+ integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+
+enhanced-resolve@^5.12.0:
+ version "5.15.0"
+ resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz"
+ integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==
+ dependencies:
+ graceful-fs "^4.2.4"
+ tapable "^2.2.0"
+
+es-abstract@^1.19.0, es-abstract@^1.20.4:
+ version "1.21.2"
+ resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz"
+ integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==
+ dependencies:
+ array-buffer-byte-length "^1.0.0"
+ available-typed-arrays "^1.0.5"
+ call-bind "^1.0.2"
+ es-set-tostringtag "^2.0.1"
+ es-to-primitive "^1.2.1"
+ function.prototype.name "^1.1.5"
+ get-intrinsic "^1.2.0"
+ get-symbol-description "^1.0.0"
+ globalthis "^1.0.3"
+ gopd "^1.0.1"
+ has "^1.0.3"
+ has-property-descriptors "^1.0.0"
+ has-proto "^1.0.1"
+ has-symbols "^1.0.3"
+ internal-slot "^1.0.5"
+ is-array-buffer "^3.0.2"
+ is-callable "^1.2.7"
+ is-negative-zero "^2.0.2"
+ is-regex "^1.1.4"
+ is-shared-array-buffer "^1.0.2"
+ is-string "^1.0.7"
+ is-typed-array "^1.1.10"
+ is-weakref "^1.0.2"
+ object-inspect "^1.12.3"
+ object-keys "^1.1.1"
+ object.assign "^4.1.4"
+ regexp.prototype.flags "^1.4.3"
+ safe-regex-test "^1.0.0"
+ string.prototype.trim "^1.2.7"
+ string.prototype.trimend "^1.0.6"
+ string.prototype.trimstart "^1.0.6"
+ typed-array-length "^1.0.4"
+ unbox-primitive "^1.0.2"
+ which-typed-array "^1.1.9"
+
+es-set-tostringtag@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz"
+ integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==
+ dependencies:
+ get-intrinsic "^1.1.3"
+ has "^1.0.3"
+ has-tostringtag "^1.0.0"
+
+es-shim-unscopables@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz"
+ integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==
+ dependencies:
+ has "^1.0.3"
+
+es-to-primitive@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz"
+ integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
+ dependencies:
+ is-callable "^1.1.4"
+ is-date-object "^1.0.1"
+ is-symbol "^1.0.2"
+
+escalade@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz"
+ integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
+
+escape-string-regexp@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
+ integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
+eslint-config-next@13.4.9:
+ version "13.4.9"
+ resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.9.tgz"
+ integrity sha512-0fLtKRR268NArpqeXXwnLgMXPvF64YESQvptVg+RMLCaijKm3FICN9Y7Jc1p2o+yrWwE4DufJXDM/Vo53D1L7g==
+ dependencies:
+ "@next/eslint-plugin-next" "13.4.9"
+ "@rushstack/eslint-patch" "^1.1.3"
+ "@typescript-eslint/parser" "^5.42.0"
+ eslint-import-resolver-node "^0.3.6"
+ eslint-import-resolver-typescript "^3.5.2"
+ eslint-plugin-import "^2.26.0"
+ eslint-plugin-jsx-a11y "^6.5.1"
+ eslint-plugin-react "^7.31.7"
+ eslint-plugin-react-hooks "5.0.0-canary-7118f5dd7-20230705"
+
+eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.7:
+ version "0.3.7"
+ resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz"
+ integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==
+ dependencies:
+ debug "^3.2.7"
+ is-core-module "^2.11.0"
+ resolve "^1.22.1"
+
+eslint-import-resolver-typescript@^3.5.2:
+ version "3.5.5"
+ resolved "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz"
+ integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==
+ dependencies:
+ debug "^4.3.4"
+ enhanced-resolve "^5.12.0"
+ eslint-module-utils "^2.7.4"
+ get-tsconfig "^4.5.0"
+ globby "^13.1.3"
+ is-core-module "^2.11.0"
+ is-glob "^4.0.3"
+ synckit "^0.8.5"
+
+eslint-module-utils@^2.7.4:
+ version "2.8.0"
+ resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz"
+ integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==
+ dependencies:
+ debug "^3.2.7"
+
+eslint-plugin-import@^2.26.0:
+ version "2.27.5"
+ resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz"
+ integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==
+ dependencies:
+ array-includes "^3.1.6"
+ array.prototype.flat "^1.3.1"
+ array.prototype.flatmap "^1.3.1"
+ debug "^3.2.7"
+ doctrine "^2.1.0"
+ eslint-import-resolver-node "^0.3.7"
+ eslint-module-utils "^2.7.4"
+ has "^1.0.3"
+ is-core-module "^2.11.0"
+ is-glob "^4.0.3"
+ minimatch "^3.1.2"
+ object.values "^1.1.6"
+ resolve "^1.22.1"
+ semver "^6.3.0"
+ tsconfig-paths "^3.14.1"
+
+eslint-plugin-jsx-a11y@^6.5.1:
+ version "6.7.1"
+ resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz"
+ integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==
+ dependencies:
+ "@babel/runtime" "^7.20.7"
+ aria-query "^5.1.3"
+ array-includes "^3.1.6"
+ array.prototype.flatmap "^1.3.1"
+ ast-types-flow "^0.0.7"
+ axe-core "^4.6.2"
+ axobject-query "^3.1.1"
+ damerau-levenshtein "^1.0.8"
+ emoji-regex "^9.2.2"
+ has "^1.0.3"
+ jsx-ast-utils "^3.3.3"
+ language-tags "=1.0.5"
+ minimatch "^3.1.2"
+ object.entries "^1.1.6"
+ object.fromentries "^2.0.6"
+ semver "^6.3.0"
+
+eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705:
+ version "5.0.0-canary-7118f5dd7-20230705"
+ resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz"
+ integrity sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==
+
+eslint-plugin-react@^7.31.7:
+ version "7.32.2"
+ resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz"
+ integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==
+ dependencies:
+ array-includes "^3.1.6"
+ array.prototype.flatmap "^1.3.1"
+ array.prototype.tosorted "^1.1.1"
+ doctrine "^2.1.0"
+ estraverse "^5.3.0"
+ jsx-ast-utils "^2.4.1 || ^3.0.0"
+ minimatch "^3.1.2"
+ object.entries "^1.1.6"
+ object.fromentries "^2.0.6"
+ object.hasown "^1.1.2"
+ object.values "^1.1.6"
+ prop-types "^15.8.1"
+ resolve "^2.0.0-next.4"
+ semver "^6.3.0"
+ string.prototype.matchall "^4.0.8"
+
+eslint-scope@^7.2.0:
+ version "7.2.0"
+ resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz"
+ integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^5.2.0"
+
+eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1:
+ version "3.4.1"
+ resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz"
+ integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==
+
+eslint@8.44.0:
+ version "8.44.0"
+ resolved "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz"
+ integrity sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==
+ dependencies:
+ "@eslint-community/eslint-utils" "^4.2.0"
+ "@eslint-community/regexpp" "^4.4.0"
+ "@eslint/eslintrc" "^2.1.0"
+ "@eslint/js" "8.44.0"
+ "@humanwhocodes/config-array" "^0.11.10"
+ "@humanwhocodes/module-importer" "^1.0.1"
+ "@nodelib/fs.walk" "^1.2.8"
+ ajv "^6.10.0"
+ chalk "^4.0.0"
+ cross-spawn "^7.0.2"
+ debug "^4.3.2"
+ doctrine "^3.0.0"
+ escape-string-regexp "^4.0.0"
+ eslint-scope "^7.2.0"
+ eslint-visitor-keys "^3.4.1"
+ espree "^9.6.0"
+ esquery "^1.4.2"
+ esutils "^2.0.2"
+ fast-deep-equal "^3.1.3"
+ file-entry-cache "^6.0.1"
+ find-up "^5.0.0"
+ glob-parent "^6.0.2"
+ globals "^13.19.0"
+ graphemer "^1.4.0"
+ ignore "^5.2.0"
+ import-fresh "^3.0.0"
+ imurmurhash "^0.1.4"
+ is-glob "^4.0.0"
+ is-path-inside "^3.0.3"
+ js-yaml "^4.1.0"
+ json-stable-stringify-without-jsonify "^1.0.1"
+ levn "^0.4.1"
+ lodash.merge "^4.6.2"
+ minimatch "^3.1.2"
+ natural-compare "^1.4.0"
+ optionator "^0.9.3"
+ strip-ansi "^6.0.1"
+ strip-json-comments "^3.1.0"
+ text-table "^0.2.0"
+
+espree@^9.6.0:
+ version "9.6.0"
+ resolved "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz"
+ integrity sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==
+ dependencies:
+ acorn "^8.9.0"
+ acorn-jsx "^5.3.2"
+ eslint-visitor-keys "^3.4.1"
+
+esquery@^1.4.2:
+ version "1.5.0"
+ resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz"
+ integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==
+ dependencies:
+ estraverse "^5.1.0"
+
+esrecurse@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
+ integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+ dependencies:
+ estraverse "^5.2.0"
+
+estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
+ version "5.3.0"
+ resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
+ integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+
+esutils@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
+ integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+
+execa@^5.0.0:
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz"
+ integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
+ dependencies:
+ cross-spawn "^7.0.3"
+ get-stream "^6.0.0"
+ human-signals "^2.1.0"
+ is-stream "^2.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^4.0.1"
+ onetime "^5.1.2"
+ signal-exit "^3.0.3"
+ strip-final-newline "^2.0.0"
+
+execa@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz"
+ integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==
+ dependencies:
+ cross-spawn "^7.0.3"
+ get-stream "^6.0.1"
+ human-signals "^4.3.0"
+ is-stream "^3.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^5.1.0"
+ onetime "^6.0.0"
+ signal-exit "^3.0.7"
+ strip-final-newline "^3.0.0"
+
+fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
+ integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+
+fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz"
+ integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.4"
+
+fast-json-stable-stringify@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
+ integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
+
+fast-levenshtein@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
+ integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
+
+fastq@^1.6.0:
+ version "1.15.0"
+ resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz"
+ integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==
+ dependencies:
+ reusify "^1.0.4"
+
+file-entry-cache@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
+ integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
+ dependencies:
+ flat-cache "^3.0.4"
+
+fill-range@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
+ integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+ dependencies:
+ to-regex-range "^5.0.1"
+
+find-up@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
+ integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
+ dependencies:
+ locate-path "^6.0.0"
+ path-exists "^4.0.0"
+
+flat-cache@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz"
+ integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
+ dependencies:
+ flatted "^3.1.0"
+ rimraf "^3.0.2"
+
+flatted@^3.1.0:
+ version "3.2.7"
+ resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz"
+ integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
+
+for-each@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz"
+ integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
+ dependencies:
+ is-callable "^1.1.3"
+
+fraction.js@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz"
+ integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
+ integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
+
+fsevents@~2.3.2:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+
+function-bind@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
+ integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+
+function.prototype.name@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz"
+ integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.0"
+ functions-have-names "^1.2.2"
+
+functions-have-names@^1.2.2, functions-have-names@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz"
+ integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
+
+get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0:
+ version "1.2.1"
+ resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz"
+ integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==
+ dependencies:
+ function-bind "^1.1.1"
+ has "^1.0.3"
+ has-proto "^1.0.1"
+ has-symbols "^1.0.3"
+
+get-stream@^6.0.0, get-stream@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz"
+ integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
+
+get-symbol-description@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz"
+ integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.1.1"
+
+get-tsconfig@^4.5.0:
+ version "4.6.2"
+ resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.2.tgz"
+ integrity sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==
+ dependencies:
+ resolve-pkg-maps "^1.0.0"
+
+glob-parent@^5.1.2, glob-parent@~5.1.2:
+ version "5.1.2"
+ resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
+ integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+ dependencies:
+ is-glob "^4.0.1"
+
+glob-parent@^6.0.2:
+ version "6.0.2"
+ resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz"
+ integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
+ dependencies:
+ is-glob "^4.0.3"
+
+glob-to-regexp@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz"
+ integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
+
+glob@7.1.6:
+ version "7.1.6"
+ resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz"
+ integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+glob@7.1.7, glob@^7.1.3:
+ version "7.1.7"
+ resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz"
+ integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+globals@^13.19.0:
+ version "13.20.0"
+ resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz"
+ integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==
+ dependencies:
+ type-fest "^0.20.2"
+
+globalthis@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz"
+ integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==
+ dependencies:
+ define-properties "^1.1.3"
+
+globby@^11.1.0:
+ version "11.1.0"
+ resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz"
+ integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
+ dependencies:
+ array-union "^2.1.0"
+ dir-glob "^3.0.1"
+ fast-glob "^3.2.9"
+ ignore "^5.2.0"
+ merge2 "^1.4.1"
+ slash "^3.0.0"
+
+globby@^13.1.3:
+ version "13.2.2"
+ resolved "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz"
+ integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==
+ dependencies:
+ dir-glob "^3.0.1"
+ fast-glob "^3.3.0"
+ ignore "^5.2.4"
+ merge2 "^1.4.1"
+ slash "^4.0.0"
+
+gopd@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz"
+ integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
+ dependencies:
+ get-intrinsic "^1.1.3"
+
+graceful-fs@^4.1.2, graceful-fs@^4.2.4:
+ version "4.2.11"
+ resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz"
+ integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
+
+graphemer@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz"
+ integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
+
+has-bigints@^1.0.1, has-bigints@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz"
+ integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
+
+has-flag@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
+ integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+has-property-descriptors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz"
+ integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
+ dependencies:
+ get-intrinsic "^1.1.1"
+
+has-proto@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz"
+ integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
+
+has-symbols@^1.0.2, has-symbols@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz"
+ integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
+
+has-tostringtag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz"
+ integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==
+ dependencies:
+ has-symbols "^1.0.2"
+
+has@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
+ integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+ dependencies:
+ function-bind "^1.1.1"
+
+hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
+ version "3.3.2"
+ resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
+ integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
+ dependencies:
+ react-is "^16.7.0"
+
+html-parse-stringify@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz"
+ integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==
+ dependencies:
+ void-elements "3.1.0"
+
+human-signals@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz"
+ integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
+
+human-signals@^4.3.0:
+ version "4.3.1"
+ resolved "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz"
+ integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==
+
+i18next-fs-backend@^2.1.5:
+ version "2.3.1"
+ resolved "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.3.1.tgz"
+ integrity sha512-tvfXskmG/9o+TJ5Fxu54sSO5OkY6d+uMn+K6JiUGLJrwxAVfer+8V3nU8jq3ts9Pe5lXJv4b1N7foIjJ8Iy2Gg==
+
+i18next@^23.2.10:
+ version "23.7.11"
+ resolved "https://registry.npmjs.org/i18next/-/i18next-23.7.11.tgz"
+ integrity sha512-A/vOkw8vY99YHU9A1Td3I1dcTiYaPnwBWzrpVzfXUXSYgogK3cmBcmop/0cnXPc6QpUWIyqaugKNxRUEZVk9Nw==
+ dependencies:
+ "@babel/runtime" "^7.23.2"
+
+ignore@^5.2.0, ignore@^5.2.4:
+ version "5.2.4"
+ resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz"
+ integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
+
+immutable@^4.0.0:
+ version "4.3.4"
+ resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz"
+ integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==
+
+import-fresh@^3.0.0, import-fresh@^3.2.1:
+ version "3.3.0"
+ resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
+ integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
+ dependencies:
+ parent-module "^1.0.0"
+ resolve-from "^4.0.0"
+
+imurmurhash@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
+ integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
+ integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2:
+ version "2.0.4"
+ resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
+ integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+internal-slot@^1.0.3, internal-slot@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz"
+ integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==
+ dependencies:
+ get-intrinsic "^1.2.0"
+ has "^1.0.3"
+ side-channel "^1.0.4"
+
+is-array-buffer@^3.0.1, is-array-buffer@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz"
+ integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.2.0"
+ is-typed-array "^1.1.10"
+
+is-bigint@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz"
+ integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==
+ dependencies:
+ has-bigints "^1.0.1"
+
+is-binary-path@~2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
+ integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+ dependencies:
+ binary-extensions "^2.0.0"
+
+is-boolean-object@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz"
+ integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==
+ dependencies:
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
+
+is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
+ version "1.2.7"
+ resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
+ integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
+
+is-core-module@^2.11.0, is-core-module@^2.9.0:
+ version "2.12.1"
+ resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz"
+ integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==
+ dependencies:
+ has "^1.0.3"
+
+is-date-object@^1.0.1:
+ version "1.0.5"
+ resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz"
+ integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-docker@^2.0.0:
+ version "2.2.1"
+ resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
+ integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
+
+is-docker@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz"
+ integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==
+
+is-extglob@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
+ integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
+
+is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
+ version "4.0.3"
+ resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
+ integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
+ dependencies:
+ is-extglob "^2.1.1"
+
+is-inside-container@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz"
+ integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==
+ dependencies:
+ is-docker "^3.0.0"
+
+is-negative-zero@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz"
+ integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
+
+is-number-object@^1.0.4:
+ version "1.0.7"
+ resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz"
+ integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-number@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+is-path-inside@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz"
+ integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
+
+is-regex@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz"
+ integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
+ dependencies:
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
+
+is-shared-array-buffer@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz"
+ integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
+ dependencies:
+ call-bind "^1.0.2"
+
+is-stream@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz"
+ integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
+
+is-stream@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz"
+ integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==
+
+is-string@^1.0.5, is-string@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz"
+ integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-symbol@^1.0.2, is-symbol@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz"
+ integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==
+ dependencies:
+ has-symbols "^1.0.2"
+
+is-typed-array@^1.1.10, is-typed-array@^1.1.9:
+ version "1.1.10"
+ resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz"
+ integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==
+ dependencies:
+ available-typed-arrays "^1.0.5"
+ call-bind "^1.0.2"
+ for-each "^0.3.3"
+ gopd "^1.0.1"
+ has-tostringtag "^1.0.0"
+
+is-weakref@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz"
+ integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
+ dependencies:
+ call-bind "^1.0.2"
+
+is-wsl@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz"
+ integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
+ dependencies:
+ is-docker "^2.0.0"
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
+ integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+
+jiti@^1.18.2:
+ version "1.19.1"
+ resolved "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz"
+ integrity sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==
+
+jose@^4.11.4, jose@^4.15.4:
+ version "4.15.4"
+ resolved "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz"
+ integrity sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==
+
+jose@^5.1.3:
+ version "5.2.0"
+ resolved "https://registry.npmjs.org/jose/-/jose-5.2.0.tgz"
+ integrity sha512-oW3PCnvyrcm1HMvGTzqjxxfnEs9EoFOFWi2HsEGhlFVOXxTE3K9GKWVMFoFw06yPUqwpvEWic1BmtUZBI/tIjw==
+
+"js-tokens@^3.0.0 || ^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+js-yaml@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz"
+ integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
+ dependencies:
+ argparse "^2.0.1"
+
+json-schema-traverse@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
+ integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+
+json-stable-stringify-without-jsonify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
+ integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
+
+json5@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz"
+ integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
+ dependencies:
+ minimist "^1.2.0"
+
+"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3:
+ version "3.3.4"
+ resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.4.tgz"
+ integrity sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw==
+ dependencies:
+ array-includes "^3.1.6"
+ array.prototype.flat "^1.3.1"
+ object.assign "^4.1.4"
+ object.values "^1.1.6"
+
+language-subtag-registry@~0.3.2:
+ version "0.3.22"
+ resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz"
+ integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==
+
+language-tags@=1.0.5:
+ version "1.0.5"
+ resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz"
+ integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==
+ dependencies:
+ language-subtag-registry "~0.3.2"
+
+levn@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
+ integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
+ dependencies:
+ prelude-ls "^1.2.1"
+ type-check "~0.4.0"
+
+lilconfig@^2.0.5, lilconfig@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz"
+ integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
+
+lines-and-columns@^1.1.6:
+ version "1.2.4"
+ resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz"
+ integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
+
+locate-path@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz"
+ integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
+ dependencies:
+ p-locate "^5.0.0"
+
+lodash.merge@^4.6.2:
+ version "4.6.2"
+ resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
+ integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+
+loose-envify@^1.1.0, loose-envify@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
+ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+ dependencies:
+ js-tokens "^3.0.0 || ^4.0.0"
+
+lru-cache@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
+ integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+ dependencies:
+ yallist "^4.0.0"
+
+merge-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
+ integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
+
+merge2@^1.3.0, merge2@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
+ integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+
+micromatch@^4.0.4, micromatch@^4.0.5:
+ version "4.0.5"
+ resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
+ integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
+ dependencies:
+ braces "^3.0.2"
+ picomatch "^2.3.1"
+
+mimic-fn@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
+ integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+
+mimic-fn@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz"
+ integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
+
+minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
+ integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
+ dependencies:
+ brace-expansion "^1.1.7"
+
+minimist@^1.2.0, minimist@^1.2.6:
+ version "1.2.8"
+ resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
+ integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
+
+ms@2.1.2, ms@^2.1.1:
+ version "2.1.2"
+ resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
+ integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+
+mz@^2.7.0:
+ version "2.7.0"
+ resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz"
+ integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
+ dependencies:
+ any-promise "^1.0.0"
+ object-assign "^4.0.1"
+ thenify-all "^1.0.0"
+
+nanoid@^3.3.4, nanoid@^3.3.6:
+ version "3.3.6"
+ resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz"
+ integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
+
+natural-compare@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
+ integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
+
+next-auth@^4.24.5:
+ version "4.24.5"
+ resolved "https://registry.npmjs.org/next-auth/-/next-auth-4.24.5.tgz"
+ integrity sha512-3RafV3XbfIKk6rF6GlLE4/KxjTcuMCifqrmD+98ejFq73SRoj2rmzoca8u764977lH/Q7jo6Xu6yM+Re1Mz/Og==
+ dependencies:
+ "@babel/runtime" "^7.20.13"
+ "@panva/hkdf" "^1.0.2"
+ cookie "^0.5.0"
+ jose "^4.11.4"
+ oauth "^0.9.15"
+ openid-client "^5.4.0"
+ preact "^10.6.3"
+ preact-render-to-string "^5.1.19"
+ uuid "^8.3.2"
+
+next-i18next@^14.0.0:
+ version "14.0.3"
+ resolved "https://registry.npmjs.org/next-i18next/-/next-i18next-14.0.3.tgz"
+ integrity sha512-FtnjRMfhlamk8YyeyWqd+pndNL+3er83iMZnH4M4mhiGA93l0+vtBUvuObgOAMHDJGLLB2SS2xOOZq69oiJh7A==
+ dependencies:
+ "@babel/runtime" "^7.20.13"
+ "@types/hoist-non-react-statics" "^3.3.1"
+ core-js "^3"
+ hoist-non-react-statics "^3.3.2"
+ i18next-fs-backend "^2.1.5"
+
+next@13.4.9:
+ version "13.4.9"
+ resolved "https://registry.npmjs.org/next/-/next-13.4.9.tgz"
+ integrity sha512-vtefFm/BWIi/eWOqf1GsmKG3cjKw1k3LjuefKRcL3iiLl3zWzFdPG3as6xtxrGO6gwTzzaO1ktL4oiHt/uvTjA==
+ dependencies:
+ "@next/env" "13.4.9"
+ "@swc/helpers" "0.5.1"
+ busboy "1.6.0"
+ caniuse-lite "^1.0.30001406"
+ postcss "8.4.14"
+ styled-jsx "5.1.1"
+ watchpack "2.4.0"
+ zod "3.21.4"
+ optionalDependencies:
+ "@next/swc-darwin-arm64" "13.4.9"
+ "@next/swc-darwin-x64" "13.4.9"
+ "@next/swc-linux-arm64-gnu" "13.4.9"
+ "@next/swc-linux-arm64-musl" "13.4.9"
+ "@next/swc-linux-x64-gnu" "13.4.9"
+ "@next/swc-linux-x64-musl" "13.4.9"
+ "@next/swc-win32-arm64-msvc" "13.4.9"
+ "@next/swc-win32-ia32-msvc" "13.4.9"
+ "@next/swc-win32-x64-msvc" "13.4.9"
+
+node-releases@^2.0.12:
+ version "2.0.13"
+ resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz"
+ integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==
+
+normalize-path@^3.0.0, normalize-path@~3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
+ integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+
+normalize-range@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
+ integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
+
+npm-run-path@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz"
+ integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
+ dependencies:
+ path-key "^3.0.0"
+
+npm-run-path@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz"
+ integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==
+ dependencies:
+ path-key "^4.0.0"
+
+oauth4webapi@^2.4.0:
+ version "2.4.0"
+ resolved "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-2.4.0.tgz"
+ integrity sha512-ZWl8ov8HeGVyc9Icl1cag76HvIcDAp23eIIT+UVGir+dEu8BMgMlvZeZwqLVd0P8DqaumH4N+QLQXN69G1QjSA==
+
+oauth@^0.9.15:
+ version "0.9.15"
+ resolved "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz"
+ integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==
+
+object-assign@^4.0.1, object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
+ integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
+
+object-hash@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz"
+ integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
+
+object-hash@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz"
+ integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
+
+object-inspect@^1.12.3, object-inspect@^1.9.0:
+ version "1.12.3"
+ resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz"
+ integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==
+
+object-keys@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
+ integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
+
+object.assign@^4.1.4:
+ version "4.1.4"
+ resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz"
+ integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ has-symbols "^1.0.3"
+ object-keys "^1.1.1"
+
+object.entries@^1.1.6:
+ version "1.1.6"
+ resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz"
+ integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+
+object.fromentries@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz"
+ integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+
+object.hasown@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz"
+ integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==
+ dependencies:
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+
+object.values@^1.1.6:
+ version "1.1.6"
+ resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz"
+ integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+
+oidc-token-hash@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz"
+ integrity sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
+ integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
+ dependencies:
+ wrappy "1"
+
+onetime@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz"
+ integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
+ dependencies:
+ mimic-fn "^2.1.0"
+
+onetime@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz"
+ integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
+ dependencies:
+ mimic-fn "^4.0.0"
+
+open@^9.1.0:
+ version "9.1.0"
+ resolved "https://registry.npmjs.org/open/-/open-9.1.0.tgz"
+ integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==
+ dependencies:
+ default-browser "^4.0.0"
+ define-lazy-prop "^3.0.0"
+ is-inside-container "^1.0.0"
+ is-wsl "^2.2.0"
+
+openid-client@^5.4.0:
+ version "5.6.2"
+ resolved "https://registry.npmjs.org/openid-client/-/openid-client-5.6.2.tgz"
+ integrity sha512-TIVimoK/fAvpiISLcoGZyNJx2TOfd5AE6TXn58FFj6Y8qbU/jqky54Aws7sYKuCph1bLPWSRUa1r/Rd6K21bhg==
+ dependencies:
+ jose "^4.15.4"
+ lru-cache "^6.0.0"
+ object-hash "^2.2.0"
+ oidc-token-hash "^5.0.3"
+
+optionator@^0.9.3:
+ version "0.9.3"
+ resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz"
+ integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==
+ dependencies:
+ "@aashutoshrathi/word-wrap" "^1.2.3"
+ deep-is "^0.1.3"
+ fast-levenshtein "^2.0.6"
+ levn "^0.4.1"
+ prelude-ls "^1.2.1"
+ type-check "^0.4.0"
+
+p-limit@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz"
+ integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
+ dependencies:
+ yocto-queue "^0.1.0"
+
+p-locate@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz"
+ integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
+ dependencies:
+ p-limit "^3.0.2"
+
+parent-module@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
+ integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
+ dependencies:
+ callsites "^3.0.0"
+
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
+ integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
+
+path-key@^3.0.0, path-key@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
+ integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+
+path-key@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz"
+ integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
+
+path-parse@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
+ integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+
+path-type@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
+ integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+
+picocolors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
+ integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
+
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+
+pify@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
+ integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
+
+pirates@^4.0.1:
+ version "4.0.6"
+ resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz"
+ integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
+
+postcss-import@^15.1.0:
+ version "15.1.0"
+ resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz"
+ integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==
+ dependencies:
+ postcss-value-parser "^4.0.0"
+ read-cache "^1.0.0"
+ resolve "^1.1.7"
+
+postcss-js@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz"
+ integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
+ dependencies:
+ camelcase-css "^2.0.1"
+
+postcss-load-config@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz"
+ integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==
+ dependencies:
+ lilconfig "^2.0.5"
+ yaml "^2.1.1"
+
+postcss-nested@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz"
+ integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==
+ dependencies:
+ postcss-selector-parser "^6.0.11"
+
+postcss-selector-parser@^6.0.11:
+ version "6.0.13"
+ resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz"
+ integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==
+ dependencies:
+ cssesc "^3.0.0"
+ util-deprecate "^1.0.2"
+
+postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
+ integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
+
+postcss@8.4.14:
+ version "8.4.14"
+ resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz"
+ integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
+ dependencies:
+ nanoid "^3.3.4"
+ picocolors "^1.0.0"
+ source-map-js "^1.0.2"
+
+postcss@8.4.25, postcss@^8.4.23:
+ version "8.4.25"
+ resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz"
+ integrity sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==
+ dependencies:
+ nanoid "^3.3.6"
+ picocolors "^1.0.0"
+ source-map-js "^1.0.2"
+
+preact-render-to-string@5.2.3, preact-render-to-string@^5.1.19:
+ version "5.2.3"
+ resolved "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz"
+ integrity sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==
+ dependencies:
+ pretty-format "^3.8.0"
+
+preact@10.11.3, preact@^10.6.3:
+ version "10.11.3"
+ resolved "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz"
+ integrity sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==
+
+prelude-ls@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
+ integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+
+pretty-format@^3.8.0:
+ version "3.8.0"
+ resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz"
+ integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==
+
+prisma@^5.8.1:
+ version "5.8.1"
+ resolved "https://registry.npmjs.org/prisma/-/prisma-5.8.1.tgz"
+ integrity sha512-N6CpjzECnUHZ5beeYpDzkt2rYpEdAeqXX2dweu6BoQaeYkNZrC/WJHM+5MO/uidFHTak8QhkPKBWck1o/4MD4A==
+ dependencies:
+ "@prisma/engines" "5.8.1"
+
+prop-types@^15.8.1:
+ version "15.8.1"
+ resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
+ integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
+ dependencies:
+ loose-envify "^1.4.0"
+ object-assign "^4.1.1"
+ react-is "^16.13.1"
+
+property-expr@^2.0.5:
+ version "2.0.6"
+ resolved "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz"
+ integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==
+
+punycode@^2.1.0:
+ version "2.3.0"
+ resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz"
+ integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
+
+queue-microtask@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
+ integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+
+react-dom@18.2.0:
+ version "18.2.0"
+ resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
+ integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
+ dependencies:
+ loose-envify "^1.1.0"
+ scheduler "^0.23.0"
+
+react-hook-form@^7.49.2:
+ version "7.49.2"
+ resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.49.2.tgz"
+ integrity sha512-TZcnSc17+LPPVpMRIDNVITY6w20deMdNi6iehTFLV1x8SqThXGwu93HjlUVU09pzFgZH7qZOvLMM7UYf2ShAHA==
+
+react-i18next@^13.0.2:
+ version "13.5.0"
+ resolved "https://registry.npmjs.org/react-i18next/-/react-i18next-13.5.0.tgz"
+ integrity sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==
+ dependencies:
+ "@babel/runtime" "^7.22.5"
+ html-parse-stringify "^3.0.1"
+
+react-icons@^4.11.0:
+ version "4.12.0"
+ resolved "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz"
+ integrity sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==
+
+react-is@^16.13.1, react-is@^16.7.0:
+ version "16.13.1"
+ resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
+ integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
+react-loading@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.npmjs.org/react-loading/-/react-loading-2.0.3.tgz"
+ integrity sha512-Vdqy79zq+bpeWJqC+xjltUjuGApyoItPgL0vgVfcJHhqwU7bAMKzysfGW/ADu6i0z0JiOCRJjo+IkFNkRNbA3A==
+
+react@18.2.0:
+ version "18.2.0"
+ resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
+ integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
+ dependencies:
+ loose-envify "^1.1.0"
+
+read-cache@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz"
+ integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==
+ dependencies:
+ pify "^2.3.0"
+
+readdirp@~3.6.0:
+ version "3.6.0"
+ resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"
+ integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+ dependencies:
+ picomatch "^2.2.1"
+
+regenerator-runtime@^0.14.0:
+ version "0.14.1"
+ resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz"
+ integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
+
+regexp.prototype.flags@^1.4.3:
+ version "1.5.0"
+ resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz"
+ integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.2.0"
+ functions-have-names "^1.2.3"
+
+resolve-from@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
+ integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
+
+resolve-pkg-maps@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz"
+ integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
+
+resolve@^1.1.7, resolve@^1.22.1, resolve@^1.22.2:
+ version "1.22.2"
+ resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz"
+ integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
+ dependencies:
+ is-core-module "^2.11.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
+resolve@^2.0.0-next.4:
+ version "2.0.0-next.4"
+ resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz"
+ integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==
+ dependencies:
+ is-core-module "^2.9.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
+reusify@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
+ integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
+
+rimraf@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
+ integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
+ dependencies:
+ glob "^7.1.3"
+
+run-applescript@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz"
+ integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==
+ dependencies:
+ execa "^5.0.0"
+
+run-parallel@^1.1.9:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
+ integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
+ dependencies:
+ queue-microtask "^1.2.2"
+
+safe-regex-test@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz"
+ integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.1.3"
+ is-regex "^1.1.4"
+
+sass@^1.63.6:
+ version "1.69.5"
+ resolved "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz"
+ integrity sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==
+ dependencies:
+ chokidar ">=3.0.0 <4.0.0"
+ immutable "^4.0.0"
+ source-map-js ">=0.6.2 <2.0.0"
+
+scheduler@^0.23.0:
+ version "0.23.0"
+ resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz"
+ integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
+ dependencies:
+ loose-envify "^1.1.0"
+
+semver@^6.3.0:
+ version "6.3.1"
+ resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
+
+semver@^7.3.7:
+ version "7.5.4"
+ resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz"
+ integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
+ dependencies:
+ lru-cache "^6.0.0"
+
+shebang-command@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
+ integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
+ dependencies:
+ shebang-regex "^3.0.0"
+
+shebang-regex@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
+ integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+
+side-channel@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz"
+ integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
+ dependencies:
+ call-bind "^1.0.0"
+ get-intrinsic "^1.0.2"
+ object-inspect "^1.9.0"
+
+signal-exit@^3.0.3, signal-exit@^3.0.7:
+ version "3.0.7"
+ resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz"
+ integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+
+slash@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
+ integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+
+slash@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz"
+ integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
+
+"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
+ integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+
+streamsearch@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz"
+ integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
+
+string.prototype.matchall@^4.0.8:
+ version "4.0.8"
+ resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz"
+ integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+ get-intrinsic "^1.1.3"
+ has-symbols "^1.0.3"
+ internal-slot "^1.0.3"
+ regexp.prototype.flags "^1.4.3"
+ side-channel "^1.0.4"
+
+string.prototype.trim@^1.2.7:
+ version "1.2.7"
+ resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz"
+ integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+
+string.prototype.trimend@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz"
+ integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+
+string.prototype.trimstart@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz"
+ integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.20.4"
+
+strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+strip-bom@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz"
+ integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
+
+strip-final-newline@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz"
+ integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+
+strip-final-newline@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz"
+ integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
+
+strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
+ integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+
+styled-jsx@5.1.1:
+ version "5.1.1"
+ resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz"
+ integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==
+ dependencies:
+ client-only "0.0.1"
+
+sucrase@^3.32.0:
+ version "3.32.0"
+ resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz"
+ integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.2"
+ commander "^4.0.0"
+ glob "7.1.6"
+ lines-and-columns "^1.1.6"
+ mz "^2.7.0"
+ pirates "^4.0.1"
+ ts-interface-checker "^0.1.9"
+
+supports-color@^7.1.0:
+ version "7.2.0"
+ resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
+ integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+ dependencies:
+ has-flag "^4.0.0"
+
+supports-preserve-symlinks-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
+ integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+
+swr@^2.2.4:
+ version "2.2.4"
+ resolved "https://registry.npmjs.org/swr/-/swr-2.2.4.tgz"
+ integrity sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==
+ dependencies:
+ client-only "^0.0.1"
+ use-sync-external-store "^1.2.0"
+
+synckit@^0.8.5:
+ version "0.8.5"
+ resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz"
+ integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==
+ dependencies:
+ "@pkgr/utils" "^2.3.1"
+ tslib "^2.5.0"
+
+tailwindcss@3.3.2:
+ version "3.3.2"
+ resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz"
+ integrity sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==
+ dependencies:
+ "@alloc/quick-lru" "^5.2.0"
+ arg "^5.0.2"
+ chokidar "^3.5.3"
+ didyoumean "^1.2.2"
+ dlv "^1.1.3"
+ fast-glob "^3.2.12"
+ glob-parent "^6.0.2"
+ is-glob "^4.0.3"
+ jiti "^1.18.2"
+ 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.23"
+ postcss-import "^15.1.0"
+ postcss-js "^4.0.1"
+ postcss-load-config "^4.0.1"
+ postcss-nested "^6.0.1"
+ postcss-selector-parser "^6.0.11"
+ postcss-value-parser "^4.2.0"
+ resolve "^1.22.2"
+ sucrase "^3.32.0"
+
+tapable@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz"
+ integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
+
+text-table@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
+ integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
+
+thenify-all@^1.0.0:
+ version "1.6.0"
+ resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz"
+ integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==
+ dependencies:
+ thenify ">= 3.1.0 < 4"
+
+"thenify@>= 3.1.0 < 4":
+ version "3.3.1"
+ resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz"
+ integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
+ dependencies:
+ any-promise "^1.0.0"
+
+tiny-case@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz"
+ integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==
+
+titleize@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz"
+ integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==
+
+to-regex-range@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
+ integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+ dependencies:
+ is-number "^7.0.0"
+
+toposort@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz"
+ integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==
+
+ts-interface-checker@^0.1.9:
+ version "0.1.13"
+ resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz"
+ integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
+
+tsconfig-paths@^3.14.1:
+ version "3.14.2"
+ resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz"
+ integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==
+ dependencies:
+ "@types/json5" "^0.0.29"
+ json5 "^1.0.2"
+ minimist "^1.2.6"
+ strip-bom "^3.0.0"
+
+tslib@^1.8.1:
+ version "1.14.1"
+ resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
+ integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
+
+tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6.0:
+ version "2.6.0"
+ resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz"
+ integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==
+
+tsutils@^3.21.0:
+ version "3.21.0"
+ resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz"
+ integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
+ dependencies:
+ tslib "^1.8.1"
+
+type-check@^0.4.0, type-check@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
+ integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
+ dependencies:
+ prelude-ls "^1.2.1"
+
+type-fest@^0.20.2:
+ version "0.20.2"
+ resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
+ integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
+
+type-fest@^2.19.0:
+ version "2.19.0"
+ resolved "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz"
+ integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
+
+typed-array-length@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz"
+ integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==
+ dependencies:
+ call-bind "^1.0.2"
+ for-each "^0.3.3"
+ is-typed-array "^1.1.9"
+
+typescript@5.1.6:
+ version "5.1.6"
+ resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz"
+ integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
+
+unbox-primitive@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz"
+ integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
+ dependencies:
+ call-bind "^1.0.2"
+ has-bigints "^1.0.2"
+ has-symbols "^1.0.3"
+ which-boxed-primitive "^1.0.2"
+
+untildify@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz"
+ integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
+
+update-browserslist-db@^1.0.11:
+ version "1.0.11"
+ resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz"
+ integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==
+ dependencies:
+ escalade "^3.1.1"
+ picocolors "^1.0.0"
+
+uri-js@^4.2.2:
+ version "4.4.1"
+ resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
+ integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
+ dependencies:
+ punycode "^2.1.0"
+
+use-sync-external-store@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
+ integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
+
+util-deprecate@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+
+uuid@^8.3.2:
+ version "8.3.2"
+ resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
+ integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
+void-elements@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz"
+ integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==
+
+watchpack@2.4.0:
+ version "2.4.0"
+ resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz"
+ integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==
+ dependencies:
+ glob-to-regexp "^0.4.1"
+ graceful-fs "^4.1.2"
+
+which-boxed-primitive@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz"
+ integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==
+ dependencies:
+ is-bigint "^1.0.1"
+ is-boolean-object "^1.1.0"
+ is-number-object "^1.0.4"
+ is-string "^1.0.5"
+ is-symbol "^1.0.3"
+
+which-typed-array@^1.1.9:
+ version "1.1.10"
+ resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.10.tgz"
+ integrity sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA==
+ dependencies:
+ available-typed-arrays "^1.0.5"
+ call-bind "^1.0.2"
+ for-each "^0.3.3"
+ gopd "^1.0.1"
+ has-tostringtag "^1.0.0"
+ is-typed-array "^1.1.10"
+
+which@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
+ integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+ dependencies:
+ isexe "^2.0.0"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+
+yallist@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
+ integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+
+yaml@^2.1.1:
+ version "2.3.1"
+ resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz"
+ integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==
+
+yocto-queue@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
+ integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+
+yup@^1.3.3:
+ version "1.3.3"
+ resolved "https://registry.npmjs.org/yup/-/yup-1.3.3.tgz"
+ integrity sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw==
+ dependencies:
+ property-expr "^2.0.5"
+ tiny-case "^1.0.3"
+ toposort "^2.0.2"
+ type-fest "^2.19.0"
+
+zod@3.21.4:
+ version "3.21.4"
+ resolved "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz"
+ integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==